Read one decision
const url = 'https://api.hydrate.sh/v1/decisions/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://api.hydrate.sh/v1/decisions/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0 \ --header 'Authorization: Bearer <token>'One decision by id.
Requires the decisions:read scope. A decision you may not read —
because it belongs to another project, or is still mid-conversation —
returns the same 404 as one that does not exist.
The URL is flat (no project component) because a decision id is globally unique. Authorization is still per project: the row is loaded, then its project is resolved through the membership gate, then the state filter — every one of those failures producing the SAME 404 a nonexistent id gets, so this route is not an oracle for “that decision exists but you may not see it”.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Responses
Section titled “Responses”Successful Response
object
A decision as the /v1 surface serves it.
A focused read view: the decision’s identity, anchor, state, and the fields a caller needs to reason about what has been decided. The shape is intentionally minimal and stable, so it won’t churn as the product grows.
object
Where a decision is anchored. id is a free-text reference
whose meaning depends on type (a node/boundary UUID, an error
payload key, or absent for a project-level decision).
type is an OPEN set, published as a plain string, for exactly the
reason Finding.code is — see that model. The anchor vocabulary is
server-owned and grows additively as new things become anchorable, so
a consumer must tolerate a type it does not recognize.
Example
{ "decision": { "anchor_ref": { "type": "node" } }}No credentials, malformed credentials, or revoked credentials. The envelope is leak-parity (same shape across all 401 paths) so an attacker cannot distinguish revoked vs. unknown via the body.
object
Example
{ "detail": "unauthenticated"}Credentials are valid but lack the scope required for this route, or the principal lacks membership in the target project.
object
object
Examplegenerated
{ "detail": { "code": "example", "message": "example" }}Resource not found OR not accessible to this principal. Leak parity: the response is identical in both cases so an attacker cannot enumerate resources via 404-vs-403 timing.
object
object
Example
{ "detail": { "code": "not_found" }}Validation Error
object
object
object
Examplegenerated
{ "detail": [ { "ctx": {}, "input": "example", "loc": [ "example" ], "msg": "example", "type": "example" } ]}Per-bucket rate limit exceeded. The response carries Retry-After and the standard X-RateLimit-* headers (Limit / Remaining / Reset).
object
Example
{ "detail": "rate_limited"}