Store Hugs Developers

Coupons

Discount codes shoppers type at checkout: a percentage or a fixed amount off, with limits on who, when and how often.

Reach them through $admin->coupons. Reading needs the marketing:read scope, changing them marketing:write.

List coupons

$admin->coupons->list(array $query = []): array

One page of the shop's coupons, newest first, or oldest change first with updatedSince. Read the next page with meta.nextCursor as cursor. Scope: marketing:read.

Parameters

Parameter Type
$query array The query fields below, by name.

Query fields

ParameterTypeDescription
codestringAn exact code (case-insensitive). At most 255 characters.
limitintegerAt least 1. At most 100. Default 50.
cursorstringmeta.nextCursor (or the cursor in links.next) of the previous page. At most 1000 characters.
updatedSincestring (date-time)Records changed at or after this time (ISO 8601, any offset or Z), oldest change first, for incremental sync.

Returns

An array with data (a list of AdminCoupon), links and meta:

FieldTypeDescription
linksobject
links.firstnull
links.lastnull
links.prevstring (uri) or null
links.nextstring (uri) or null
metaobject
meta.pathstring (uri)
meta.perPageinteger
meta.nextCursorstring or null
meta.prevCursorstring or null
dataarray of AdminCoupon
data[].idinteger
data[].codestring
data[].typestringOne of percentage, fixed.
data[].valuenumber
data[].minOrderValuenumber or null
data[].maxDiscountAmountnumber or null
data[].usageLimitinteger or null
data[].usageLimitPerCustomerinteger or null
data[].usedCountinteger or null
data[].autoApplyboolean
data[].firstOrderOnlyboolean
data[].combinableWithOffersboolean
data[].startsAtstring (date-time) or null
data[].endsAtstring (date-time) or null
data[].statusboolean
data[].createdAtstring (date-time) or null
data[].updatedAtstring (date-time) or null

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.

Example

$page = $admin->coupons->list(['code' => 'WELCOME10']);
$coupon = $page['data'][0] ?? null;

Iterate over every coupon

$admin->coupons->all(array $query = []): Generator

Every coupon matching the query, one at a time, fetching the next page as you read. It takes the same query as list, without cursor. Scope: marketing:read.

Returns

A generator of AdminCoupon arrays, each:

FieldTypeDescription
[].idinteger
[].codestring
[].typestringOne of percentage, fixed.
[].valuenumber
[].minOrderValuenumber or null
[].maxDiscountAmountnumber or null
[].usageLimitinteger or null
[].usageLimitPerCustomerinteger or null
[].usedCountinteger or null
[].autoApplyboolean
[].firstOrderOnlyboolean
[].combinableWithOffersboolean
[].startsAtstring (date-time) or null
[].endsAtstring (date-time) or null
[].statusboolean
[].createdAtstring (date-time) or null
[].updatedAtstring (date-time) or null

Example

foreach ($admin->coupons->all(['updatedSince' => $lastSyncedAt]) as $coupon) {
    $erp->saveCoupon($coupon);
}

Get a coupon

$admin->coupons->get(int $id): array

One coupon by its id. Scope: marketing:read.

Parameters

Parameter Type
$id int The coupon's id.

Returns

An AdminCoupon:

FieldTypeDescription
idinteger
codestring
typestringOne of percentage, fixed.
valuenumber
minOrderValuenumber or null
maxDiscountAmountnumber or null
usageLimitinteger or null
usageLimitPerCustomerinteger or null
usedCountinteger or null
autoApplyboolean
firstOrderOnlyboolean
combinableWithOffersboolean
startsAtstring (date-time) or null
endsAtstring (date-time) or null
statusboolean
createdAtstring (date-time) or null
updatedAtstring (date-time) or null

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
404not_found: the shop has no such record.
429Rate limited.

Create a coupon

$admin->coupons->create(array $input, string|false|null $idempotencyKey = null): array

A new coupon. The code is stored in upper case and must be unique in the shop. Scope: marketing:write.

Parameters

Parameter Type
$input array The coupon's fields, below.
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none. One is made for you when null.

Request fields

FieldTypeDescription
code requiredstringUnique in the shop; stored in upper case. At most 50 characters.
type requiredstringOne of percentage, fixed.
value requirednumberAt most 100 for a percentage. At least 0.
minOrderValuenumber or nullAt least 0.
maxDiscountAmountnumber or nullAt least 0.
usageLimitinteger or nullAt least 1.
usageLimitPerCustomerinteger or nullAt least 1.
autoApplyboolean or null
firstOrderOnlyboolean or null
combinableWithOffersboolean or null
startsAtstring (date-time) or null
endsAtstring (date-time) or null
taxonomyFiltersobject (map) or nullLimits the coupon to term ids, by taxonomy type id. Not returned in responses.
taxonomyLabelsobject (map) or nullNot returned in responses.
statusboolean or null

Returns

The new AdminCoupon:

FieldTypeDescription
idinteger
codestring
typestringOne of percentage, fixed.
valuenumber
minOrderValuenumber or null
maxDiscountAmountnumber or null
usageLimitinteger or null
usageLimitPerCustomerinteger or null
usedCountinteger or null
autoApplyboolean
firstOrderOnlyboolean
combinableWithOffersboolean
startsAtstring (date-time) or null
endsAtstring (date-time) or null
statusboolean
createdAtstring (date-time) or null
updatedAtstring (date-time) or null

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
409idempotency_in_progress: a request with this Idempotency-Key is still running. Retry with the same key after Retry-After seconds; the first answer is then replayed.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.

Example

$coupon = $admin->coupons->create([
    'code' => 'WELCOME10',
    'type' => 'percentage',
    'value' => 10,
    'firstOrderOnly' => true,
    'usageLimitPerCustomer' => 1,
    'endsAt' => '2026-12-31T23:59:59Z',
]);

Update a coupon

$admin->coupons->update(
    int $id,
    array $changes,
    DateTimeInterface|string|null $unmodifiedSince = null,
    string|false|null $idempotencyKey = null,
): array

Changes only the fields sent; the coupon must still pass the full rules. Setting status to false switches it off. Scope: marketing:write.

Parameters

Parameter Type
$id int The coupon's id.
$changes array The fields to change, below.
$unmodifiedSince DateTimeInterface|string|null The coupon's updatedAt as you read it. If it changed since, the change is refused with 409 edit_conflict.
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none.

Request fields

FieldTypeDescription
codestringUnique in the shop; stored in upper case. At most 50 characters.
typestringOne of percentage, fixed.
valuenumberAt most 100 for a percentage. At least 0.
minOrderValuenumber or nullAt least 0.
maxDiscountAmountnumber or nullAt least 0.
usageLimitinteger or nullAt least 1.
usageLimitPerCustomerinteger or nullAt least 1.
autoApplyboolean or null
firstOrderOnlyboolean or null
combinableWithOffersboolean or null
startsAtstring (date-time) or null
endsAtstring (date-time) or null
taxonomyFiltersobject (map) or nullLimits the coupon to term ids, by taxonomy type id. Not returned in responses.
taxonomyLabelsobject (map) or nullNot returned in responses.
statusboolean or null
updatedAtstring (date-time) or nullThe record's updatedAt as you read it; a newer record gets 409 edit_conflict.

Returns

The changed AdminCoupon:

FieldTypeDescription
idinteger
codestring
typestringOne of percentage, fixed.
valuenumber
minOrderValuenumber or null
maxDiscountAmountnumber or null
usageLimitinteger or null
usageLimitPerCustomerinteger or null
usedCountinteger or null
autoApplyboolean
firstOrderOnlyboolean
combinableWithOffersboolean
startsAtstring (date-time) or null
endsAtstring (date-time) or null
statusboolean
createdAtstring (date-time) or null
updatedAtstring (date-time) or null

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
404not_found: the shop has no such record.
409edit_conflict (the record changed after If-Unmodified-Since or updatedAt), or idempotency_in_progress.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.

Example

$coupon = $admin->coupons->get(5);
$admin->coupons->update(5, ['value' => 15], unmodifiedSince: $coupon['updatedAt']);

Delete a coupon

$admin->coupons->delete(int $id): void

Deletes a coupon. Scope: marketing:write.

Parameters

Parameter Type
$id int The coupon's id.

Returns

Nothing.

Errors

StatusWhen
401invalid_api_key: no active Admin key in Authorization: Bearer.
403admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope.
404not_found: the shop has no such record.
409idempotency_in_progress: a request with this Idempotency-Key is still running. Retry with the same key after Retry-After seconds; the first answer is then replayed.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.