Developers · HTTP API

The Agent API.

A read-only HTTP API for programmatic and agent access to your vault. Bearer-authed with a Personal Access Token, scoped to your account, part of Granite Paid.

Base URL & auth

All requests go to https://api.granite.co/v1 over HTTPS, with your token in the Authorization header:

Authorization: Bearer gra_live_…

The API is served on its own host so your app session cookie never reaches it — it is bearer-only. Create a token under Settings → Developer → Access tokens. Free or canceled plans get 402.

Scopes

Each token carries one or more scopes (orthogonal to the plan gate):

scopegrants
documents:readlist / read / search documents, poll status
vault:askvault Q&A (POST /ask)

Endpoints

method + pathscopenotes
GET /v1/documentsdocuments:readcursor-paginated list (metadata)
GET /v1/documents/:iddocuments:readfull doc; ?include=full_text adds the OCR body
GET /v1/documents/:id/statusdocuments:readingest-status poll
GET /v1/search?q=&mode=documents:readmode = hybrid (default) / keyword / semantic
POST /v1/ask?q=vault:askvault Q&A (answer + citations)

Pagination

GET /v1/documents returns { documents, next_cursor, has_more }. Pass the opaque next_cursor back as ?cursor=… for the next page (a keyset on (created_at, id), stable across bulk-inserted ties). ?limit= defaults to 50, max 100.

Examples

TOKEN=gra_live_xxx

# list
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.granite.co/v1/documents?limit=20"

# next page
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.granite.co/v1/documents?cursor=<next_cursor>"

# full document incl. OCR text
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.granite.co/v1/documents/<id>?include=full_text"

# search
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.granite.co/v1/search?q=2024%20W-2"

# ask
curl -XPOST -H "Authorization: Bearer $TOKEN" \
  "https://api.granite.co/v1/ask?q=When%20does%20my%20passport%20expire%3F"

Rate limits

Per token (keyed on the owning account): 60 req/min, 500 reads/day, 200 ask/day (ask shares the in-app vault-Q&A budget). Responses advertise RateLimit-Policy; over a limit → 429 with Retry-After.

Errors

Errors are JSON { "error": "<code>" }:

statuscodemeaning
401unauthenticatedmissing / invalid / revoked / expired token
402feature_lockednot on a paid plan
403insufficient_scopetoken lacks the required scope
404not_foundno such document for this account
422query_required / query_too_long / invalid_modebad input
429rate_limitedthrottled

Security

Returned document text is run through an output sanitizer that neutralizes injected-instruction-shaped content — a defense against prompt injection via uploaded documents. It's a layer, not a guarantee; treat vault content as you would any data an agent ingests. Every call is written to your audit log and surfaced under Settings → Access tokens, so you can see exactly what each agent has done.

Prefer an MCP client? The MCP server wraps this API for Claude Desktop, Claude Code, and Cursor.