# Verifyum agent API

AI agents and automated workflows can create public Verifyum proofs through the production HTTP API. Public access currently requires no account, wallet, payment, API key, or Bearer token.

The agent must have local access to the file. Verifyum does not provide a file upload endpoint. The original file and private proof material must stay on the agent's machine.

## Discovery

Use these canonical resources:

- agent page: <https://verifyum.com/agents>
- LLM discovery file: <https://verifyum.com/llms.txt>
- OpenAPI 3.1 description: <https://verifyum.com/openapi.json>
- private manifest schema: <https://verifyum.com/schema/manifest-v2.json>
- anchor request schema: <https://verifyum.com/schema/anchor-request-v2.json>
- public proof schema: <https://verifyum.com/schema/proof-v2.json>
- optional Witness membership schema: <https://verifyum.com/schema/witness-proof-membership-v1.json>
- browser protocol implementation: <https://verifyum.com/assets/verifyum-protocol.js>
- service health: <https://api.verifyum.com/health>

## MCP endpoint

Agents that use the Model Context Protocol can reach the same service at `https://api.verifyum.com/mcp`. The endpoint is stateless Streamable HTTP with no account or API key, and exposes `verifyum_get_proof`, `verifyum_verify_public_proof`, and `verifyum_anchor_commitment`. It accepts only a commitment, an idempotency key, or a public proof ID. The privacy boundary, limits, and retry rules in this guide apply unchanged. Example client configuration:

    claude mcp add --transport http verifyum https://api.verifyum.com/mcp

## Agent decision records

A common use for this API is sealing an agent's own operating state so the log becomes tamper-evident. Assemble the full state of one decision into a single document, for example:

    {
      "type": "agent-decision-record",
      "recorded_at": "2026-08-31T20:15:04Z",
      "agent": { "name": "claims-triage", "version": "4.2.0" },
      "model": { "provider": "...", "model": "...", "temperature": 0.2 },
      "system_instructions": "...",
      "input": { "prompt": "...", "context_digest": "sha256:..." },
      "tools": [ { "name": "...", "arguments": {}, "result_digest": "sha256:..." } ],
      "output": { "decision": "...", "rationale": "..." }
    }

Serialize it deterministically, then follow the normal flow in this guide: hash the exact bytes locally, build the version 2 manifest and commitment, and anchor only the commitment. Store the record together with its private draft. Verifyum never receives the record, so prompts, retrieved context and customer data stay on your infrastructure.

During a later review you present the record and its private draft. The reviewer recomputes the file hash, rebuilds the commitment and matches it against the finalized Solana transaction. A record that was rewritten, backdated or corrected after the fact will not match.

State the boundary honestly in any audit material: the proof shows that this exact record existed no later than the block time and has not changed since. It does not prove that the agent actually ran with those parameters, because the record is written by the agent's own system. It removes the possibility of silent revision, which is the part a log cannot establish about itself.

Volume: one anchor per decision is rarely necessary. Anchor a per-case or daily record, or maintain a local hash chain of decisions and anchor the chain head periodically. The public limits in this guide apply unchanged.

## Witness Layer

Finalized proofs may also be grouped into hourly and daily checkpoints that are witnessed externally by OpenTimestamps on Bitcoin, a public GitHub checkpoint log, the Internet Archive, and Certificate Transparency. Only aggregate checkpoint roots reach those services.

    GET https://api.verifyum.com/v2/proofs/{proof-id}/witnesses
    GET https://verifyum.com/witness/checkpoints/{hourly|daily}/{batch-id}.json
    GET https://verifyum.com/witness/receipts/{hourly|daily}/{batch-id}.json

The first returns the Merkle path from a proof to its checkpoint, the second the exact checkpoint bytes, and the third the per-channel state with artifact digests. Channel states are `pending`, `confirmed`, `unavailable` or `failed`. Treat a pending or missing witness as normal: it never invalidates the Solana proof or the Verifyum signature. The channels are explained at <https://verifyum.com/witness>.

## Local proof preparation

Perform every step in this section locally.

1. Read the exact file bytes.
2. Calculate the lowercase SHA-256 digest of those bytes.
3. Generate 32 cryptographically secure random bytes. Encode them as unpadded Base64url. The result is exactly 43 characters.
4. Build this exact private manifest. The file size is a decimal string.

       {
         "file": {
           "hash": {
             "algorithm": "sha256",
             "value": "<64 lowercase hex characters>"
           },
           "size": "<decimal byte count>"
         },
         "nonce": "<43-character unpadded Base64url>",
         "protocol": "verifyum",
         "version": 2
       }

5. Canonicalize the manifest with RFC 8785 JSON Canonicalization Scheme.
6. Concatenate the UTF-8 bytes of `verifyum:commitment:v2\n` and the UTF-8 bytes of the canonical manifest.
7. SHA-256 hash the concatenated bytes.
8. Format the public commitment as `sha256:` followed by 64 lowercase hexadecimal characters.
9. Save the manifest, nonce, raw file hash, and commitment in a private local draft, and keep that draft with the original file.

The raw file hash and the final commitment are different values. The final commitment binds the private manifest and nonce without publishing them.

The browser implementation at <https://verifyum.com/assets/verifyum-protocol.js> is the executable reference for manifest construction, canonicalization, hashing, and validation.

## Create the anchor

Check service state first:

    GET https://api.verifyum.com/health

Require `network=mainnet-beta`, `anchoring=enabled`, and `access=public` before creating a public proof.

Submit only the final commitment:

    POST https://api.verifyum.com/v2/anchor
    Content-Type: application/json

    {
      "commitment": "sha256:<64 lowercase hex characters>",
      "idempotency_key": "agent-run-20260830-example-0001"
    }

The idempotency key is optional but strongly recommended. It must contain 16 to 128 URL-safe characters from `A-Z`, `a-z`, `0-9`, `.`, `_`, `~`, and `-`. Reuse the same key only when retrying the same commitment. A key already bound to another commitment returns HTTP 409.

Public access must omit the Authorization header. An invalid or revoked Bearer token does not fall back to public access. The Verifyum operations M2M token is not an anchor credential and must never be sent to this endpoint.

The service returns HTTP 202 while the proof is active and may return HTTP 200 for a terminal result. The response contains a random proof ID, status, status URL, public proof URL, network, and a transaction signature when available.

## Poll the proof

Read the returned status URL:

    GET https://api.verifyum.com/v2/proofs/{proof-id}

Poll every two to five seconds until the status is `finalized` or `failed`. Do not create a second proof to replace a slow request. Resume the same proof ID and keep the original idempotency key.

After finalization, retrieve public metadata from:

    https://{proof-id}.verifyum.com/.well-known/verifyum.json

The public viewer is:

    https://{proof-id}.verifyum.com/

An optional Witness membership can later be read from either equivalent route:

    GET https://api.verifyum.com/v2/proofs/{proof-id}/witnesses
    GET https://{proof-id}.verifyum.com/.well-known/verifyum-witnesses.json

The caller must already know the proof ID. Verifyum provides no operation that
lists checkpoint members. HTTP 404 means the disabled or recently activated
Witness worker has not published a membership for this proof; it does not
invalidate the finalized Protocol v2 proof or Verifyum signature.

When present, validate the canonical checkpoint and its Merkle membership using
the Witness Layer specification. The membership document currently does not
claim that OpenTimestamps, GitHub, Wayback or Certificate Transparency has
confirmed the checkpoint.

## Retry behavior

- HTTP 400, 409, 413, and 415 require a client-side correction.
- HTTP 429 means a rate or policy limit was reached. Honor `Retry-After`.
- HTTP 503 is temporary or means anchoring is disabled. Honor `Retry-After` and recheck health.
- Network timeouts after POST are ambiguous. Retry the same commitment with the same idempotency key.
- Never start a new proof only to hide an unresolved request.

## Limits and cost

Public creation is currently free. AI SENSE AS pays the Solana network fee. This is a current service policy and not a permanent pricing guarantee.

The hard ceiling is ten new anchor reservations per rolling hour per IP. Lower daily per-IP, per-client, global, queue, wallet-balance, and signer-budget controls may stop requests sooner. Keep request rates low and do not parallelize retries.

## Browser and server clients

The public agent API is intended for server-to-server clients and tools without a browser Origin header. Browser CORS is limited to the official Verifyum web origins. A third-party browser application must use its own backend or obtain a separately reviewed integration.

Do not embed private integration credentials in browser code.

## Privacy boundary

The anchor request accepts only `commitment` and optional `idempotency_key`. Do not send:

- original file bytes
- filename
- raw file hash
- nonce
- private manifest or private draft
- user description or personal data
- wallet, RPC, M2M, or service credentials

Public metadata contains the proof ID, commitment, Solana transaction details, and Verifyum service signature. It contains no source file or private manifest fields.

## MCP use

MCP is a useful adapter for Verifyum, but it does not replace this public contract. A remote MCP server may accept a completed commitment and may read public proof status. It must not accept the source file or private manifest. A local MCP process may read a local file path, calculate the commitment, save the private draft locally, and call the public API.

The recommended AI SENSE MCP boundary is documented in [AISENSE-MCP-INTEGRATION.md](AISENSE-MCP-INTEGRATION.md).

## Meaning of the proof

A finalized proof shows that a commitment to the exact file bytes existed no later than the estimated Solana block time. It does not by itself prove authorship, ownership, signature validity, legal status, or whether the file's claims are true.
