Errors
The B2B Receivables API uses standard HTTP status codes to indicate whether a request succeeded or failed.
For non-token endpoints, failed requests return a JSON error response in the Error Response Format below. This format is distinct from the Checkout API error format. In particular, B2B Receivables errors do not include a timestamp field.
OAuth 2.0 token endpoint errors follow the RFC 6749 format and are not returned in the format described on this page.
Error Response Format
{
"errors": [
{
"code": "urn:pyng:platform:billing:error:<category>:<name>",
"displayMessage": "Human-readable summary of the failure.",
"target": "fieldName"
}
],
"traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}
Fields
| Parameter Key | Parameter Data Type | Required | Notes |
|---|---|---|---|
| errors | array | Y | One or more error objects describing the failure. |
| traceId | string | Y | Unique identifier of the request. Include when contacting support. |
Error Object
| Parameter Key | Parameter Data Type | Required | Notes |
|---|---|---|---|
| code | string | Y | Stable error code in URN form: urn:pyng:platform:billing:error:<category>:<name> |
| displayMessage | string | Y | Human-readable summary suitable for logging and support diagnostics. |
| target | string | N | Identifies the request element that caused the error (body field, query parameter, path parameter). |
Common HTTP Status Codes
| Status | Condition |
|---|---|
| 400 | Request body or query parameters fail validation. |
| 401 | The access token is missing, malformed, or expired. |
| 403 | The token is valid but does not authorise the action — for example, the calling Organisation does not own the requested {siteId}, or the token does not include the required scope. |
| 404 | The named resource does not exist (for example, an unknown batchReference). |
| 409 | A resource with the same idempotency key already exists with a different body, or the target resource is in a conflicting state. |
| 410 | The version named in the Pyng-Api-Version header has been retired. See API Versions. |
| 429 | The partner has exceeded the request rate limit for this endpoint. Retry after the duration in the Retry-After response header. |
Rate Limits
The B2B Receivables API enforces per-Organisation rate limits on each endpoint. When a request exceeds the limit, the API responds 429 Too Many Requests with a Retry-After response header indicating the number of seconds to wait before retrying. Specific quotas are agreed during onboarding and may be reviewed via your Pyng account manager.
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json;charset=UTF-8
{
"errors": [
{
"code": "urn:pyng:platform:billing:error:rate-limit:exceeded",
"displayMessage": "The request rate limit for this endpoint has been exceeded. Retry after the duration in the Retry-After header.",
"target": "endpoint"
}
],
"traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}
Site Not Accessible to the Calling Organisation
When a request targets a {siteId} that does not belong to the calling Organisation, the API responds 403 Forbidden. The response is the same whether the Site does not exist or exists under a different Organisation — the API does not reveal the existence of Sites outside the caller's Organisation.
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
{
"errors": [
{
"code": "urn:pyng:platform:billing:error:site:not-accessible",
"displayMessage": "The requested Site is not accessible to your Organisation.",
"target": "siteId"
}
],
"traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}
Insufficient Scope
When the access token is valid but does not include the scope required for the endpoint, the API responds 403 Forbidden with a scope-specific code.
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
{
"errors": [
{
"code": "urn:pyng:platform:billing:error:auth:insufficient-scope",
"displayMessage": "The access token does not include the scope required for this endpoint.",
"target": "Authorization"
}
],
"traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}