Standard Library

api_response

import api_response produces the JSON envelope strings public API handlers return. Every helper writes a stable shape with ok, optional data fields, and request_id, so clients and audit logs can correlate on the same key.

The ManualResponseEnvelopeRule (VCH010) flags hand-built envelopes; this module is the single place handlers build responses from.

Success envelopes

import api_response

return api_response.ok_object("issue", issue_to_json(created))
return api_response.ok_array("issues", json_array_map(rows, issue_to_json))
return api_response.ok_fields(extra_fields)
HelperShape
ok_object(name, value){ "ok": true, <name>: { ... } }
ok_array(name, value){ "ok": true, <name>: [ ... ] }
ok_fields(fields){ "ok": true, ...fields } (spreads a JSON object)

Page envelopes

return api_response.ok_page(
    Json.empty_object(),
    "issues",
    issue_array,
    limit,
    next_page_token)

ok_page(fields, name, value, limit, next_page_token) returns { "ok": true, ...fields, "limit": limit, "next_page_token": <int|null>, <name>: [...] }. Pair it with paging.page_slice to compute the slice and cursor from a typed query that fetched limit + 1 rows.

Error envelopes

FailureHelperNotes
Single field failed validationvalidation_error(field, message, rid)Tags field_errors with path for client highlighting.
Multiple fields or shape-level failureerror_fields(code, message, field_errors, extra, rid)Decoder uses this when more than one field is wrong.
Caller lacks a capabilitycapability_error(message, capability, rid)Names the capability in extra for scope-aware retry.
Anything elseerror_object(code, message, rid)Default for not-found, conflict, or generic refusal.

rid should be ctx.request_id.value; when no id is available the helper defaults to "req_unavailable" instead of silently dropping the correlation.

return api_response.validation_error("title", "must be 1-200 chars", ctx.request_id.value)
return api_response.capability_error("forbidden", "issues.moderate", ctx.request_id.value)
return api_response.error_object("not_found", "issue not found", ctx.request_id.value)

When to prefer contract data

For routes that declare a response shape, prefer returning typed values through the contract instead of building envelopes directly. Use this module when the route's contract intentionally returns a raw string envelope (mutations with custom shapes, error paths, or pagination wrappers that pre-date the response DSL).

← JSON
HTTP Client →