Conventions
The contracts every lane honors: machine-readable output, errors, pagination, and idempotency.
Machine-readable output
Every lane returns structured data. The CLI prints exactly one JSON value on stdout with --json (diagnostics go to stderr); the API returns GraphQL JSON; the SDK returns typed objects.
spaceboy --json projects list | jq -r '.[0].id'Errors
Failures carry a stable code in every lane. The API attaches extensions.code to GraphQL errors; the CLI maps those codes to exit codes; the SDK throws a RepobotError carrying the same code.
- UNAUTHENTICATED — bad or revoked key. CLI exit code 3.
- PERMISSION_DENIED / FAILED_PRECONDITION — your role or plan does not allow it. CLI exit code 4.
- RESOURCE_EXHAUSTED — out of usage credits; the error carries your balance and top-up bounds. CLI exit code 1 with a remediation command.
- CLI exit codes: 0 success, 1 failure, 2 usage error, 3 authentication, 4 permission or plan.
spaceboy --json deploy --project prj_... --target production# on failure, stdout is one JSON error object:# { "error": { "message": "...", "exitCode": 4, "code": "PERMISSION_DENIED" } }Pagination
List queries take a connection input with pagination and sort. The CLI and SDK apply sensible defaults (newest first); raw API callers pass the input themselves:
query Projects($input: ProjectsConnectionInput!) { projects(input: $input) { nodes { id name } }}# variables{ "input": { "pagination": { "first": 20 }, "sort": [{ "fieldName": "rowCreatedAt", "direction": "desc" }] }}Idempotency and polling
- Mutations accept an idempotencyKey; re-sending a failed request with the same key is safe. The CLI and SDK generate these automatically — re-running a failed command is always safe.
- Long operations (agent messages, deploys, setups) are asynchronous server-side. The CLI and SDK poll internally and block until a terminal state; raw API callers poll the matching status query.
- If a wrapped call times out, the run keeps going server-side — resume by reading status, never by re-issuing the work.
Explore the schema
The API schema is self-documenting: introspection is enabled, so point any GraphQL client — a desktop client, graphql-codegen, or your editor's GraphQL plugin — at the endpoint and browse every operation, type, and docstring. What you introspect is always the schema that's live. Operations this reference doesn't curate are still fully available: the SDK's repobot.graphql() escape hatch and the raw endpoint reach everything.