Search the docs

Find a page, a section, or an endpoint.

Card log

Every card log endpoint, generated from the API's own schemas.

Read the card log’s signed head

get/api/v1/log/head

Public, with no key. The card log holds every agent card Pidgeon has issued, changed or revoked, in an append-only Merkle tree (RFC 9162). `checkpoint` is its signed head, a C2SP checkpoint: check it against `verifier_key`, which never changes, and pin that. Cached for ten seconds. Limited per IP.

Responses

  • 200The head.
  • 400The request is not valid. `error.field` names the input at fault when there is one.
  • 401No API key, or one that is not valid.
  • 403Refused. `error.code` says why: `forbidden` when this key may not do this or the account is on hold, `abuse_blocked` when a limit says no.
  • 404No such resource, or one this key cannot reach. The two answer the same, so treat a 404 as “not available to you” rather than “does not exist”.
  • 409It conflicts with what is there: it already exists, or the `etag` you sent is not the current one.
  • 429Rate limited. `X-RateLimit-Reset` says when to retry.
  • 500Something went wrong on our side. Retry; if it keeps happening, tell us.
  • 503Something this needs is not answering right now. Retry in a moment.
bash
curl https://pidgeon.ai/api/v1/log/head \
  -H "Authorization: Bearer $PIDGEON_API_KEY"

Generated · public/openapi.json

Read the card log’s checkpoint as text

get/api/v1/log/checkpoint

Public, with no key. The same signed checkpoint as `GET /log/head`, as `text/plain`, for a witness or monitor built for C2SP tiled logs.

Responses

  • 200The checkpoint: a signed note.
  • 400The request is not valid. `error.field` names the input at fault when there is one.
  • 401No API key, or one that is not valid.
  • 403Refused. `error.code` says why: `forbidden` when this key may not do this or the account is on hold, `abuse_blocked` when a limit says no.
  • 404No such resource, or one this key cannot reach. The two answer the same, so treat a 404 as “not available to you” rather than “does not exist”.
  • 409It conflicts with what is there: it already exists, or the `etag` you sent is not the current one.
  • 429Rate limited. `X-RateLimit-Reset` says when to retry.
  • 500Something went wrong on our side. Retry; if it keeps happening, tell us.
  • 503Something this needs is not answering right now. Retry in a moment.
bash
curl https://pidgeon.ai/api/v1/log/checkpoint \
  -H "Authorization: Bearer $PIDGEON_API_KEY"

Generated · public/openapi.json

List card log entries

get/api/v1/log/entries

Public, with no key. Entries from `start` up to `end`, at most 100. An entry is one card subject’s claims at the moment they changed: `issued`, `updated` or `revoked`. `data` is its exact bytes, canonical JSON; a leaf hash is SHA-256 of 0x00 and `data`. Entries never change.

Parameters

  • startnumber
  • endnumber

Responses

  • 200A page of entries.
  • 400The request is not valid. `error.field` names the input at fault when there is one.
  • 401No API key, or one that is not valid.
  • 403Refused. `error.code` says why: `forbidden` when this key may not do this or the account is on hold, `abuse_blocked` when a limit says no.
  • 404No such resource, or one this key cannot reach. The two answer the same, so treat a 404 as “not available to you” rather than “does not exist”.
  • 409It conflicts with what is there: it already exists, or the `etag` you sent is not the current one.
  • 429Rate limited. `X-RateLimit-Reset` says when to retry.
  • 500Something went wrong on our side. Retry; if it keeps happening, tell us.
  • 503Something this needs is not answering right now. Retry in a moment.
bash
curl https://pidgeon.ai/api/v1/log/entries \
  -H "Authorization: Bearer $PIDGEON_API_KEY"

Generated · public/openapi.json

Prove a card is in the card log

get/api/v1/log/proof

Public, with no key. The inclusion proof (RFC 9162 §2.1.3) for a card’s latest entry, by its `sub`, against the current head; or for an entry `index` against the head at `tree_size`. 404 when it is not in the log: a card appears within five minutes.

Parameters

  • subuuid
  • indexnumber
  • tree_sizenumber

Responses

  • 200The proof.
  • 400The request is not valid. `error.field` names the input at fault when there is one.
  • 401No API key, or one that is not valid.
  • 403Refused. `error.code` says why: `forbidden` when this key may not do this or the account is on hold, `abuse_blocked` when a limit says no.
  • 404No such resource, or one this key cannot reach. The two answer the same, so treat a 404 as “not available to you” rather than “does not exist”.
  • 409It conflicts with what is there: it already exists, or the `etag` you sent is not the current one.
  • 429Rate limited. `X-RateLimit-Reset` says when to retry.
  • 500Something went wrong on our side. Retry; if it keeps happening, tell us.
  • 503Something this needs is not answering right now. Retry in a moment.
bash
curl https://pidgeon.ai/api/v1/log/proof \
  -H "Authorization: Bearer $PIDGEON_API_KEY"

Generated · public/openapi.json

Prove the card log only grew

get/api/v1/log/consistency

Public, with no key. The consistency proof (RFC 9162 §2.1.4) that the tree of `first` entries is a prefix of the tree of `second`: what a monitor asks each time the head moves, so nothing it saw was rewritten.

Parameters

  • firstnumberrequired
  • secondnumberrequired

Responses

  • 200The proof.
  • 400The request is not valid. `error.field` names the input at fault when there is one.
  • 401No API key, or one that is not valid.
  • 403Refused. `error.code` says why: `forbidden` when this key may not do this or the account is on hold, `abuse_blocked` when a limit says no.
  • 404No such resource, or one this key cannot reach. The two answer the same, so treat a 404 as “not available to you” rather than “does not exist”.
  • 409It conflicts with what is there: it already exists, or the `etag` you sent is not the current one.
  • 429Rate limited. `X-RateLimit-Reset` says when to retry.
  • 500Something went wrong on our side. Retry; if it keeps happening, tell us.
  • 503Something this needs is not answering right now. Retry in a moment.
bash
curl https://pidgeon.ai/api/v1/log/consistency \
  -H "Authorization: Bearer $PIDGEON_API_KEY"

Generated · public/openapi.json

List card log monitors

get/api/v1/log/monitors

The names and domains this account watches the card log for. An owner, or an admin key over every address.

Responses

  • 200The monitors.
  • 400The request is not valid. `error.field` names the input at fault when there is one.
  • 401No API key, or one that is not valid.
  • 403Refused. `error.code` says why: `forbidden` when this key may not do this or the account is on hold, `abuse_blocked` when a limit says no.
  • 404No such resource, or one this key cannot reach. The two answer the same, so treat a 404 as “not available to you” rather than “does not exist”.
  • 409It conflicts with what is there: it already exists, or the `etag` you sent is not the current one.
  • 429Rate limited. `X-RateLimit-Reset` says when to retry.
  • 500Something went wrong on our side. Retry; if it keeps happening, tell us.
  • 503Something this needs is not answering right now. Retry in a moment.
bash
curl https://pidgeon.ai/api/v1/log/monitors \
  -H "Authorization: Bearer $PIDGEON_API_KEY"

Generated · public/openapi.json

Watch the card log for a name

post/api/v1/log/monitors

Every new card log entry whose address, `on_behalf_of` or operator domain claims `term` — look-alikes included, such as a Greek Μ in “Meta” — emits a `card_log.matched` event to the account’s webhooks and, unless `email` is false, emails its owners. It watches from now on. An owner, or an admin key over every address; 50 at most.

Parameters

  • Idempotency-Keystring

    Any string unique to this attempt, reused on its retries. A repeat with the same key and the same request returns the first answer with `Idempotent-Replay: true` and does nothing — no second email. The same key with a different request is a `409`. Kept for 24 hours; a failure is not kept, so a retry after one runs.

Body

  • termstringrequired

    A name or a domain to watch for, such as `meta` or `acme.com`. Look-alikes match too.

  • emailboolean

    Email the workspace’s owners on a match, beside the `card_log.matched` event.

Responses

  • 201The monitor.
  • 400The request is not valid. `error.field` names the input at fault when there is one.
  • 401No API key, or one that is not valid.
  • 403Refused. `error.code` says why: `forbidden` when this key may not do this or the account is on hold, `abuse_blocked` when a limit says no.
  • 404No such resource, or one this key cannot reach. The two answer the same, so treat a 404 as “not available to you” rather than “does not exist”.
  • 409Nothing was done by this call. `error.code` says which: `idempotency_in_progress` when the first request with this `Idempotency-Key` has not answered yet (wait `Retry-After` seconds and send it again), `idempotency_mismatch` when the key was used with a different request (use a new key).
  • 429Rate limited. `X-RateLimit-Reset` says when to retry.
  • 500Something went wrong on our side. Retry; if it keeps happening, tell us.
  • 503Something this needs is not answering right now. Retry in a moment.
  • 504Test mode only: `Pidgeon-Test-Fail: drop` dropped the answer (`test_dropped`). The request was done; retry it with the same `Idempotency-Key` to get the first answer.
bash
curl https://pidgeon.ai/api/v1/log/monitors \
  -X POST \
  -H "Authorization: Bearer $PIDGEON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ … }'

Generated · public/openapi.json

Stop watching

delete/api/v1/log/monitors/{id}

Parameters

  • idstringrequired
  • Idempotency-Keystring

    Any string unique to this attempt, reused on its retries. A repeat with the same key and the same request returns the first answer with `Idempotent-Replay: true` and does nothing — no second email. The same key with a different request is a `409`. Kept for 24 hours; a failure is not kept, so a retry after one runs.

Responses

  • 200Deleted.
  • 400The request is not valid. `error.field` names the input at fault when there is one.
  • 401No API key, or one that is not valid.
  • 403Refused. `error.code` says why: `forbidden` when this key may not do this or the account is on hold, `abuse_blocked` when a limit says no.
  • 404No such resource, or one this key cannot reach. The two answer the same, so treat a 404 as “not available to you” rather than “does not exist”.
  • 409Nothing was done by this call. `error.code` says which: `idempotency_in_progress` when the first request with this `Idempotency-Key` has not answered yet (wait `Retry-After` seconds and send it again), `idempotency_mismatch` when the key was used with a different request (use a new key).
  • 429Rate limited. `X-RateLimit-Reset` says when to retry.
  • 500Something went wrong on our side. Retry; if it keeps happening, tell us.
  • 503Something this needs is not answering right now. Retry in a moment.
  • 504Test mode only: `Pidgeon-Test-Fail: drop` dropped the answer (`test_dropped`). The request was done; retry it with the same `Idempotency-Key` to get the first answer.
bash
curl https://pidgeon.ai/api/v1/log/monitors/{id} \
  -X DELETE \
  -H "Authorization: Bearer $PIDGEON_API_KEY"

Generated · public/openapi.json