---
search:
  tags:
    - Topics
    - POST
seo:
  description: >-
    Resolve the physical read plan for a topic identity over a time… Reference
    for the POST /v2/topics/id/{topic_id}/read-plan endpoint in the Roboto REST
    API.
sidebar:
  label: Resolve read plan
  badge: POST
title: Resolve read plan
type: openapi-operation
---
Resolve the physical read plan for a topic identity over a time window.

The request body carries the window, the field projection (as field-subtree
addresses), an optional per-subtree representation ``prefer`` grammar, and
optionally names the schema and timeline source to use. A malformed
body, or a schema named by both id and checksum, yields a 400.

Authorization is two layers. The caller must first hold topic view
access in the org that owns the topic. Within the org, authorization
is all-or-nothing over the window, through view access to every
in-window partition's backing file: if the caller cannot view any
part of the requested window, the whole request fails with a 401
(``RobotoUnauthorizedException``) rather than returning a plan that
silently omits data.

When the body carries a ``session_id``, the read is scoped to the files
recorded in that session (so a shared topic name does not pull data
from unrelated files org-wide), and the caller must additionally hold
session-view access in the org that owns the session; an unknown session
yields a 404 and one the caller cannot view yields a 401.

A ``file_id`` limits the read to the topic's data in that file, a ``dataset_id`` to its data in the dataset's
files, and a ``device_id`` to its data in the device's files (a file belongs to the device it names, or, when it
names none, to the device its dataset names). A named file or dataset must exist (else 404) and the caller must
hold view access to it (else 401). A device is not looked up, so an unknown device yields an empty plan. Every
restriction the body names narrows the read, and restrictions named together intersect. Data a restriction leaves
out does not affect the read: its schemas cause no ambiguity and its files need no access.

With a file, dataset or device named, the body may omit ``start_time``, ``end_time`` or both. An omitted bound
defaults to the start or end of the topic's data within the body's restrictions, across every timeline source.
When the restrictions select no timestamped data for the topic, or the one given bound lies past the far end of
that data (a start after the data ends, or an end before it begins), the plan has no partitions and a null
``window``.

A caller pinned to an API version below 2026-10-05 receives on every
partition the ``extent`` field that SDK releases pinned to those versions
require. Such an SDK selects rows by the requested window alone, so a plan
is refused for that caller with a 400 (``RobotoDeprecatedException``)
asking them to upgrade when any partition owns a slice of a shared file, or
when a session narrows any partition's window below the requested one:
reading it on that version would return rows belonging to another session
or to another partition packed in the same file.

### Access control
 - Restricted tokens need the API scope `api.everything_else`

`POST /v2/topics/id/{topic_id}/read-plan`
