Spree Commerce Gift Cards API
Gift cards and gift card batches
Gift cards and gift card batches
openapi: 3.0.3
info:
title: Admin Account / Address Gift Cards API
contact:
name: Spree Commerce
url: https://spreecommerce.org
email: hello@spreecommerce.org
description: "Spree Admin API v3 - Administrative API for managing products, orders, and store settings.\n\n## Authentication\n\nThe Admin API requires a secret API key passed in the `x-spree-api-key` header.\nSecret API keys can be generated in the Spree admin dashboard.\n\n## Response Format\n\nAll responses are JSON. List endpoints return paginated responses with `data` and `meta` keys.\nSingle resource endpoints return a flat JSON object.\n\n## Resource IDs\n\nEvery resource is identified by an opaque string ID (e.g. `prod_86Rf07xd4z`,\n`variant_k5nR8xLq`, `or_UkLWZg9DAJ`). Use these IDs everywhere — URL paths,\nrequest bodies, and Ransack filters all accept them directly.\n\n## Error Handling\n\nErrors return a consistent format:\n```json\n{\n \"error\": {\n \"code\": \"validation_error\",\n \"message\": \"Validation failed\",\n \"details\": { \"name\": [\"can't be blank\"] }\n }\n}\n```\n"
version: v3
servers:
- url: http://{defaultHost}
variables:
defaultHost:
default: localhost:3000
tags:
- name: Gift Cards
description: Gift cards and gift card batches
paths:
/api/v3/admin/gift_card_batches:
get:
summary: List gift card batches
tags:
- Gift Cards
security:
- api_key: []
bearer_auth: []
description: 'Returns the gift card batches issued by the current store. Each batch
groups the cards generated together for a campaign or bulk-issuance
— the cards themselves live under `/admin/gift_cards` and reference
the batch via `gift_card_batch_id`.
**Required scope:** `read_gift_cards` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst { data: batches } = await client.giftCardBatches.list({ page: 1, limit: 25 })"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
description: Bearer token for admin authentication
schema:
type: string
- name: page
in: query
required: false
description: Page number
schema:
type: integer
- name: limit
in: query
required: false
description: Records per page
schema:
type: integer
- name: q[prefix_cont]
in: query
required: false
description: Filter by prefix (contains)
schema:
type: string
- name: sort
in: query
required: false
description: Sort by field. Prefix with `-` for descending.
schema:
type: string
responses:
'200':
description: gift card batches found
content:
application/json:
example:
data:
- id: gcb_UkLWZg9DAJ
codes_count: 2
currency: USD
prefix: WELCOME
created_at: '2026-06-12T17:24:14.398Z'
updated_at: '2026-06-12T17:24:14.398Z'
amount: '50.0'
expires_at: null
created_by_id: null
meta:
page: 1
limit: 25
count: 1
pages: 1
from: 1
to: 1
in: 1
previous: null
next: null
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/GiftCardBatch'
meta:
$ref: '#/components/schemas/PaginationMeta'
required:
- data
- meta
post:
summary: Create a gift card batch
tags:
- Gift Cards
security:
- api_key: []
bearer_auth: []
description: 'Issues a batch of gift cards in a single call. The server generates
`codes_count` cards inline for small batches (configurable via
`Spree.config.gift_card_batch_web_limit`, default 500) or enqueues
a background job for larger ones. Each card''s code is the batch
`prefix` followed by random hex.
**Required scope:** `write_gift_cards` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst batch = await client.giftCardBatches.create({\n prefix: 'WELCOME',\n amount: '25.00',\n currency: 'USD',\n codes_count: 100,\n expires_at: '2030-12-31',\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
responses:
'201':
description: gift card batch created
content:
application/json:
example:
id: gcb_gbHJdmfrXB
codes_count: 5
currency: USD
prefix: NEWCAMP
created_at: '2026-06-12T17:24:14.972Z'
updated_at: '2026-06-12T17:24:14.972Z'
amount: '25.0'
expires_at: '2030-12-31'
created_by_id: admin_UkLWZg9DAJ
schema:
$ref: '#/components/schemas/GiftCardBatch'
'422':
description: validation error
content:
application/json:
example:
error:
code: validation_error
message: Prefix can't be blank
details:
prefix:
- can't be blank
schema:
$ref: '#/components/schemas/ErrorResponse'
requestBody:
content:
application/json:
schema:
type: object
required:
- prefix
- amount
- codes_count
properties:
prefix:
type: string
example: WELCOME
description: Lowercased and prepended to every generated code.
amount:
type: string
example: '25.00'
description: Decimal amount per card, greater than zero.
currency:
type: string
example: USD
description: ISO 4217 currency code. Defaults to the store currency.
codes_count:
type: integer
example: 100
description: Number of cards to generate. Capped at `gift_card_batch_limit`.
expires_at:
type: string
example: '2030-12-31'
nullable: true
/api/v3/admin/gift_card_batches/{id}:
parameters:
- name: id
in: path
required: true
description: Gift card batch prefixed ID
schema:
type: string
get:
summary: Get a gift card batch
tags:
- Gift Cards
security:
- api_key: []
bearer_auth: []
description: 'Returns a single batch.
**Required scope:** `read_gift_cards` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst batch = await client.giftCardBatches.get('gcb_K3zr8x')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
responses:
'200':
description: gift card batch found
content:
application/json:
example:
id: gcb_UkLWZg9DAJ
codes_count: 2
currency: USD
prefix: WELCOME
created_at: '2026-06-12T17:24:15.269Z'
updated_at: '2026-06-12T17:24:15.269Z'
amount: '50.0'
expires_at: null
created_by_id: null
schema:
$ref: '#/components/schemas/GiftCardBatch'
'404':
description: gift card batch not found
content:
application/json:
example:
error:
code: record_not_found
message: Gift card batch not found
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/v3/admin/gift_cards:
get:
summary: List gift cards
tags:
- Gift Cards
security:
- api_key: []
bearer_auth: []
description: 'Returns the gift cards issued by the current store. Filter by
`q[code_cont]` for code search, `q[user_id_eq]` for cards issued
to a specific customer, or `q[state_eq]` for status filtering.
**Required scope:** `read_gift_cards` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst { data: giftCards } = await client.giftCards.list({\n page: 1,\n limit: 25,\n expand: ['customer', 'created_by'],\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
description: Bearer token for admin authentication
schema:
type: string
- name: page
in: query
required: false
description: Page number
schema:
type: integer
- name: limit
in: query
required: false
description: Number of records per page
schema:
type: integer
- name: q[code_cont]
in: query
required: false
description: Filter by gift card code (contains)
schema:
type: string
- name: q[state_eq]
in: query
required: false
description: Filter by status (active, redeemed, partially_redeemed, canceled)
schema:
type: string
- name: sort
in: query
required: false
description: Sort by field. Prefix with `-` for descending (e.g., `-created_at`).
schema:
type: string
- name: fields
in: query
required: false
description: Comma-separated list of fields to include. id is always included.
schema:
type: string
responses:
'200':
description: gift cards found
content:
application/json:
example:
data:
- id: gc_UkLWZg9DAJ
code: CD084BB41D246D4F
status: active
currency: USD
amount: '50.0'
amount_used: '0.0'
amount_authorized: '0.0'
amount_remaining: '50.0'
display_amount: $50.00
display_amount_used: $0.00
display_amount_remaining: $50.00
expires_at: null
redeemed_at: null
expired: false
active: true
created_at: '2026-06-12T17:24:15.844Z'
updated_at: '2026-06-12T17:24:15.844Z'
customer_id: null
created_by_id: null
- id: gc_gbHJdmfrXB
code: 1942CCC0C95DF267
status: active
currency: USD
amount: '25.0'
amount_used: '0.0'
amount_authorized: '0.0'
amount_remaining: '25.0'
display_amount: $25.00
display_amount_used: $0.00
display_amount_remaining: $25.00
expires_at: null
redeemed_at: null
expired: false
active: true
created_at: '2026-06-12T17:24:15.846Z'
updated_at: '2026-06-12T17:24:15.846Z'
customer_id: null
created_by_id: null
meta:
page: 1
limit: 25
count: 2
pages: 1
from: 1
to: 2
in: 2
previous: null
next: null
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/GiftCard'
meta:
$ref: '#/components/schemas/PaginationMeta'
required:
- data
- meta
'401':
description: unauthorized
content:
application/json:
example:
error:
code: authentication_required
message: Authentication required
schema:
$ref: '#/components/schemas/ErrorResponse'
post:
summary: Create a gift card
tags:
- Gift Cards
security:
- api_key: []
bearer_auth: []
description: 'Issues a gift card scoped to the current store. The code is
auto-generated when omitted. `currency` defaults to the store''s
configured currency. Pass `user_id` (prefixed ID) to attach the
card to a specific customer.
**Required scope:** `write_gift_cards` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst giftCard = await client.giftCards.create({\n amount: '25.00',\n currency: 'USD',\n expires_at: '2030-12-31',\n user_id: 'cus_UkLWZg9DAJ',\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
responses:
'201':
description: gift card created
content:
application/json:
example:
id: gc_EfhxLZ9ck8
code: 4F5E5C544DDFA6B5
status: active
currency: USD
amount: '25.0'
amount_used: '0.0'
amount_authorized: '0.0'
amount_remaining: '25.0'
display_amount: $25.00
display_amount_used: $0.00
display_amount_remaining: $25.00
expires_at: '2030-12-31'
redeemed_at: null
expired: false
active: true
created_at: '2026-06-12T17:24:16.432Z'
updated_at: '2026-06-12T17:24:16.432Z'
customer_id: null
created_by_id: admin_UkLWZg9DAJ
schema:
$ref: '#/components/schemas/GiftCard'
'422':
description: validation error
content:
application/json:
example:
error:
code: validation_error
message: Amount must be greater than 0
details:
amount:
- must be greater than 0
schema:
$ref: '#/components/schemas/ErrorResponse'
requestBody:
content:
application/json:
schema:
type: object
required:
- amount
properties:
amount:
type: string
example: '25.00'
description: Decimal amount, greater than zero.
currency:
type: string
example: USD
description: ISO 4217 currency code. Defaults to the store currency.
code:
type: string
example: WELCOME50
description: Optional caller-supplied code. Auto-generated when omitted.
expires_at:
type: string
example: '2030-12-31'
description: ISO 8601 date.
nullable: true
user_id:
type: string
example: cus_UkLWZg9DAJ
description: Optional customer prefixed ID.
nullable: true
/api/v3/admin/gift_cards/{id}:
parameters:
- name: id
in: path
required: true
description: Gift card prefixed ID
schema:
type: string
get:
summary: Get a gift card
tags:
- Gift Cards
security:
- api_key: []
bearer_auth: []
description: 'Returns a single gift card.
**Required scope:** `read_gift_cards` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst giftCard = await client.giftCards.get('gc_K3zr8x', {\n expand: ['customer', 'created_by', 'orders'],\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: fields
in: query
required: false
description: Comma-separated list of fields to include. id is always included.
schema:
type: string
responses:
'200':
description: gift card found
content:
application/json:
example:
id: gc_UkLWZg9DAJ
code: CF2E19F27E7DA895
status: active
currency: USD
amount: '50.0'
amount_used: '0.0'
amount_authorized: '0.0'
amount_remaining: '50.0'
display_amount: $50.00
display_amount_used: $0.00
display_amount_remaining: $50.00
expires_at: null
redeemed_at: null
expired: false
active: true
created_at: '2026-06-12T17:24:16.734Z'
updated_at: '2026-06-12T17:24:16.734Z'
customer_id: null
created_by_id: null
schema:
$ref: '#/components/schemas/GiftCard'
'404':
description: gift card not found
content:
application/json:
example:
error:
code: record_not_found
message: Gift card not found
schema:
$ref: '#/components/schemas/ErrorResponse'
patch:
summary: Update a gift card
tags:
- Gift Cards
security:
- api_key: []
bearer_auth: []
description: 'Updates an active gift card''s editable attributes. Redeemed or
partially-redeemed cards cannot be edited.
**Required scope:** `write_gift_cards` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst giftCard = await client.giftCards.update('gc_K3zr8x', {\n amount: '75.00',\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
responses:
'200':
description: gift card updated
content:
application/json:
example:
id: gc_UkLWZg9DAJ
code: 38197D3D485C7386
status: active
currency: USD
amount: '75.0'
amount_used: '0.0'
amount_authorized: '0.0'
amount_remaining: '75.0'
display_amount: $75.00
display_amount_used: $0.00
display_amount_remaining: $75.00
expires_at: null
redeemed_at: null
expired: false
active: true
created_at: '2026-06-12T17:24:17.340Z'
updated_at: '2026-06-12T17:24:17.626Z'
customer_id: null
created_by_id: null
schema:
$ref: '#/components/schemas/GiftCard'
requestBody:
content:
application/json:
schema:
type: object
properties:
amount:
type: string
example: '75.00'
expires_at:
type: string
example: '2031-12-31'
nullable: true
user_id:
type: string
example: cus_UkLWZg9DAJ
nullable: true
delete:
summary: Delete a gift card
tags:
- Gift Cards
security:
- api_key: []
bearer_auth: []
description: 'Deletes an unused gift card. Cards that have been redeemed or
partially redeemed cannot be deleted and return 422.
**Required scope:** `write_gift_cards` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nawait client.giftCards.delete('gc_K3zr8x')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
responses:
'204':
description: gift card deleted
'422':
description: redeemed gift card cannot be deleted
content:
application/json:
example:
error:
code: validation_error
message: Gift card cannot be deleted
components:
schemas:
LineItem:
type: object
properties:
id:
type: string
variant_id:
type: string
quantity:
type: number
currency:
type: string
name:
type: string
slug:
type: string
options_text:
type: string
price:
type: string
display_price:
type: string
total:
type: string
display_total:
type: string
adjustment_total:
type: string
display_adjustment_total:
type: string
additional_tax_total:
type: string
display_additional_tax_total:
type: string
included_tax_total:
type: string
display_included_tax_total:
type: string
discount_total:
type: string
display_discount_total:
type: string
pre_tax_amount:
type: string
display_pre_tax_amount:
type: string
discounted_amount:
type: string
display_discounted_amount:
type: string
display_compare_at_amount:
type: string
nullable: true
compare_at_amount:
type: string
nullable: true
thumbnail_url:
type: string
nullable: true
option_values:
type: array
items:
$ref: '#/components/schemas/OptionValue'
digital_links:
type: array
items:
$ref: '#/components/schemas/DigitalLink'
metadata:
type: object
created_at:
type: string
updated_at:
type: string
cost_price:
type: string
nullable: true
tax_category_id:
type: string
nullable: true
variant:
$ref: '#/components/schemas/Variant'
tax_category:
$ref: '#/components/schemas/TaxCategory'
adjustments:
type: array
items:
$ref: '#/components/schemas/Adjustment'
required:
- id
- variant_id
- quantity
- currency
- name
- slug
- options_text
- price
- display_price
- total
- display_total
- adjustment_total
- display_adjustment_total
- additional_tax_total
- display_additional_tax_total
- included_tax_total
- display_included_tax_total
- discount_total
- display_discount_total
- pre_tax_amount
- display_pre_tax_amount
- discounted_amount
- display_discounted_amount
- display_compare_at_amount
- compare_at_amount
- thumbnail_url
- option_values
- digital_links
- metadata
- created_at
- updated_at
- cost_price
- tax_category_id
x-typelizer: true
ReturnAuthorization:
type: object
properties:
id:
type: string
number:
type: string
status:
type: string
order_id:
type: string
nullable: true
stock_location_id:
type: string
nullable: true
return_authorization_reason_id:
type: string
nullable: true
created_at:
type: string
updated_at:
type: string
order:
$ref: '#/components/schemas/Order'
stock_location:
$ref: '#/components/schemas/StockLocation'
required:
- id
- number
- status
- order_id
- stock_location_id
- return_authorization_reason_id
- created_at
- updated_at
x-typelizer: true
StockItem:
type: object
properties:
id:
type: string
count_on_hand:
type: number
backorderable:
type: boolean
stock_location_id:
type: string
nullable: true
variant_id:
type: string
nullable: true
metadata:
type: object
created_at:
type: string
updated_at:
type: string
allocated_count:
type: number
available_count:
type: number
stock_location:
$ref: '#/components/schemas/StockLocation'
variant:
$ref: '#/components/schemas/Variant'
required:
- id
- count_on_hand
- backorderable
- stock_location_id
- variant_id
- metadata
- created_at
- updated_at
- allocated_count
- available_count
x-typelizer: true
PaymentSource:
type: object
properties:
id:
type: string
gateway_payment_profile_id:
type: string
nullable: true
metadata:
type: object
created_at:
type: string
updated_at:
type: string
required:
- id
- gateway_payment_profile_id
- metadata
- created_at
- updated_at
x-typelizer: true
AdminUser:
type: object
properties:
id:
type: string
email:
type: string
first_name:
type: string
nullable: true
last_name:
type: string
nullable: true
full_name:
type: string
nullable: true
created_at:
type: string
updated_at:
type: string
roles:
type: array
items:
$ref: '#/components/schemas/AdminUserRoleAssignment'
required:
- id
- email
- first_name
- last_name
- full_name
- created_at
- updated_at
- roles
x-typelizer: true
Adjustment:
type: object
properties:
id:
type: string
label:
type: string
display_amount:
type: string
included:
type: boolean
created_at:
type: string
updated_at:
type: string
amount:
type: string
order_id:
type: string
nullable: true
required:
- id
- label
- display_amount
- included
- created_at
- updated_at
- amount
- order_id
x-typelizer: true
Address:
type: object
properties:
id:
type: string
first_name:
type: string
nullable: true
last_name:
type: string
nullable: true
full_name:
type: string
address1:
type: string
nullable: true
address2:
type: string
nullable: true
postal_code:
type: string
nullable: true
city:
type: string
nullable: true
phone:
type: string
nullable: true
company:
type: string
nullable: true
country_name:
type: string
country_iso:
type: string
state_text:
type: string
nullable: true
state_abbr:
type: string
nullable: true
quick_checkout:
type: boolean
is_default_billing:
type: boolean
is_default_shipping:
type: boolean
state_name:
type: string
nullable: true
label:
type: string
nullable: true
metadata:
type: object
created_at:
type: string
updated_at:
type: string
customer_id:
type: string
nullable: true
required:
- id
- first_name
- last_name
- full_name
- address1
- address2
- postal_code
- city
- phone
- company
- country_name
- country_iso
- state_text
- state_abbr
- quick_checkout
- is_default_billing
- is_default_shipping
- state_name
- label
- metadata
- created_at
- updated_at
- customer_id
x-typelizer: true
DeliveryRate:
type: object
properties:
id:
type: string
delivery_method_id:
type: string
name:
type: string
selected:
type: boolean
cost:
type: string
total:
type: string
additional_tax_total:
type: string
included_tax_total:
type: string
tax_total:
type: string
display_cost:
type: string
display_total:
type: string
display_additional_
# --- truncated at 32 KB (73 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/spree/refs/heads/main/openapi/spree-gift-cards-api-openapi.yml