Error handling
Every error response follows RFC 7807 (application/problem+json). This page lists every status code the API emits, whether the client should retry, and what action is appropriate.
Response shape
HTTP/2 404
content-type: application/problem+json
{
"type": "https://api.sandbox.messpunkt.io/errors/resource-not-found",
"title": "Resource not found",
"status": 404,
"detail": "Property d490d09c-46cc-498e-a9ac-e031dd2402d2 not found in this Tenant's scope",
"trace_id": "e9048b1072c8443b"
}
type is a stable identifier you can branch on in code; title is human-readable but may be localised in the future; trace_id is the single best thing to include when you open a support ticket.
Status-code matrix
Applies to all /v1/* data endpoints. OAuth endpoints (/oauth/*) use the OAuth 2.0 error format (RFC 6749 §5.2) — see the OAuth table below.
| Status | type suffix |
Retryable? | Recommended client action |
|---|---|---|---|
400 |
invalid-request |
No | Malformed request — missing required query parameter, bad date format, etc. Fix the request, do not retry. |
401 |
invalid-token |
After refresh | Access token missing, expired, or malformed. Refresh the token via grant_type=refresh_token and retry once. If refresh also fails, restart the authorization flow. |
401 |
invalid-dpop-proof |
No | DPoP proof failed validation (wrong htu/htm, clock skew, reused jti, missing cnf.jkt match). Fix the proof generation — see the DPoP guide. |
403 |
insufficient-scope |
No | Token is valid but lacks a scope required for this endpoint (e.g. calling a read:readings endpoint with only read:units). Re-authorize requesting the missing scope. |
404 |
resource-not-found |
No | Either the resource doesn't exist, or it exists but is outside your Property scope. The API deliberately does not distinguish these — see Property scope in the Reference. Treat 404 on a previously-known ID as "access revoked"; refresh your Property list via /whoami and re-fetch /properties. |
422 |
validation-failed |
No | Query was well-formed but semantically invalid (from after to, unknown metric value). Response includes a field-level breakdown. Fix and do not retry. |
429 |
too-many-requests |
Yes | Rate limit exceeded. Honour the Retry-After header (seconds). Use exponential backoff for bursty loads — see Retry strategy below. |
500 |
internal-error |
Yes | Unexpected server error. Retry with exponential backoff. Include trace_id if you escalate. |
502 / 503 / 504 |
(platform-level) | Yes | Gateway or cold-start transient. Retry with exponential backoff. Usually resolves within a few seconds. |
OAuth endpoint errors
The /oauth/authorize and /oauth/token endpoints follow RFC 6749 §5.2 — a flat {"error": "...", "error_description": "..."} body:
error |
Meaning | Action |
|---|---|---|
invalid_request |
Missing or malformed parameter on the request. | Fix and retry. |
invalid_client |
Unknown client_id, or client_id mismatch between the authorization code and the token request. |
Fix client config. Do not retry the same request. |
invalid_grant |
Authorization code is expired, wrong redirect_uri, PKCE verifier doesn't match, refresh token is replayed or the session was revoked. |
Restart the authorization flow — do not retry. If this happened on refresh, the refresh-token family was revoked: the user must re-consent. |
invalid_scope |
Requested a scope that's not in the original grant (refresh-time scope narrowing only). | Request a subset of the original scopes, or re-authorize to widen. |
unsupported_grant_type |
Only authorization_code and refresh_token are supported. |
Fix the request. |
invalid_redirect_uri |
The redirect_uri is not on the allow-list for this client_id. |
Use a registered redirect URI, or contact us to register a new one. |
Retry strategy
For 429 and 5xx responses, use exponential backoff with jitter:
- Attempt 1: wait max(
Retry-After, 1 s) - Attempt 2: wait 2 s ± 500 ms random jitter
- Attempt 3: 4 s ± 1 s
- Attempt 4: 8 s ± 2 s
- Attempt 5: 16 s ± 4 s
- Stop at 5 retries. Log
trace_id, surface a user-facing message, and continue.
Getting help
When you open a support ticket, always include:
- The
trace_idfrom the response body - The UTC timestamp of the request
- Your
client_id - The HTTP method + path (without secrets)
Email: kontakt@messpunkt.io — we respond within 1 business day during the pilot phase.