Errors
An error answers with an HTTP status and a JSON body holding an error object:
{
"error": {
"type": "validation_error",
"code": "invalid_request",
"message": "Request validation failed",
"details": {
"target": "body",
"issues": [{ "message": "\"file\" is required", "path": ["file"], "type": "any.required" }]
}
}
}
type is the category and code the specific reason. Branch on those, not on message, which is written for people and
can change. details is optional; for a request that fails validation it names the part of the request that failed
(target) and lists each problem (issues).
| Status | type |
Meaning |
|---|---|---|
400 |
validation_error |
The request, or one of its fields, is invalid |
401 |
authentication_error |
The token is missing or not valid |
403 |
authorization_error |
The token may not do this, for example a read-only token on a write |
404 |
not_found_error |
The resource or the route does not exist |
409 |
conflict_error |
The request conflicts with data that already exists |
409 |
not_ready_error |
Your library has not finished its first sync yet |
429 |
rate_limit_error |
Too many requests; see Rate limiting |
500 |
internal_error |
Something failed inside Paperpile |
502, or upstream status |
api_error |
A service Paperpile relies on failed or refused the request |
503 |
sync_error |
The change could not be synced to Paperpile's servers |
A few responses use an older shape instead, { "error": { "msg": "…", "status": 404 } }: a request to a path outside
/v1 that doesn't exist, some errors from upstream services, and unexpected server errors (500). Check for
error.type first and fall back to the HTTP status.
The MCP endpoint (POST /) reports rate limiting as a JSON-RPC error, and its 401 responses carry a WWW-Authenticate
header pointing to the OAuth protected resource metadata.