Skip to content
API / API overview
  1. Docs
  2. API
  3. API overview

API overview

How the Space Context REST API works: base URL, API key authentication, the error envelope, pagination, idempotency, rate limits, test mode and endpoints.

Open .md
Text
https://api.spacecontext.app/v1

A JSON API over HTTPS. Field names are snake_case, timestamps ISO 8601 in UTC, money in US cents. The contract is the OpenAPI document, browsable in the API reference; it lists exactly what you call with a key (the console’s own endpoints are not in it). GET /v1 answers a short descriptor with the links to the contract, the docs, llms.txt and the MCP server.

Authentication

Send an API key as a bearer token:

Terminal
curl https://api.spacecontext.app/v1/me \
  -H "Authorization: Bearer $SPACECONTEXT_API_KEY"
JSON
{
  "user": { "id": "…", "email": "you@example.com", "is_pro": false },
  "key": { "id": "key_…", "mode": "test", "scopes": ["spaces:read", "scans:read", "scans:write"] }
}

The console endpoints (/keys, /billing, /webhook-endpoints, and /auth/* except the sign-in steps themselves) take a console session instead and are meant for the console. The terminal sign-in, POST /auth/device and POST /auth/device/token, takes no credential at all: it is how a tool without a key gets one (what spacecontext login does).

Errors

Every error has the same envelope, with a stable code to branch on and a request_id to quote to support. Some errors add fields:

JSON
{
  "error": {
    "code": "INSUFFICIENT_FUNDS",
    "message": "The wallet does not cover this scan",
    "request_id": "8f0c…",
    "balance_cents": 60,
    "price_cents": 100
  }
}

See all error codes.

Pagination

Lists that can grow take limit and cursor and answer next_cursor (null on the last page):

Terminal
curl "https://api.spacecontext.app/v1/spaces?limit=20&cursor=$NEXT" -H "Authorization: Bearer $KEY"

Idempotency

POST /spaces/{id}/scans accepts an Idempotency-Key header (8 to 64 letters, digits, - or _). Retrying with the same key returns the scan already created (200) instead of creating another (201). POST /scans/{id}/start is safe to repeat: a second call answers 200 with the scan already started and charges nothing.

Rate limits

LimitValue
Per key120 requests per minute
Per IP address1 200 requests per minute
Search, per account20 per minute, 1 000 per day
Questions (ask), per account20 per minute, 200 answered per day
Frame checks, per account2 000 per day
Scans processing at once, per account10 (more on request)
New spaces, per account200 per day in each mode (test keys included)
New scans, per account500 per day in each mode (test keys included)
Event streams open at once, per account10, test and live together

A refused request answers 429 RATE_LIMIT_EXCEEDED with the seconds to wait in retry_after, and in a Retry-After header for per-minute limits, new spaces and scans, and event streams. Daily limits reset at midnight UTC; new spaces and scans also say their allowance in daily_limit. An eleventh event stream answers Retry-After: 30 with max_streams: poll GET /scans/{id} until one closes. The SDK and the CLI wait and retry short waits for you, and follow a scan by polling when no stream can be opened. See Limits.

Test mode

Requests made with a test key (sc_test_…) never touch real data: see Concepts. Responses have the same shape in both modes; scans and spaces carry livemode.

Browsers

The API is meant to be called from servers, scripts and agents. Browser calls are accepted only from Space Context’s own sites (CORS); keep keys out of web pages.

Endpoints at a glance

GET /meThe key in use
GET /spaces, POST /spacesList spaces, create a space
GET /spaces/{id}, DELETE /spaces/{id}Read a space (Space Document), delete an API space
GET /spaces/{id}/scans, POST /spaces/{id}/scansScan history, create a scan
GET /spaces/{id}/scans/{scan_id}A past scan as recorded
GET /spaces/{id}/skill, GET /spaces/{id}/markdownThe space as an Agent Skill, or as one Markdown page
POST /spaces/{id}/askAsk a question
GET /spaces/{id}/diffCompare two scans
GET /searchSearch across spaces
GET /scans/{id}, DELETE /scans/{id}A scan, cancel a scan
GET /scans/{id}/eventsFollow a scan live (Server-Sent Events)
PUT /scans/{id}/frames/{index}, PUT /scans/{id}/videoUpload
POST /scans/{id}/startStart and charge
POST /frames/checkIs this frame usable, which key locations does it show (?space_type= for that type’s, and the area)
GET /capture-profiles, GET /capture-profiles/{space_type}What to film for each type of space (public, no key)
GET /walletBalance and free scans
POST /auth/device, POST /auth/device/tokenSign in from a terminal (what spacecontext login does)
GET /media/{key}An evidence frame (signed URL)

Space Context docs · llms.txt · download Edit on GitHub

esc

↑↓ navigate↵ openesc close