Skip to main content
The YuvexPay API uses standard HTTP status codes and returns structured error responses.

Error response format

All errors follow a consistent structure:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request body",
    "details": {
      "amount": "Must be greater than 0.01"
    }
  }
}
FieldTypeDescription
error.codestringMachine-readable error code.
error.messagestringHuman-readable description.
error.detailsobjectAdditional context (optional).

HTTP status codes

StatusMeaning
200Success.
201Resource created.
400Bad request (validation error, missing fields).
401Unauthorized (invalid or expired token).
403Forbidden (insufficient permissions).
404Resource not found.
409Conflict (idempotency key mismatch).
429Rate limit exceeded.
500Internal server error.
503Service unavailable.

Error codes

Authentication errors

CodeStatusDescription
UNAUTHORIZED401Missing, invalid, or expired access token.
FORBIDDEN403Token is valid but lacks permission for this action.

Validation errors

CodeStatusDescription
VALIDATION_ERROR400Request body or query parameters failed validation. Check details for specifics.

Idempotency errors

CodeStatusDescription
IDEMPOTENCY_KEY_REQUIRED400POST endpoints that require an X-Idempotency-Key header.
IDEMPOTENCY_PAYLOAD_MISMATCH409The same idempotency key was used with a different request body.
IDEMPOTENCY_CONFLICT409The request is still being processed from a previous attempt.

Rate limiting errors

CodeStatusDescription
RATE_LIMIT_EXCEEDED429Too many requests. Check response headers for reset timing.

Resource errors

CodeStatusDescription
NOT_FOUND404The requested resource does not exist or does not belong to your account.

Server errors

CodeStatusDescription
INTERNAL_ERROR500Unexpected server error. Retry with exponential backoff.
SERVICE_UNAVAILABLE503The service is temporarily unavailable. Retry after a short delay.

Handling errors

async function createPayment(data) {
  const response = await fetch("https://api.yuvexpay.com/v1/payments", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
      "X-Idempotency-Key": generateIdempotencyKey(),
    },
    body: JSON.stringify(data),
  });

  if (!response.ok) {
    const { error } = await response.json();

    switch (response.status) {
      case 400:
        // Fix the request based on error.details
        console.error("Validation error:", error.details);
        break;
      case 401:
        // Token expired - generate a new one and retry
        await refreshToken();
        return createPayment(data);
      case 409:
        // Idempotency conflict - safe to return the original response
        console.warn("Duplicate request detected");
        break;
      case 429:
        // Rate limited - wait and retry
        const retryAfter = response.headers.get("X-RateLimit-Reset");
        await sleep(retryAfter * 1000);
        return createPayment(data);
      default:
        throw new Error(`API error: ${error.message}`);
    }
  }

  return response.json();
}