Instructions for assistants
Use this page when a user asks you to use their Graunt subscriptions and content entitlements.
Start
Ask the user for their Graunt Access Pass. The pass is a string of the form gap_live_ followed by 64 hex characters. Treat it as a credential — store it only for the current conversation, and do not echo it back to other users.
Pass scopes
Every pass has one of three scopes — the manifest's pass.scope_kind tells you which:
SINGLE_PACKET— one selected entitlement. The manifest lists exactly that resource.PACKET_SET— a set of entitlements the user picked. The manifest lists those resources.FULL_ENTITLED_LIBRARY— every active entitlement and every active subscription in the user's library.
Scopes resolve dynamically. If an entitlement is refunded, revoked, or expires after the pass is created, it disappears from the manifest on the next call. Newly purchased content appears only when scope rules allow it.
Retrieve the manifest
Call POST https://api.graunt.com/v1/access-passes/resolve with the pass in the Authorization: Bearer gap_live_... header. Then call GET https://api.graunt.com/v1/access-passes/manifest with the same header.
The manifest contains the user's currently-active entitlements + subscriptions. Each entitlement carries a rights summary, provenance summary, and supported access modes. Follow those — Graunt's rights model is the source of truth for what the user is permitted to do with the content.
The manifest's pass.router block links to compact and detail endpoints. Default to compact; ask for detail per-resource only when you need it.
Use the content
Three delivery shapes are available for in-scope resources:
- Inline content —
GET /v1/access-passes/resources/{id}/content?asset_id=...&offset=...&length=...returns asset bytes up to 1 MiB per call. Use this for short text, JSON, CSV, JSONL, or Markdown assets. - Rows —
GET /v1/access-passes/resources/{id}/records?asset_id=...&row_start=...&row_end=...returns parsed rows from CSV/JSONL/tabular assets as paginated JSON. - Full packet bundle —
GET /v1/entitlements/{id}/packet-bundlewith the sameAuthorization: Bearer gap_live_...header returns short-lived presigned URLs for every asset in the bundle. The presigned URLs are entitled delivery; they are not pass tokens.
Always:
- Use ONLY resources listed in the manifest. Do not invent IDs.
- Cite sources per the manifest's
rights_summary.citation_requiredfield. - Respect
no_trainandno_redistributeflags. Do not include the content in training datasets or redistribute it. - Honor
license_familyper resource.
Conversational assistants vs file-based tools
There are two ways to consume a Graunt packet. Pick the one that fits the tool:
- Key access (this page) — for conversational assistants: ChatGPT, Claude, Gemini, Grok, or any MCP-compatible client. The user pastes a
gap_live_pass and you retrieve content live through the access plane. No download. This is the default. - LLM-ready pack — for file-based tools (Cursor, Codex, project-file workflows) and API agents that prefer a local copy. The buyer exports a portable ZIP via
GET /v1/entitlements/{id}/llm-ready-packand drops it into the project. It containsREADME_FOR_LLM.md(start here),ROUTER.md(navigation),MANIFEST.json,RIGHTS.md,PROVENANCE.md,EVALUATION.md,LIMITATIONS.md,USAGE_PROMPTS.md, the source files underoriginals/, andchecks/checksums.sha256. - Original source archive —
GET /v1/entitlements/{id}/source-archivedelivers just the raw files when that is all you need.
Key access is the default usage path; the LLM-ready pack and the source archive are portable fallbacks. All three use the same entitlement — there is no separate product to register for.
Answers and verification
POST /v1/query/ask currently returns answers with verifier_kind: STUB_VERIFIER — citation binding is not yet enforced at runtime. Treat answers as un-verified for now. The flag is set to flip to DETERMINISTIC_LIVE_VERIFIER in a later slice, and the response will say so when it does.
When Graunt denies a request
If a Graunt API call returns a JSON body with ok: false and an error.code field, tell the user plainly what happened. Common codes:
ACCESS_PASS_EXPIRED— the pass timed out. Ask the user to create a new pass.ACCESS_PASS_REVOKED— the user revoked the pass.ACCESS_PASS_LIBRARY_EMPTY— there is no active library to surface yet.ACCESS_PASS_RATE_LIMITED— you are calling too fast. Slow down and try again.ACCESS_PASS_OUT_OF_SCOPE— the resource is not in this pass's scope. Use a different pass or a wider scope.ACCESS_PASS_DAILY_BYTE_BUDGET_EXCEEDED— the pass has read its per-day byte budget. Try again tomorrow or use the packet bundle delivery route.ACCESS_PASS_ASSET_NOT_INLINEABLE— the asset is binary or otherwise not text-shaped. Use the packet bundle route instead.ACCESS_PASS_CONTENT_TOO_LARGE— yourlengthexceeds 1 MiB. Page through the asset in chunks.
Self-revoke
An assistant holding a pass may revoke that pass by calling POST /v1/access-passes/revoke with the same Authorization: Bearer gap_live_... header and an empty JSON body {}. The pass becomes unusable immediately. This affects only the bearer's own pass; cross-pass revoke is reserved for the user's account.
The access plane serves inline content under 1 MiB through /v1/access-passes/resources/{id}/content and row-shaped data through /records. For the full packet bundle, GET /v1/entitlements/{id}/packet-bundle issues short-lived presigned URLs scoped to the entitled delivery. A scoped pass can only reach entitlements the user selected at pass creation.