Errors
Every failure has the same error shape, and a 422 gives the reason for each field.
Every error has the same shape. It has a code for your code, a message for people and sometimes details.
{
"error": {
"code": "validation_failed",
"message": "Name can't be blank.",
"details": { "name": ["can't be blank"] }
}
}
Codes
| Status | code |
Means |
|---|---|---|
| 400 | invalid_parameter, invalid_json |
A query parameter or the JSON body is malformed |
| 401 | unauthorized |
No token, or a bad one (Authentication) |
| 403 | session_required |
Only Nifty itself can do this, not a token |
| 403 | read_only |
Nifty is read-only: the trial has ended with no licence that covers this version (Read-only) |
| 403 | read_only_token |
The token is read only, so it can't make changes (Read-only tokens) |
| 404 | not_found |
No such record, or the ID isn't one |
| 409 | conflict, folder_not_empty, in_use, idempotency_key_in_use |
It clashes with the record's state, or a retry is still running |
| 411 | length_required |
An upload without Content-Length |
| 413 | payload_too_large |
The body is too big |
| 415 | unsupported_media_type |
The body isn't application/json |
| 422 | validation_failed |
A field is wrong: see details |
| 422 | idempotency_key_reused, provider_error, key_required, already_added |
See the endpoint's reference |
| 429 | rate_limited |
Too many requests: wait |
| 500 | internal_error |
Nifty failed. No details |
| 503 | busy, timeout |
busy: Nifty is already making as many PDFs as it can, so retry after Retry-After seconds. timeout: the work took too long. Both come from a note's PDF |
Each endpoint in the reference lists the errors it can return (People, for example).
422: what was wrong
details maps each field, or base for the record as a whole, to its problems. The problems are phrases you can show
beside the field. A 400 uses the same details for query parameters.
Read-only
When the free trial has ended and there's no licence that covers this version, every POST, PUT, PATCH and
DELETE gets 403 read_only. A revoked key doesn't cover versions released after it was revoked. Every GET still
works. The exceptions are the licence itself, your password, username, authenticators and API tokens, appearance,
sounds and update settings. A token can read the licence (GET /api/v1/licence, System), but
it can't change it. Add or replace a licence from a signed-in session in the app (Nifty → Licence…), or with
nifty licence add on the server. A refused POST doesn't use up its Idempotency-Key.
Rate limits
Each IP address can make 300 API requests a minute. After that, requests get 429 rate_limited with a Retry-After
header that says how many seconds to wait. A few endpoints, such as checking for updates, have tighter limits of their
own.
Reporting a problem
Every response has an X-Request-Id header, and the server's log names each request by it
(journalctl -u nifty | grep <id>). Quote the ID when you ask for help.