Errors

JKAPay uses standard HTTP status codes and returns a structured JSON body for every error. Always inspect the body rather than relying on status alone.

Error envelope

JSON
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request",
    "details": {
      "fieldErrors": {
        "customer.msisdn": ["Required"]
      }
    }
  }
}

Error codes

StatusCodeMeaning
400VALIDATION_ERRORThe request body or query failed validation. Inspect error.details for field-level info.
401UNAUTHENTICATEDMissing, malformed, or revoked API key.
403FORBIDDENAuthenticated but not allowed — e.g. merchant is SUSPENDED, or insufficient role.
404NOT_FOUNDResource doesn't exist or doesn't belong to your merchant.
409CONFLICTResource state conflict — e.g. duplicate email at registration.
429RATE_LIMITEDToo many requests. Back off and retry with exponential delay.
502PROVIDER_ERRORA mobile network or bank returned an error or was unreachable. Safe to retry.
500INTERNALUnexpected server error. Report to support with the request ID if it persists.

Retry strategy

  • Safe to retry: 429, 502, 503, network timeouts.
  • Do NOT retry without an idempotency key: any POST that creates resources. Pass idempotencyKey on every write so retries are safe.
  • Do not retry: 400, 401, 403, 404, 409 — fix the request first.

For retries, use exponential backoff: start at 1s, double each attempt, cap at 30s, give up after 5 attempts.