Authentication
Every request to a /v1 endpoint needs an API key. Keys start with tmk_, and you can send one
in either of two headers:
curl -X POST "$TICKMARKS_API/v1/schemas/validate" \ -H "Authorization: Bearer tmk_live_4fJ2kq9XbT8mWc1R" \ -H "Content-Type: application/json" -d @schema.jsoncurl -X POST "$TICKMARKS_API/v1/schemas/validate" \ -H "x-api-key: tmk_live_4fJ2kq9XbT8mWc1R" \ -H "Content-Type: application/json" -d @schema.jsonIf you send both, Tickmarks uses Authorization.
A key acts on behalf of the account that created it, so anyone holding it can run extractions that count against your usage. Keep it on your server. It doesn’t belong in browser code, mobile apps, URLs or version control, and it should only ever travel over HTTPS.
Create, list and revoke keys
Section titled “Create, list and revoke keys”You manage keys in the panel at app.tickmarks.nl under API keys. If you don’t have an account yet, sign up: every new account gets €0.05 of free credit (10 reads). When you create one, you give it a name of 1 to 64 characters, and you can also set an expiry of 1 to 365 days (by default it never expires) and limit its scopes (by default it has all of them). The panel shows the full key once, at creation. After that, the key list shows only its name, first characters, scopes and expiry, so copy the key somewhere safe straight away.
Revoking a key takes effect immediately: the next request that uses it gets 401.
Scopes
Section titled “Scopes”Give each key only the access it needs. A key that runs in CI to check schemas, for example, only
needs schemas:validate, so a leak can’t be used to run extractions.
| Scope | Grants |
|---|---|
extractions:create |
POST /v1/extractions |
extractions:edit |
POST /v1/extractions/edit |
schemas:validate |
POST /v1/schemas/validate |
Rate limits
Section titled “Rate limits”Each key can make 60 requests per minute. Past that, requests get 429 until the minute is up,
so back off and retry.
The API also applies burst protection across an account: 120 authenticated requests per minute across its keys, MCP and dashboard, and 30 model extractions per minute across those same surfaces. Changing keys does not reset the account limits. A coarse 300-request-per-minute IP limit protects the API before authentication. These additional limits use Cloudflare’s per-location counters and are approximate burst limits, separate from prepaid credit accounting.
HTTP throttling responses use 429 rate_limited and Retry-After: 60. An extraction throttled
before inference uses no reads. Inside MCP, an extraction tool can instead return an isError
result containing rate_limited; wait 60 seconds before retrying that tool. Health checks, CORS
preflight and signed payment callbacks are excluded from the coarse IP limit.
Errors
Section titled “Errors”Every authentication failure is a 401 unauthorized with the same message, whatever the cause,
including a key without the right scope.
{ "error": { "code": "unauthorized", "message": "Invalid, expired or insufficiently scoped API key." }}If you get one, work through the possible causes:
| Status | error.code |
Cause | What to do |
|---|---|---|---|
401 |
unauthorized |
No key sent | Add one of the headers above. |
401 |
unauthorized |
Key unknown, revoked or expired | Create a new key. |
401 |
unauthorized |
Key lacks the endpoint’s scope | Create a key with that scope. |
429 |
rate_limited |
More than 60 requests in a minute | Wait and retry. |