Errors and Business Rules
Errors use Problem Details JSON. Every error response includes:
typetitlestatusdetail- optional
errors
Common statuses:
| Status | Meaning |
|---|---|
401 | Missing or invalid bearer token |
403 | Credential does not have the required scope |
404 | Referenced client-owned site, project, item, or resource was not found |
409 | Duplicate resource, optimistic concurrency conflict, idempotency conflict, or invalid site-asset assignment |
413 | Uploaded file is larger than the allowed limit |
422 | Request validation failed |
429 | Request rate limit exceeded |
5xx | Transient service or upstream dependency failure |
Problem Details examples
Rate limit response:
{
"type": "https://api.ssn.local/problems/rate-limit-exceeded",
"title": "Too Many Requests",
"status": 429,
"detail": "Client API requests are limited to 100 requests per minute."
}
Validation response:
{
"type": "https://api.ssn.local/problems/validation-error",
"title": "Validation Error",
"status": 422,
"detail": "Request validation failed.",
"errors": {
"body.siteCode": ["Required"]
}
}
Retry guidance
Retry only when the failure is likely transient:
- retry
429responses with backoff and lower request concurrency - retry transient
502,503, or504responses with backoff - retry network timeouts when the request used an
Idempotency-Key - do not retry
401,403, or422without changing credentials, scopes, or request data - treat
404and most409responses as data issues to inspect before retrying
Use a unique Idempotency-Key for each create request. If a request times out
or receives a transient response, retry the same request body with the same key.
If the same key is reused with a different request body, the API returns 409
to prevent accidental duplicate or mismatched creates.
Upload failures
File upload endpoints accept form field name file.
- return labels accept PDF files
- message attachments accept PDF, PNG, and JPEG files
- uploaded files must be 10 MB or smaller
- empty uploads are rejected as validation errors
Important business rules:
siteCodemust be unique per client.clientTicketNumbershould be unique per client.projectIdmust belong to the client and be active.itemNamemust belong to the client.- every
siteAssetIdassigned to a site visit must belong to that visit's site siteAssetIds: []clears assigned site assets on patch