API reference

Anchors

External timestamp receipts for your record's root, each with instructions a stranger can follow without asking us.

GET /v1/anchors

List anchor receipts

Lists the receipts written when your root was anchored externally, each with instructions to check it without us.

Auth
session cookie or API key
Capability
anchors
Success
HTTP 200

A failed attempt is still a receipt: status anchor_failed with the error text and no how_to_check. With the provider set to none the list reports provider_status anchoring_disabled and no receipts are written.

Parameters

None.

Request body

None.

Example request

curl

curl -sS -X GET "https://api.afaprotocol.com/v1/anchors" \
  -H "X-API-Key: afa-beta-EXAMPLE-e4qs"

Python

import requests

API = "https://api.afaprotocol.com"
headers = {"X-API-Key": "afa-beta-EXAMPLE-e4qs"}

r = requests.get(f"{API}/v1/anchors", headers=headers, timeout=30)
r.raise_for_status()
print(r.json())

Example response

HTTP 200
{
  "anchors": [
    {
      "anchor_id": "anc-7d2f9a1c4b3e8065",
      "created_at": "2026-09-01T14:12:10+00:00",
      "error": null,
      "external_ref": "90de9e6cde8c1f312afba912cfed5bf673d11b43884607adf9ee608a2b6bc79f50b3722e2df1539b",
      "how_to_check": {
        "commands": [
          "rekor-cli get --uuid 90de9e6cde8c1f312afba912cfed5bf673d11b43884607adf9ee608a2b6bc79f50b3722e2df1539b",
          "rekor-cli get --log-index 412039871"
        ],
        "provider": "rekor",
        "recompute": "sha256 over proof_json.record serialised as JSON with sorted keys and no whitespace must equal proof_json.record_sha256; that digest is the hash the external entry carries. The entry's signature verifies against proof_json.public_key_pem over that digest.",
        "search_url": "https://search.sigstore.dev/?uuid=90de9e6cde8c1f312afba912cfed5bf673d11b43884607adf9ee608a2b6bc79f50b3722e2df1539b",
        "url": "https://rekor.sigstore.dev/api/v1/log/entries/90de9e6cde8c1f312afba912cfed5bf673d11b43884607adf9ee608a2b6bc79f50b3722e2df1539b"
      },
      "integrated_time": 1756735930,
      "proof_json": {
        "log_index": 412039871,
        "public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAExampleKeyBytesOnlyReplaceMe0000000000=\n-----END PUBLIC KEY-----\n",
        "record": {
          "issued_at": "2026-09-01T14:12:10+00:00",
          "root": "sha256:fa169e47437c116de26d2e8a91c3cd7c75c91c12cbe418cb3d60804008eb496c",
          "schema": "afa.anchor.record.v1",
          "subject": "2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14"
        },
        "record_sha256": "a5b922e3dbf400f3ca9f9194635e1d84c9e9813af47b651757dfcb6084007e2b",
        "rekor_url": "https://rekor.sigstore.dev"
      },
      "provider": "rekor",
      "root": "sha256:fa169e47437c116de26d2e8a91c3cd7c75c91c12cbe418cb3d60804008eb496c",
      "status": "anchored",
      "user_id": "2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14"
    }
  ],
  "provider": "rekor",
  "provider_error": null,
  "provider_status": "ok",
  "user_id": "2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14"
}

Errors

StatusCodeMeaning
401missing_token / invalid_or_expired_api_keyNo credential, an expired session, or a revoked or expired key.
403scope_missingA key limited by scopes lacks anchors; the body names it.

What would show this is false

Follow how_to_check without us: fetch the log entry by its reference and recompute record_sha256 from proof_json.record. The entry carries that digest.

POST /v1/anchors/run

Anchor the current root now

Anchors the account's current root with the configured provider, or reports unchanged if it has not moved.

Auth
session cookie or API key
Capability
anchors
Success
HTTP 200

HTTP 200 describes the request; status describes the outcome: anchored, unchanged, anchor_failed, no_root, anchoring_disabled or provider_misconfigured. A provider failure still writes a receipt row carrying the error.

Parameters

None.

Request body

None.

Example request

curl

curl -sS -X POST "https://api.afaprotocol.com/v1/anchors/run" \
  -H "X-API-Key: afa-beta-EXAMPLE-e4qs"

Python

import requests

API = "https://api.afaprotocol.com"
headers = {"X-API-Key": "afa-beta-EXAMPLE-e4qs"}

r = requests.post(f"{API}/v1/anchors/run", headers=headers, timeout=30)
r.raise_for_status()
print(r.json())

Example response

HTTP 200
{
  "anchor_id": "anc-7d2f9a1c4b3e8065",
  "provider": "rekor",
  "receipt": {
    "anchor_id": "anc-7d2f9a1c4b3e8065",
    "created_at": "2026-09-01T14:12:10+00:00",
    "error": null,
    "external_ref": "90de9e6cde8c1f312afba912cfed5bf673d11b43884607adf9ee608a2b6bc79f50b3722e2df1539b",
    "how_to_check": {
      "commands": [
        "rekor-cli get --uuid 90de9e6cde8c1f312afba912cfed5bf673d11b43884607adf9ee608a2b6bc79f50b3722e2df1539b",
        "rekor-cli get --log-index 412039871"
      ],
      "provider": "rekor",
      "recompute": "sha256 over proof_json.record serialised as JSON with sorted keys and no whitespace must equal proof_json.record_sha256; that digest is the hash the external entry carries. The entry's signature verifies against proof_json.public_key_pem over that digest.",
      "search_url": "https://search.sigstore.dev/?uuid=90de9e6cde8c1f312afba912cfed5bf673d11b43884607adf9ee608a2b6bc79f50b3722e2df1539b",
      "url": "https://rekor.sigstore.dev/api/v1/log/entries/90de9e6cde8c1f312afba912cfed5bf673d11b43884607adf9ee608a2b6bc79f50b3722e2df1539b"
    },
    "integrated_time": 1756735930,
    "proof_json": {
      "log_index": 412039871,
      "public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAExampleKeyBytesOnlyReplaceMe0000000000=\n-----END PUBLIC KEY-----\n",
      "record": {
        "issued_at": "2026-09-01T14:12:10+00:00",
        "root": "sha256:fa169e47437c116de26d2e8a91c3cd7c75c91c12cbe418cb3d60804008eb496c",
        "schema": "afa.anchor.record.v1",
        "subject": "2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14"
      },
      "record_sha256": "a5b922e3dbf400f3ca9f9194635e1d84c9e9813af47b651757dfcb6084007e2b",
      "rekor_url": "https://rekor.sigstore.dev"
    },
    "provider": "rekor",
    "root": "sha256:fa169e47437c116de26d2e8a91c3cd7c75c91c12cbe418cb3d60804008eb496c",
    "status": "anchored",
    "user_id": "2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14"
  },
  "recorded": true,
  "root": "sha256:fa169e47437c116de26d2e8a91c3cd7c75c91c12cbe418cb3d60804008eb496c",
  "status": "anchored"
}

Errors

StatusCodeMeaning
401missing_token / invalid_or_expired_api_keyNo credential, an expired session, or a revoked or expired key.
403scope_missingA key limited by scopes lacks anchors; the body names it.

What would show this is false

Run twice without new events: the second answers unchanged, names the first anchor_id, and recorded is false.