Skip to main content

Error response format

All PCX services return errors in a consistent JSON envelope:
{
  "status": "error",
  "message": "Human-readable description of what went wrong"
}
Some services include an additional error field with a technical detail string (present mainly on 500 responses):
{
  "status": "error",
  "message": "An internal error occurred",
  "error": "NullPointerException at use_case line 42"
}

HTTP status codes

CodeMeaningWhen it occurs
200OKSuccessful GET, PUT, PATCH, DELETE
201CreatedSuccessful POST that creates a resource
204No ContentSuccessful DELETE with no response body
207Multi-StatusPartial success (e.g. target_type: both notifications where one fails)
400Bad RequestMissing required fields, invalid values, validation errors
401UnauthorizedMissing, malformed, or expired auth credentials
403ForbiddenValid credentials but insufficient role/permission
404Not FoundResource does not exist
409ConflictOperation conflicts with current state (e.g. duplicate invite, deletion conflict)
500Internal Server ErrorUnhandled exception in the service

Auth errors in detail

The pcx-authorizer returns 401 in these situations:
  • X-Api-Key header is absent or set to something other than a valid key or NONE
  • Authorization header is absent or set to something other than a valid Bearer JWT or NONE
  • Both headers are set to NONE (no credential provided)
  • The API key has been revoked or deleted
  • The Cognito JWT is expired or invalid
403 is returned by the service layer (not the authorizer) when the identity is valid but the caller’s role does not satisfy the endpoint’s roles constraint.

Success response format

Successful responses follow one of two shapes depending on the service: Standard envelope (most services):
{
  "status": "success",
  "message": "Operation description",
  "data": { ... }
}
Direct object (some older endpoints):
{
  "user_id": "...",
  "email": "...",
  ...
}

Pagination

PCX uses DynamoDB cursor-based pagination throughout. There is no offset-based (page=2) pagination.

How it works

  1. Make your first request — optionally pass limit to control page size
  2. If there are more results, the response includes a last_evaluated_key (or lastEvaluatedKey) field
  3. Pass that value back as a query parameter on your next request to get the next page
  4. When last_evaluated_key is null (or absent), you have reached the last page

Request

GET /v1/users/list?limit=20
GET /v1/users/list?limit=20&last_evaluated_key=<cursor_from_previous_response>

Response

{
  "status": "success",
  "data": [ ... ],
  "count": 20,
  "last_evaluated_key": "eyJwa...",
  "meta": {
    "last_evaluated_key": "eyJwa..."
  }
}
DynamoDB pagination cursors are opaque tokens. Do not attempt to parse, modify, or construct them manually — they are base64-encoded DynamoDB key objects and will cause a 400 if malformed.

Key naming inconsistency

Different services use slightly different field names for the pagination cursor — this is a known inconsistency:
ServiceRequest paramResponse field
OrganizationslastEvaluatedKeylastEvaluatedKey
Userslast_evaluated_keylast_evaluated_key
Virtual Accountslast_evaluated_keylast_evaluated_key
Beneficiarylast_evaluated_keylast_evaluated_key
Transactionlast_evaluated_keylast_evaluated_key

Decimal handling

Monetary values are stored as DynamoDB Decimal types and serialized to JSON as floats. Always treat amounts as number in your client — never as integers.

Idempotency

PCX does not currently implement idempotency keys. For critical operations (payment creation, KYB initiation), implement idempotency in your own layer by checking for the existence of a resource before creating it.