API docs

Gift certificates

Permission: gift_certificates (read / write).

Every balance change is a row in the certificate's ledger, and certificates are mirrored to the shop's BigCommerce store (when one is connected) exactly like certificates sold at the register.

List and look up

GET /v1/gift-certificates. Filters: code (exact code, dashes included; case and spaces ignored), status, purchaser_customer_id, updated_since, limit, cursor.

GET /v1/gift-certificates/{id} returns the certificate plus its last 50 transactions, newest first.

curl "https://app.ironregister.com/api/v1/gift-certificates?code=IR-7K2M-9QXA" -H "Authorization: Bearer $KEY"
{
  "object": "gift_certificate",
  "id": 58,
  "code": "IR-7K2M-9QXA",
  "status": "active",
  "source": "pos",
  "initial_cents": 10000,
  "balance_cents": 6450,
  "purchaser_customer_id": 1166,
  "recipient_name": "Sam Reyes",
  "recipient_email": "sam@example.com",
  "expires_on": null,
  "issued_at": "2026-08-30T20:11:00Z",
  "updated_at": "2026-09-21T18:40:00Z",
  "transactions": [
    { "object": "gift_certificate_transaction", "id": 311, "kind": "redeem", "amount_cents": -3550, "balance_after_cents": 6450, "note": "Redeemed via API (Webstore) · ref ORD-1042", "created_at": "2026-09-21T18:40:00Z" },
    { "object": "gift_certificate_transaction", "id": 290, "kind": "purchase", "amount_cents": 10000, "balance_after_cents": 10000, "note": null, "created_at": "2026-08-30T20:11:00Z" }
  ]
}
  • status is one of active, depleted (balance 0), disabled or expired. source is pos (including API-issued) or bigcommerce.
  • transactions[].kind is purchase, redeem, online_redeem, reload, adjustment, reversal or import. Amounts are signed: spending is negative.

Issue a certificate

POST /v1/gift-certificates (write). For a certificate sold on another channel, such as your webstore or a marketplace.

curl -X POST https://app.ironregister.com/api/v1/gift-certificates \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: web-gc-88812" \
  -d '{
    "amount_cents": 5000,
    "recipient_name": "Pat Lee",
    "recipient_email": "pat@example.com",
    "message": "Happy birthday!",
    "purchaser_name": "Jordan Reyes",
    "purchaser_email": "jordan@example.com",
    "expires_on": "2027-12-31",
    "reference": "WEB-88812"
  }'
Field Notes
amount_cents Required. $5.00–$2,000.00 (500–200000).
code Optional. 6–40 letters, digits or dashes. Omit it and a code is generated. A code in use is 409 GIFT_CERTIFICATE_CODE_TAKEN; a malformed one is 422 GIFT_CERTIFICATE_CODE_INVALID.
purchaser_customer_id Or purchaser_name / purchaser_email. An unknown customer id is 422 INVALID_REFERENCE.
recipient_name, recipient_email, message Optional.
expires_on Optional YYYY-MM-DD.
location_id Optional; must be a location the key can see.
reference Optional; your reference, recorded in the ledger note.

Returns 201 with the certificate. Send an Idempotency-Key so a retry can't issue two.

Redeem and reverse

POST /v1/gift-certificates/{id}/redeem and POST /v1/gift-certificates/{id}/reverse (write). Redeem spends part of the balance at your checkout; reverse gives a redemption back, for example when that order is refunded.

An Idempotency-Key header is required on both. Without one the call is 400 IDEMPOTENCY_KEY_REQUIRED, so a retried request can never move a balance twice. Use one key per payment attempt, such as your order or refund id.

curl -X POST https://app.ironregister.com/api/v1/gift-certificates/58/redeem \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: ORD-1042-gc" \
  -d '{ "amount_cents": 3550, "reference": "ORD-1042" }'
{
  "status": "ok",
  "data": {
    "object": "gift_certificate",
    "id": 58,
    "code": "IR-7K2M-9QXA",
    "status": "active",
    "balance_cents": 6450,
    "transactions": [ "…" ],
    "transaction": { "object": "gift_certificate_transaction", "id": 311, "kind": "redeem", "amount_cents": -3550, "balance_after_cents": 6450, "note": "Redeemed via API (Webstore) · ref ORD-1042", "created_at": "2026-09-21T18:40:00Z" }
  }
}
  • Body: amount_cents (required, 1–200000) and an optional reference.
  • Redeem needs an active certificate (422 GIFT_CERTIFICATE_INACTIVE otherwise, with details.status) and enough balance (422 GIFT_CERTIFICATE_INSUFFICIENT, with details.balance_cents). A certificate spent to zero becomes depleted.
  • Reverse puts value back, and reactivates a depleted certificate.
  • To look a certificate up by the code your customer typed, use GET /v1/gift-certificates?code=… and redeem by its id.

Reload and adjust

POST /v1/gift-certificates/{id}/reload and POST /v1/gift-certificates/{id}/adjust (write). An Idempotency-Key header is required on both, as on redeem and reverse.

  • Reload adds value, for example a top-up bought on your website. Body: amount_cents (required, 1–200000) and an optional reference. A disabled or expired certificate can't be reloaded (422 GIFT_CERTIFICATE_INACTIVE).
  • Adjust is a correction in either direction. Body: amount_cents (required, signed, -200000–200000, not 0; negative removes value) and reason (required, up to 200 characters). The balance can't go below zero (422 GIFT_CERTIFICATE_INSUFFICIENT, with details.balance_cents).
curl -X POST https://app.ironregister.com/api/v1/gift-certificates/58/reload \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: TOPUP-2291" \
  -d '{ "amount_cents": 2500, "reference": "TOPUP-2291" }'

curl -X POST https://app.ironregister.com/api/v1/gift-certificates/58/adjust \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: ADJ-58-0925" \
  -d '{ "amount_cents": -1000, "reason": "Price match correction" }'

Both return the certificate, like redeem, with the new ledger row in transaction (kind reload or adjustment).

Disable and enable

  • POST /v1/gift-certificates/{id}/disable with { "reason": "…" } (required). A disabled certificate can't be redeemed. Disabling one that's already disabled is a no-op.
  • POST /v1/gift-certificates/{id}/enable puts it back to active (or depleted at a zero balance). An expired certificate can't be re-enabled (422 GIFT_CERTIFICATE_INACTIVE).

Webhooks

gift_certificate.issued fires when a certificate is issued (at the register, online or through the API). gift_certificate.updated fires on every balance or status change: redeemed, reversed, reloaded, adjusted, disabled, enabled or expired. The payload is the certificate as GET /v1/gift-certificates/{id} returns it, without transactions.