Responses, errors & limits
Response format
Every response is JSON with the same envelope. The result is in data.
{
"success": true,
"message": "Success",
"data": { … },
"timestamp": "2026-10-12T09:30:00Z"
}Pagination
List endpoints are paginated. Most take page (starting at 1) and pageSize (up to 100) and return:
"data": {
"items": [ … ],
"page": 1,
"pageSize": 20,
"totalElements": 128,
"totalPages": 7
}A few endpoints use page (from 0), size and sort (for example createdAt,desc) instead — the API reference lists the exact query parameters for each endpoint.
Errors
Errors use the same envelope with success: false and a readable message. Authentication errors also carry a machine-readable data.code:
{
"success": false,
"message": "The access token does not have the scope Scalar360.invoices.CREATE.",
"data": { "code": "INVALID_SCOPE" }
}| HTTP | Code | Meaning |
|---|---|---|
| 200 | Success. | |
| 400 | The request is invalid — for example a missing required field. message explains what to fix. | |
| 401 | INVALID_OAUTHTOKEN | The access token is missing, invalid or expired. Refresh it. |
| 401 | INVALID_SCOPE | The token has no scope for this module and operation. |
| 402 | SUBSCRIPTION_REQUIRED | The organisation's subscription has ended. |
| 403 | FORBIDDEN_RESOURCE | This area is never available through the API (sign-in and account security, billing, switching or creating organisations, invitations, AI and developer settings, employee portal). |
| 403 | The user's role, module permissions or plan don't allow this action in this organisation. | |
| 403 | ORGANIZATION_ACCESS_DENIED | The user isn't an active member of the requested organization_id (or of the organisation the token was authorised in, when none is given). |
| 400 | INVALID_ORGANIZATION_ID | organization_id isn't a valid organisation id — use one from GET /api/v1/organizations. |
| 404 | The record doesn't exist or isn't in the organisation. | |
| 409 | The request conflicts with the record's current state. | |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests — wait for the time in Retry-After. |
| 5xx | A problem on our side. Retry with backoff; contact support if it persists. |
Rate limits
Each access token can make 100 requests per minute. Every response includes:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | Unix time when the window resets. |
Retry-After | On 429 only: seconds to wait. |
Good practice
- Refresh access tokens on 401
INVALID_OAUTHTOKENand retry once. - Back off on 429 and 5xx responses.
- Keep the Client Secret and refresh tokens on your server; never ship them in a browser or app.
- Request the narrowest scopes your integration needs.
