Skip to content

Errors

When the GIB API can't fulfill a request, it returns an HTTP error status with a structured JSON body describing what went wrong. This page is the catalog of every error type you might see and the patterns for handling them.

For per-operation error coverage, see the API reference; every endpoint lists the errors it can return.

Error response shape

Every error shares this body shape:

{
  "error": "BusinessError: amount must be a positive integer in cents",
  "exception_class": "BusinessError"
}
Field Purpose
error "ExceptionClass: human-readable message" — the full error description
exception_class Machine-readable exception name — use this to branch on error type

HTTP status codes

The GIB API returns only the following HTTP status codes:

Status Meaning Exception class Example
200 Success — Resource returned or created
400 Bad request BusinessError Missing required field, business rule violation
402 Payment required PaymentRequired Insufficient funds for the requested transaction
403 Forbidden ForbiddenError or PermissionError Wrong IP, insufficient permissions, OFAC hit
404 Not found NotFoundError Unknown resource ID or deleted resource
409 Conflict ConflictError Duplicate detection: same transaction re-submitted
500 Server error Any other exception Internal server error

Error class catalog

BusinessError — HTTP 400

Returned when a request is structurally valid but violates a business rule or contains invalid data. Examples:

  • Missing or malformed required field
  • Invalid routing number (check digit fails)
  • Invalid amount (must be a positive integer in cents)
  • Invalid SEC code for the direction
  • Business rule violation (e.g. wrong account type for the rail)

PaymentRequired — HTTP 402

Returned when an outbound transaction would cause an overdraft and the program's overdraft-rejection policy is enabled.

  • Outbound transaction exceeds available balance on the source account or virtual account
  • All outbound transactions for that account in the same batch are rejected together

Unlike all other error responses (which roll back the request entirely), a 402 does persist data: the Batch and its Transactions are saved in failed state. You can inspect them via getTransactions and getBatches.

See Balances → Available Balance and Returns → Automated Returns for the overdraft behavior.

ForbiddenError / PermissionError — HTTP 403

Returned when the authenticated user is not permitted to perform the operation:

  • Source IP not on the API key's allowlist
  • User's role does not have permission for the endpoint
  • OFAC screening hit on a counterparty

Missing or invalid API key credentials return 403.

NotFoundError — HTTP 404

Returned when the referenced resource does not exist or has been deleted.

ConflictError — HTTP 409

Returned when a duplicate submission is detected. The API checks for duplicate transactions at creation time using a combination of fields (external_key if provided, otherwise core transaction fields). If a matching transaction already exists, the API returns 409 and includes a list of the duplicate transfer keys in the X-Duplicate-Transaction-Transfer-Keys response header.

To intentionally retry a request without creating a duplicate, provide an external_key in the request body. The same external_key for the same user returns 409 on re-submission; use this as a guard rather than re-generating the key on retry.

See Idempotency and Security → Duplicate Detection.

500 — Server error

Any unhandled exception returns 500. This is unexpected; the error field will contain details. Reference these in a support request to info@gibank.com.

Handling pattern

Retry strategy

Status Retry? How
500 — Contact info@gibank.com
409 No Human inspection — likely an accidental re-submission
400 No Fix the request and re-submit
402 No Insufficient funds — top up the account first
403 No Fix auth/permissions before retrying
404 No Verify the resource ID

Use external_key for safe retries

For any POST that creates a resource, include an external_key in the request body. If the request times out and you retry, the same external_key returns 409 with the original resource's transfer key in the X-Duplicate-Transaction-Transfer-Keys header, so retries on timeouts don't produce duplicates. See Idempotency.

  • Idempotency, safe retries via external_key
  • Security, authentication and duplicate detection
  • Webhooks, how state-change failures are communicated asynchronously
  • Transactions, state=failed Transactions reference the underlying error