# Truestamp full guide for LLM agents (MCP + HTTP APIs) This is the full guide, served at `https://www.truestamp.com/llms-full.txt`: the detailed companion to the concise `https://www.truestamp.com/llms.txt` overview. It covers connecting an agent over MCP and writing integration code against the Truestamp HTTP APIs. If you are connected over MCP and want to OPERATE Truestamp directly (create items, generate or verify proofs, read the ledger), prefer the native MCP tools (call `quickstart` first); they are typed and need no hand-built HTTP. Reach for the HTTP APIs when you are generating an integration: a script, a backend service, or a no-code automation. ## Connect over MCP (operate Truestamp live) The MCP server at `https://www.truestamp.com/mcp` is the preferred surface for OPERATING Truestamp through an agent (read, preview/create items, generate/verify proofs) with typed tools instead of hand-built HTTP. Transport is MCP Streamable HTTP (JSON-RPC 2.0 over POST). It is an OAuth 2.1 protected resource: there is NO API key or header to paste. A compliant client discovers the authorization server from the unauthenticated 401 challenge, registers itself, and opens a browser for you to sign in and consent; it then holds a short-lived access token and refreshes it automatically. Request the `mcp:read` scope to read and `mcp:write` to create items. Once connected, call the `quickstart` tool first to orient. (The server is feature-flag gated; if it is disabled, `/mcp` returns 404.) Configure it in Claude Code (no `--header`; it runs the OAuth flow for you): claude mcp add --transport http truestamp https://www.truestamp.com/mcp Or in a client config file (`.mcp.json`, or the client's `mcpServers` block) - a remote HTTP MCP entry; the client prompts you to authenticate on first use: { "mcpServers": { "truestamp": { "type": "http", "url": "https://www.truestamp.com/mcp" } } } Client caveat: the MCP surface requires OAuth 2.1. Clients that perform the MCP OAuth flow (Claude Code, Claude.ai connectors, IDE agents) connect automatically. Clients that can only send a static `Authorization: Bearer` header (no OAuth) cannot use `/mcp`; use the HTTP APIs below with an API key instead. Session lifetime: access tokens last 24h and the client should renew silently with its 30-day refresh token. Some clients (currently Claude Code) do not refresh after a long idle and instead report that re-authorization is required - if that happens, just reconnect (`/mcp` in Claude Code); it runs a fresh login and reuses your existing consent (no re-approval). This is a client-side behavior, not a Truestamp limitation. For integration code, Truestamp also exposes two HTTP surfaces, all authenticated the same way: - REST / JSON:API at `https://www.truestamp.com/api/json` (full read + write, JSON:API v1.1). - GraphQL at `https://www.truestamp.com/gql` (full read + write). ## Authentication (both surfaces) Send your API key as a bearer token on every request: Authorization: Bearer API keys are created per user in the Truestamp dashboard (Settings -> API Keys) and are shown only once at creation time. A missing or invalid key returns `401 Unauthorized`. The key authenticates the user; every request acts as that user under the same authorization as the web app. ## Team context (both surfaces) Truestamp is multi-tenant; writes land in one team. Select it with a header (or query param) named `tenant` (alias `X-Truestamp-Team-Id`) carrying the team UUID: X-Truestamp-Team-Id: 019526a4-1234-7abc-8000-abcdef012345 If you omit it, the server resolves the team in this order: the `tenant` header, then the `tenant` query param, then the user's saved default-team preference, then the user's personal team. Reads of a user's own items span all their teams automatically. Ledger reads (blocks, commitments, entropy observations, beacons) are global: they still require a valid API key, but no team header. (Every HTTP surface requires a key; the only unauthenticated public surface is the HTML `/beacons` page, not a JSON endpoint.) Discover your team UUIDs with `GET https://www.truestamp.com/api/json/teams` (JSON:API), the `listTeams` GraphQL query, or `accounts.user.whoami` over MCP code mode. ## Base URL This guide is served from `https://www.truestamp.com`. All paths and examples below are relative to that base URL (the curl examples set `BASE="https://www.truestamp.com"`). ## Conventions that matter - Truestamp proves WHEN data was SUBMITTED within a verifiable window, not when it was created. Use "submitted" / "submission window", not "created". - Say "commit" / "commitment" (committing a block to a public blockchain), never "anchor". - Item claims have two modes. Every item's `claims` must include a `name`. (1) Hash mode: send `hash` AND `hash_type` together; the hash is the data being timestamped. (2) Claims-as-source-of-truth mode: omit both; the claims content itself is timestamped, and you must include either a `description` of at least 32 characters or a non-empty `metadata` object. - Omit optional claim fields rather than sending them as `null`. Null and absent are treated identically (null keys are dropped before the `claims_hash` is computed), so omitting keeps payloads small and predictable. ## REST / JSON:API (`/api/json`) The REST API conforms to the JSON:API v1.1 specification (https://jsonapi.org). Use the media type `application/vnd.api+json` for both `Content-Type` and `Accept`. Responses are JSON:API documents: a top-level `data` (a resource object, or an array of them) with `type`, `id`, `attributes`, and `links`. Create an item (hash mode): BASE="https://www.truestamp.com" KEY="" curl -X POST "$BASE/api/json/items" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/vnd.api+json" \ -H "Accept: application/vnd.api+json" \ -H "X-Truestamp-Team-Id: " \ -d '{ "data": { "type": "item", "attributes": { "claims": { "name": "Quarterly report", "hash": "dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f", "hash_type": "sha256" }, "visibility": "private", "tags": ["report"] } } }' Read items (newest first): curl "$BASE/api/json/items?sort=-inserted_at" \ -H "Authorization: Bearer $KEY" \ -H "Accept: application/vnd.api+json" \ -H "X-Truestamp-Team-Id: " Response (trimmed): { "data": [ { "type": "item", "id": "01J...", "attributes": { "state": "committed", "claims_hash": "401d9e...", "claims": {"name": "Quarterly report", "hash": "dffd60...", "hash_type": "sha256"} }, "links": {"self": "..."} } ], "links": {"next": "...page[after]=..."} } GraphQL equivalent: `{"query": "query { listItems { results { id state } } }"}`. ### Query parameters (JSON:API only; not GraphQL) - Pagination: item lists are KEYSET-paginated and bounded by default (25 per page, 100 max). A request without `page[limit]` returns the first 25 plus a `links.next` URL (carrying a `page[after]` cursor) to fetch the next page; `page[before]` pages backward. Example: `GET /api/json/items?page[limit]=25`. See https://jsonapi.org/format/#fetching-pagination. - Filtering: `GET /api/json/items?filter[state]=committed&filter[visibility]=public`. See https://jsonapi.org/format/#fetching-filtering. - Sorting: `GET /api/json/items?sort=-inserted_at` (prefix `-` for descending; comma-separate multiple keys). - Sparse fieldsets: `GET /api/json/items?fields[item]=claims_hash,state`. - Includes (related resources): `GET /api/json/items?include=team,creator,block`. - More worked examples: https://jsonapi.org/examples/. The authoritative, per-endpoint list of supported filters, sorts, and page params is in the OpenAPI spec (and the auto-generated endpoint index at the end of this guide). Not every resource supports every parameter. Item lists default to 25 per page (100 max); other list endpoints have their own limits in the spec. The per-plan claims size cap is enforced server-side. Explore and validate the REST API: - Interactive (Swagger UI): `https://www.truestamp.com/api/json/swaggerui` - Reference (ReDoc): `https://www.truestamp.com/api/json/redoc` - Machine-readable OpenAPI 3.0 spec: `https://www.truestamp.com/api/json/open_api` ## GraphQL (`/gql`) POST queries and mutations to `https://www.truestamp.com/gql` with `Content-Type: application/json` and the same `Authorization` and team headers. Body shape is standard GraphQL: `{"query": "...", "variables": {...}}`. A minimal authenticated request to confirm connectivity (every POST to `/gql` needs a valid API key; only GET `/gql/playground` is reachable without one): curl -X POST "https://www.truestamp.com/gql" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -H "X-Truestamp-Team-Id: " \ -d '{"query": "query { __typename }"}' Build and validate real queries in the GraphiQL playground, a browser UI at `https://www.truestamp.com/gql/playground` (open it in a browser, not via curl; set the `Authorization` header there to execute queries). The available root queries and mutations are listed in the auto-generated index at the end of this guide. ## Proofs (generate and verify) Proofs are the core deliverable. A proof must be passed to a verifier EXACTLY as produced: never reorder, truncate, or reformat it. Generate a proof for a committed subject. You MUST declare the subject `type` (no auto-detection): one of `item`, `block`, `beacon`, `entropy_nist`, `entropy_stellar`, `entropy_bitcoin`. `id` is the subject's ULID (items) or UUIDv7 (block / beacon / entropy). Arguments go under `data`; the proof comes back under `result`: curl -X POST "$BASE/api/json/proof/generate" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/vnd.api+json" \ -H "Accept: application/vnd.api+json" \ -d '{"data": {"id": "01J...", "type": "item"}}' # -> {"result": { ... the proof object ... }} Verify a proof you hold. Pass the WHOLE proof object (the `result` from generate) back unchanged as `proof`; optional `skip_external` skips live Stellar / Bitcoin lookups and `expected_hash` asserts the subject's data hash. The verification report comes back under `result` with a boolean `passed`: curl -X POST "$BASE/api/json/proof/verify" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/vnd.api+json" \ -H "Accept: application/vnd.api+json" \ -d '{"data": {"proof": {"...": "the result object from generate"}, "skip_external": false}}' GraphQL equivalents: `generateProof(id: "01J...", type: "item")` and `verifyProof(proof: {...})`. ## Errors On auth failure every API surface returns `401` with a `WWW-Authenticate: Bearer realm="Truestamp API"` header. Bodies: JSON:API and MCP return a JSON:API error document (`{"errors": [{"status", "code", "title", "detail"}]}`); GraphQL returns its error envelope (`{"errors": [{"message", "extensions": {"code"}}]}`). Other failures: JSON:API and the proof routes use JSON:API error documents; GraphQL reports them in the `errors` array. Send `Accept: application/json` (or `application/vnd.api+json`) so error bodies come back as JSON. ## REST endpoint index (auto-generated from the OpenAPI spec) - `GET /api/json/beacons` : List recent beacons - `GET /api/json/beacons/by-hash/{hash}` : Get a beacon by block hash - `GET /api/json/beacons/latest` : Get the latest finalized beacon (current head) - `GET /api/json/beacons/{id}` : Get a beacon by block id - `GET /api/json/block_healing_events` : List healing events - `GET /api/json/block_healing_events/{id}` : Get a healing event by id - `GET /api/json/blocks` : List blocks - `GET /api/json/blocks/{id}` : Get a block by id - `GET /api/json/commitments` : List commitments - `GET /api/json/commitments/{id}` : Get a commitment by id - `GET /api/json/entropy_observations` : List entropy observations - `GET /api/json/entropy_observations/{id}` : Get an entropy observation by id - `GET /api/json/epochs` : List epochs - `GET /api/json/epochs/{id}` : Get an epoch by id - `GET /api/json/external_commitments` : List external commitments - `GET /api/json/external_commitments/{id}` : Get an external commitment by id - `GET /api/json/invitations` : List team invitations - `GET /api/json/invitations/{id}` : Get a team invitation by id - `GET /api/json/items` : List items (paginated, 25 per page by default, 100 max) - `POST /api/json/items` : Create an item - `GET /api/json/items/{id}` : Get an item by id - `PATCH /api/json/items/{id}` : Update an item - `GET /api/json/memberships` : List team memberships - `GET /api/json/memberships/{id}` : Get a team membership by id - `POST /api/json/proof/generate` : Generate a proof - `POST /api/json/proof/verify` : Verify a proof - `GET /api/json/teams` : List teams - `POST /api/json/teams` : Create a team you own (subject to your plan's team limit) - `GET /api/json/teams/{id}` : Get a team by id - `GET /api/json/users` : List users - `GET /api/json/users/me` : Return the authenticated user's own profile. - `GET /api/json/users/{id}` : Get a user by id - `GET /api/json/webhook-deliveries` : List webhook deliveries - `GET /api/json/webhook-deliveries/{id}` : Get a webhook delivery by id - `GET /api/json/webhook-endpoints` : List webhook endpoints - `POST /api/json/webhook-endpoints` : Create a webhook endpoint - `DELETE /api/json/webhook-endpoints/{id}` : Delete a webhook endpoint - `GET /api/json/webhook-endpoints/{id}` : Get a webhook endpoint by id - `PATCH /api/json/webhook-endpoints/{id}` : Update a webhook endpoint ## GraphQL operations (auto-generated from the schema) Queries: - `beacon` : Get a beacon by block id (UUIDv7). - `beaconByHash` : Get a beacon by block hash (hex). - `beacons` - `getBlock` - `getBlockHealingEvent` : Read healing events - `getCommitment` : Read commitments with filtering and pagination - `getEntropyObservation` : Get a single entropy observation by ID - `getEpoch` : Read epochs with filtering and pagination - `getExternalCommitment` : Read external commitments with filtering and pagination - `getInvitation` : Get a single invitation by ID - `getItem` : Get a single item by ID - `getMembership` : Get a single membership by ID - `getTeam` : Get a single team by ID - `getUser` : Get a single user by ID - `getWebhookDelivery` : Get a webhook delivery by ID - `getWebhookEndpoint` : Get a webhook endpoint by ID - `hash` : Compute a cryptographic hash of the given UTF-8 text, returned as a - `health` : Health check endpoint that returns system status and version information. - `jcsCanonicalize` : Canonicalize a JSON object with JCS (RFC 8785): keys sorted, insignificant - `kbFetch` : Fetch a knowledge-base concept by id (TOC-first), or a single section when an anchor is given. Fetch the id `
/index` for a section's concept map (a directory such as `internal/index` or a domain such as `api/index`), or `index` for the whole knowledge base, to see what exists before drilling in (progressive disclosure). To browse by cross-cutting tag instead of by domain, fetch `tags` for every tag with its concept count, or `tag/` for the concepts carrying that tag. Returns not-found for concepts outside the caller's audience. - `kbLinks` : Fetch the visible incoming and outgoing links of a knowledge-base concept by id: which concepts it references (related, prerequisites, body links) and which concepts reference it (backlinks). Use `direction` to limit to `in`, `out`, or `both` (default `both`). Returns not-found for a concept outside the caller's audience. - `kbSearch` : Search the Truestamp knowledge base by keyword, optionally within a domain (product, verification, cryptography, merkle, entropy, blockchain, items, teams, accounts, api, integrations, glossary, library, platform). Returns lightweight results (concept id, title, summary, section anchors) for progressive disclosure; fetch full text with kb_fetch. To browse a domain instead of searching, kb_fetch the id `/index` (or `index` for the whole knowledge base). - `latestBeacon` : Get the latest finalized or committed beacon (current head). - `listBlockHealingEvents` : Read healing events - `listBlocks` - `listCommitments` : Read commitments with filtering and pagination - `listEntropyObservations` : List all entropy observations. - `listEpochs` : Read epochs with filtering and pagination - `listExternalCommitments` : Read external commitments with filtering and pagination - `listInvitations` : List all invitations you are authorized to see. - `listItems` : List all items you are authorized to see. - `listMemberships` : List all memberships you are authorized to see. - `listTeams` : List all teams you are authorized to see. - `listUsers` : List all users you are authorized to see. - `listWebhookDeliveries` : List your recent webhook deliveries - `listWebhookEndpoints` : List your webhook endpoints - `me` : Return the authenticated user's own profile. - `resolveId` : Identify what an opaque ULID or UUIDv7 id refers to, so you can decide what - `ulidTimestamp` : Extract the embedded creation time from a ULID identifier (used for - `uuidv7Timestamp` : Extract the embedded creation time from a UUIDv7 identifier (used for - `verifyHash` : Check whether a given hex hash matches the hash of the given text. Defaults Mutations: - `createItem` : Create a new item - `createTeam` : Create a new team - `createWebhookEndpoint` : Create a webhook endpoint - `destroyWebhookEndpoint` : Delete a webhook endpoint - `generateProof` : Generate a proof for a committed subject. The caller MUST declare - `updateItem` : Update an existing item - `updateWebhookEndpoint` : Update a webhook endpoint - `verifyProof` : Verify a cryptographic proof. Reads the proof's signed `t` code