Infracard

Error Handling

Understand API error responses and status codes

Error Format

All error responses follow a consistent format:

{
  "statusCode": 400,
  "message": "Validation failed",
  "error": "Bad Request"
}

HTTP Status Codes

CodeMeaning
200Success
201Created
400Bad Request — invalid parameters
401Unauthorized — missing or invalid API key
403Forbidden — insufficient permissions
404Not Found — resource doesn't exist
409Conflict — resource already exists or state conflict
422Unprocessable Entity — valid JSON but semantic error
429Too Many Requests — rate limit exceeded
500Internal Server Error

Handling Errors

Always check the HTTP status code before parsing the response body:

POST/cards

Example: issuing a card may return various error codes depending on the failure.

cardOfferingIdRequiredstring

ID of the card offering to issue

amountRequiredstring

Initial load amount (e.g. "100.00")

cardHolderIdstring

Card holder ID (if required by offering)

labelstring

Optional label for the card

const response = await fetch('https://api.infracard.co/cards', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.INFRACARD_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(cardData),
})

if (!response.ok) {
  const error = await response.json()
  console.error(`API error ${error.statusCode}: ${error.message}`)
  if (response.status === 429) {
    // Wait and retry
  }
  return
}

const card = await response.json()

Retry Strategy

For transient errors (429, 500, 502, 503, 504), implement exponential backoff:

async function fetchWithRetry(
  url: string,
  options: RequestInit,
  maxRetries = 3,
) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options)

    if (response.ok) return response

    const retryable = [429, 500, 502, 503, 504]
    if (!retryable.includes(response.status)) throw new Error(`HTTP ${response.status}`)

    if (attempt < maxRetries) {
      const delay = Math.pow(2, attempt) * 1000
      await new Promise((r) => setTimeout(r, delay))
    }
  }

  throw new Error('Max retries exceeded')
}

Validation Errors

400 responses from validation failures include details about which fields failed:

{
  "statusCode": 400,
  "message": ["amount must be a positive number", "currency must be a valid ISO 4217 code"],
  "error": "Bad Request"
}