veil

Save a card as a contact

Download a person’s card as a vCard for a phone or a mail client: the name, the card’s address, the verified accounts and the 12 words.

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

Parameters#

NameLocationMeaning
cardRequiredPathA person’s permanent card number or its current alias.
langQueryen or it: the note’s words and the fingerprint’s word list. English is the default.

Request examples#

cURL
curl -fsS -o veil-1.vcf 'https://veil.rip/u/1.vcf'

Response#

HTTP 200text/vcard

A vCard 4.0 (text/vcard): FN and N with the card’s name, UID and URL with the card’s permanent address (and its alias), EMAIL for each verified email address, URL for each verified GitHub, Discord, domain and Fediverse account, PHOTO with the profile picture (a small PNG inline, or a GIF by address), NOTE with the 12-word fingerprint and where to check it, REV and SOURCE.

Response headers#

HeaderValueMeaning
Content-Typetext/vcard; charset=utf-8A vCard 4.0 in UTF-8, with CRLF line ends.
Cache-Controlno-cacheAsk again each time: a removed key leaves the file at once.
Content-Dispositionattachment; filename="veil-<n>.vcf"Saved under the card’s number, never its name.

What to verify#

Before you trust a saved contact for anything that matters, open the card it names and compare the 12 words with the ones in the note: the card checks its keys in your browser, the file does not.

Usage notes#

  • The file is the server’s word, built from the same data as the card’s previews. Its note says so, and names the card where the check runs in the reader’s browser.
  • Only for a card shown as it is: never for one that is suspended, closed or removed, or whose name the Veil staff hid. Organisations have no contact file.
  • No platform the directory links today has a standard instant-messaging address, so the file has no IMPP line: Discord, GitHub, a domain and the Fediverse are profile URLs.

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
404not_found

No person card has this number or alias; or the card is an organisation, is suspended, or has its name hidden by the Veil staff, so it has no contact file.

Open the card to see its state. A contact file comes back once the card is shown as it is again.

410erased

The card was closed or removed, so it has no contact file.

Remove the contact you saved from it, or mark it as closed.

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.