veil

Read a person’s card

Read the full public card, signed record, proof and recent history.

GET/u/{card}.json
Access
Public; API key optional
Client
Browser fetch supported

Other addresses#

  • /u/{card}
  • /v1/identities/{n}

Parameters#

NameLocationMeaning
cardRequiredPathA permanent card number or its current alias.

Request examples#

cURL
curl -fsS 'https://veil.rip/u/1.json'
javascript
const response = await fetch("https://veil.rip/u/1.json");
const result = await response.json();

Try the request#

Response#

HTTP 200application/json

The card includes n, id, url, type, keys, links and proof. historyBefore points to older history. An erased card returns a public tombstone with HTTP 410.

FieldTypeMeaning
nintegerPermanent card number.
urlstringPermanent URL using the card number.
namestringCurrent display name; a hidden name becomes Card followed by its number.
initialsstringInitials for an image fallback.
sincestringVersion-one date in YYYY-MM-DD UTC.
idstringVersion-one commitment in hex; the source of the fingerprint.
idSaltobject | nullserver and client salt halves in hex. client can be null.
tokenstringStable public-log pseudonym in base64url.
versionintegerCurrent published version.
keysarray<CardKey>All device and recovery keys, including revoked keys.
linksarray<CardLink>Linked accounts and pending takeovers.
orgsarray<CardOrg>Accepted organisation affiliations of a person.
eventsarray<CardEvent>Newest page of card history, ordered oldest first within the page.
witnessesobject | nullsigned, of and needed counts for the current version. These are server checks.
nodesinteger | nullNumber of hashes in the current inclusion path.
fingerprintFingerprintTwelve words in each language and twelve five-digit groups.
proofCardProof | nullCurrent opening and inclusion proof. Null means the log could not be verified now; never treat it as verified.
erasureobject | nullrequestedAt and executesAt for a pending erasure.
typestringperson or organization.
membersarray<CardMember>, optionalPresent for an organisation, including pending invitations.
moderationobject | nullPublic moderation state and actions.
eventsTotalintegerTotal history events across all pages.
historyBeforeinteger | nullPass as before to the history endpoint to read the older page.
badgesarray<object>Active signed or derived badges.
nameHiddenobject | nullPublic reason, since and logIndex for a hidden name.
logoobject, optionalImage type and URL; omitted without a visible image.
logoHiddenobject, optionalPublic reason for a hidden logo.
aliasstring | nullCurrent alias; it can change.
aliasUrlstring | nullCurrent alias address. Use n as the permanent identifier.
formatinteger | optional2 on a log in format 2; absent in format 1.
currentV2Version | optionalFormat 2: the current version with label, body, signature, signedBy, logIndex, publishedAt and entry.
authorityarray<V2Version> | optionalFormat 2: authority versions from version 1, at most 50, each with its log entry, i and inclusion proof on the index checkpoint.
authorityNextinteger | null | optionalFormat 2: where GET /v1/identities/{n}/authority?after= continues, or null.
stateobject | optionalFormat 2: head, keys, links, orgs, the first page of members, external (public keys from elsewhere, [] when none) and the set roots; roots.external is there only when the card has public keys from elsewhere.
externalarray<CardExternal> | optionalFormat 2: the public keys from elsewhere as the page shows them, with the server’s check in proofOk. Your client checks each proof again from state.external and does not rely on proofOk.
indexV2IndexBundle | null | optionalFormat 2: the card’s index bundle on the proof’s checkpoint, as the log serves it at /index/<token>, with statements and statementsNext added. Null when the log gave none.
standinginteger | null | optionalFormat 2: the log position of the card’s last staff statement as the server knows it, or null. A staff browser puts it in prev of a new statement. The verified value is index.value.standing.
alertsarray<object> | optionalFormat 2, a person: the alerts in force on its linked accounts, one per account (platform, subject, display, state, since, to, logIndex, publishedAt). The server’s word: check them with GET /v1/identities/{n}/alerts.
statementsobject | optionalFormat 2: the card’s signed statements in short: total, latest (the three newest: id, title, publishedAt, retracts, retracted, url), url and feed.
HTTP 304none

Not modified. The rebuilt card has the same bytes as the ETag you sent. Reuse the card stored with it and verify it as usual. There is no response body, and an erased card still answers 410.

Expand a nested object for its fields. Types ending in null allow a null value; optional fields may be absent. Other fields are present in that object.

Device key CardKey
FieldTypeMeaning
idstringDevice label shown on the card.
algstringReadable algorithm name.
fpstringFull public key as stored in the signed record.
ed25519stringEd25519 key or composite-key half, in hex.
sincestringDate the key was added.
statestringactive, offline or revoked. Offline denotes a recovery key.
revokedstring | nullRevocation date, when revoked.
rolestringSigning role assigned to the key.
addedInintegerVersion that added the key.
revokedIninteger | nullVersion that revoked the key.
Linked account CardLink
FieldTypeMeaning
servicestringPlatform identifier.
handlestringDisplay handle or normalised account.
idstring | nullStable provider ID, when separate from the handle.
howstringProof method, such as oauth, dns_txt, well_known, emailCode or backlink.
atstringTime the link was established.
statestringactive or pending.
untilstring | nullPending takeover deadline.
takeoverinteger | nullPending takeover ID.
unicodestring, optionalUnicode spelling of an international domain. Keep the ASCII handle as the identifier.
addedIninteger | nullVersion that added the link.
logIndexinteger | nullZero-based log index of that version.
checkCardLinkCheck, optionalThe server’s periodic re-check of the proof (since 30 October 2026), for an active domain, Fediverse or GitHub link it has checked at least once. Its word, not part of the signed card.
Re-check of a proof CardLinkCheck
FieldTypeMeaning
statestringok, failing (the place answered and the proof is not there) or unreachable (no answer).
atstringTime of the last check that got an answer.
sincestring, optionalSince when the proof has not confirmed. Absent while ok.
reportedbooleanTrue once 30 days passed without a confirmation and the owner was told. The link stays.
Card fingerprint Fingerprint
FieldTypeMeaning
wordsobjecten and it each contain the same twelve word-list positions in their language.
digitsarray<string>Twelve groups of five decimal digits.
Organisation affiliation CardOrg
FieldTypeMeaning
nintegerPermanent card number.
urlstringPermanent card URL.
namestringDisplay name, subject to moderation.
rolestringAccepted membership role.
sincestringMembership start time.
nameHiddenbooleanWhether staff hide the name.
logoobject | nullImage type and URL, when available.
Organisation member CardMember
FieldTypeMeaning
nintegerMember’s permanent card number.
urlstringMember card URL.
namestringMember’s display name.
rolestringMembership role.
statestringMembership state, including pending invitations.
sincestring | nullAcceptance time, when accepted.
iconstring | nullRole icon, when provided.
nameHiddenbooleanWhether staff hide the member’s name.
logoobject | nullImage type and URL.
Card history event CardEvent
FieldTypeMeaning
tstringPublication time in ISO 8601 UTC.
kindstringChange kind, such as created, added, revoked, renamed or takeover.
byobjectdevice, key and identity of the signer, where available.
ninteger | nullCard version, or null for an external event.
logIndexinteger | nullZero-based log index.
devicestring | nullDevice concerned by the change.
servicestring | nullPlatform concerned by the change.
handlestring | nullAccount concerned by the change.
changesarray<string>All changes in this version, in a fixed order.
Card proof CardProof
FieldTypeMeaning
versionintegerVersion covered by this proof.
recordstringExact canonical JSON text that was signed. Do not reformat before verifying.
saltstringCommitment salt in hex.
serverSaltstringServer’s salt contribution in hex.
clientSaltstring | nullDevice’s salt contribution in hex, when used.
commitmentstringSHA-256 of salt bytes followed by record bytes, in hex.
signedBystringPublic signing key.
signaturestringSignature over the identity-version prefix and exact record.
entrystringExact canonical log entry text.
logIndexintegerZero-based leaf index.
leafHashstringSHA-256 of 0x00 followed by entry bytes, in hex.
checkpointCheckpointSigned checkpoint containing size, root and note.
inclusionarray<string>Audit-path hashes in hex, deepest sibling first.
witnessesarray<string>Witness cosignature lines also present in checkpoint.note.
Checkpoint Checkpoint
FieldTypeMeaning
sizeintegerNumber of leaves in the signed tree.
rootstringRoot hash in base64.
notestringFull signed note, including log and witness signatures.
Version in format 2 V2Version
FieldTypeMeaning
labelstringThe canonical label exactly as signed, after the prefix veil-rubrica:identity-version:v2 and a line break. For an organisation it carries signer, the member card that signs and its version. Its hash is the c that the index keeps for the version.
bodystringThe canonical body: the operations outside label.auth and the salt. It never carries signer. label.body is its hash.
signaturestringThe signature over the prefix and the label.
signedBystringThe key that signed.
logIndexinteger | nullZero-based position of the version’s entry in the log.
publishedAtstring | nullEarliest cosignature time on the first checkpoint that held it.
entrystringThe version’s log entry as text: key, label, signature and v. The index checks the signature from this entry alone.
iinteger, optionalIn the authority list of a card: the entry’s log position, the same as logIndex.
inclusionarray<string>, optionalIn the authority list of a card: the entry’s inclusion proof in hex, deepest sibling first, on the checkpoint of index. Absent without a verified log.
Index bundle V2IndexBundle
FieldTypeMeaning
checkpointobjectnote, the checkpoint signed by the log with the witness cosignatures, and size.
entryobjectThe checkpoint’s last index entry: i, entry and its inclusion proof.
valueobject | nullThe card’s value in the index: auth, closed, latest and standing. Null when the card is not in the index.
proofobjectbitmap and siblings: the proof of value under the root of the index entry.
tailarray<object>The entries after the index entry, each with i, entry and inclusion. Apply those of this card to value yourself.
statementsarray<StatementEntry> | nullThe first page, at most 200, of the card’s counted staff statements, newest first. The first is value.standing and each prev is the i of the next. An empty array means no statements, null means the server could not read or prove the chain.
statementsNextstring | nullThe address of the next page of statements, or null when the chain ends here.
Statement entry StatementEntry
FieldTypeMeaning
iintegerThe entry’s position in the log.
entrystringThe entry text as the log holds it, signature included.
inclusionarray<string>Inclusion proof in hex, deepest sibling first, on the checkpoint of the card’s index bundle.
byinteger, optionalCard number of the staff member who signed. A hint for display: the signer in the entry is what counts.
Public key from elsewhere
FieldTypeMeaning
typestringssh-ed25519, ssh-ecdsa-p256, ssh-ecdsa-p384, ssh-rsa, pgp, minisign, ed25519, ml-dsa-44, ml-dsa-65 or ml-dsa-87.
fpstringThe fingerprint as its own tools print it: SHA256:… for SSH and ML-DSA, the 40 hex digits of the version 4 fingerprint in capitals for OpenPGP, the 16-digit key ID for minisign, the key in hex for Ed25519.
labelstringThe name the person gave the key, up to 40 characters.
pubstringThe public key in its canonical form, without comment. For OpenPGP, the base64 of its packets: the primary key with its self-signatures, the user IDs the person kept, the signing subkeys.
idsarray<string> | optionalOpenPGP only, when the key carries user IDs: the ones the person chose to keep, as the key writes them. Your client reads them again from pub and shows only those with a valid self-certification.
addedInintegerThe card version that added the key.
sincestringWhen that version was published.
logIndexinteger | nullThe log entry of that version.
proofOkbooleanThe server’s own check of the proof. Informative only.
anchorobject | nullThe quoted checkpoint: origin, size, root and signedAt, the quorum’s cosigning time.
consistencyobject | nullAn RFC 6962 consistency proof {size, proof} from the quoted size to the size of the card’s checkpoint, or null.

Response headers#

HeaderValueMeaning
Content-Typeapplication/jsonUse the declared media type before choosing a parser.
DateHTTP dateServer time. Compare it with your clock when signing requests.
ETagW/"<SHA-256 of the JSON bytes>"Send it back in If-None-Match. The server rebuilds the card with current visibility, moderation and proofs, and answers 304 only when the JSON bytes are the same.
Cache-Controlprivate, no-cache, must-revalidateA shared cache does not keep the card, and a client revalidates it before every reuse.
Retry-Afterinteger seconds, on rate_limited or busyWait at least this long before retrying. Other 429/503 codes do not necessarily include it.

What to verify#

Verify proof, the version chain and the expected identity. The summary endpoint alone does not carry this proof.

Usage notes#

  • Without .json, send Accept set to application/json. The /v1 variant requires the permanent number.
  • On a log in format 2 the card adds format, current, authority, authorityNext, state, index and standing, and proof carries the v2 entry instead of the record. index.statements is the first page of the card’s staff statements, and index.statementsNext leads to the next one.

Errors#

API errors return an error object. Use error.code for program logic; error.message is English text for people and can change. Response and error guide

HTTPCodeMeaning and next step
400invalid_parameter

A path, query or body field is missing, malformed or outside its accepted range.

Correct the field named in error.message before sending again.

404not_found

The requested card, key, alias, code or resource was not found.

Check the identifier. Temporary codes and previews may already have expired or been used.

410erased

The card existed and was erased or removed. The response also carries its public erasure receipt.

Stop using this card as current authority. Retain only the public receipt if needed.

When using an optional API key
HTTPCodeMeaning and next step
401invalid_api_key

The bearer credential is malformed, unknown, expired or revoked.

Use an active key. To use anonymous public access, remove Authorization entirely. Invalid credentials never fall back automatically.

403api_key_scope

The API key lacks read or verify scope, or the endpoint does not accept bearer keys.

Use the correct scope. Identity writes and key management still require a device signature.

403api_key_suspended

This API key is suspended.

Ask staff to restore it; another key cannot lift an account suspension.

403developer_suspended

The owner’s API account is suspended or the owner card is unavailable.

Check the owner account and any staff restriction. Creating another key does not bypass suspension.

Shared request errors
HTTPCodeMeaning and next step
429rate_limited

An anonymous, signed-request or API-key allowance was exceeded.

Wait at least Retry-After seconds. Share a queue and retry budget across your workers.

500internal_error

An unexpected server error occurred. Internal details are not returned.

Retry reads with bounded backoff. Check write results before sending a new signed operation.

503busy

The application has reached a temporary concurrency or database limit.

Wait Retry-After seconds and retry with bounded backoff.