Errors and hints
The error envelope, every code the API can return, and the hint that accompanies each. Generated from the code.
Every error is JSON: { "code": "…", "hint": "…", ... } with an HTTP status that means what it usually means — 400 your input, 401 no valid key, 403 not allowed, 404 not yours or not there, 409 conflict, 413 too big, 429 slow down, 502 something upstream. Extra fields when useful: field, detail, suggestions, retryAfter.
{ "code": "username_taken", "hint": "Choose another name — see `suggestions` — or check one first with GET /api/username/check?u=<name>.", "field": "username", "suggestions": ["anna-bakes-official", "anna-bakeshq"] }Read code to branch, hint to know what to do, detail to know where. The hints are English and stable; the codes are the contract.
| code | hint |
|---|---|
unauthorized | Send Authorization: Bearer tapmy_sk_…, or create a page first with POST /api/agent/pages, which returns a key. |
invalid_key | The key is malformed. Keys look like tapmy_sk_ followed by 43 URL-safe characters. |
key_revoked | This key was revoked in the dashboard. Ask the owner for a new one, or create a new page to get a fresh key. |
forbidden_via_key | This action needs a browser session, not an API key. The owner can do it in the dashboard. |
invalid_fields | The body did not match the schema. detail names the first offending field; the schema is at /openapi.json. |
too_short | Usernames are 3 to 30 characters. |
too_long | Usernames are 3 to 30 characters. |
bad_chars | Usernames use lowercase a–z, 0–9 and single hyphens only. |
edge_hyphen | A username cannot start or end with a hyphen. |
double_hyphen | A username cannot contain two hyphens in a row. |
reserved | This name belongs to the service. Pick another one. |
username_taken | Choose another name — see suggestions — or check one first with GET /api/username/check?u=<name>. |
email_taken | An account with this e-mail exists. Log in with it, or omit email to create a provisional account the owner can claim later. |
limit_reached | A program may create at most 10 pages on one account. Delete one, use another account, or let the owner add pages by hand in the dashboard — that has no ceiling. |
banned | This page was banned by moderation and cannot be edited until a human clears it. |
not_found | No page with this id belongs to the authenticated account. |
bad_path | A short path must be 1–40 characters of a–z, 0–9 and hyphens, unique within the page, and not a reserved word. detail names the path. |
bad_url | Only http(s) URLs with a real hostname are accepted. |
blocked | That host resolves to a private or local address, or refused the request. Use a public URL. |
unreachable | The URL could not be fetched. Check it opens in a browser and try again. |
too_large | The file is over the size limit: 8 MB for avatars and cards, 30 MB for backgrounds. |
not_image | The bytes are not a JPEG, PNG, WebP, AVIF, GIF, TIFF or HEIC image. |
processing_failed | The image could not be decoded. Try a different file. |
nothing_found | No outbound links were found on that page. |
js_only | That page renders its links with JavaScript and cannot be read. Add the links by hand. |
rate_limited | Too many requests. Wait retryAfter seconds (also in the Retry-After header) and try again. |
claim_invalid | This claim link is not valid. Ask for a new one with POST /api/agent/claim-link. |
claim_expired | This claim link has expired. Ask for a new one with POST /api/agent/claim-link. |
claim_used | This account has already been claimed. Log in at /login. |
already_claimed | This account already has an e-mail and password; there is nothing to claim. |
bad_credentials | The e-mail or password is wrong. |
no_file | Send the image as multipart/form-data field file, or as JSON { "url": "https://…" }. |
bad_kind | kind must be avatar, background or card. |
quota | The daily quota for this import is used up. |