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(query?: ListQuery & { code?: string }): Promise<CursorPage<AdminCoupon>>

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 object 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

A CursorPage<AdminCoupon>:

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

const { data } = await admin.coupons.list({ code: 'WELCOME10' });
const coupon = data[0];

Iterate over every coupon

admin.coupons.all(query?: ListQuery & { code?: string }): AsyncGenerator<AdminCoupon, void, undefined>

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

An async generator of AdminCoupon, 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

for await (const coupon of admin.coupons.all({ updatedSince: lastSyncedAt })) {
    await erp.saveCoupon(coupon);
}

Get a coupon

admin.coupons.get(id: number): Promise<AdminCoupon>

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

Parameters

Parameter Type
id number 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(input: AdminCouponInput, options?: RequestOptions): Promise<AdminCoupon>

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

Parameters

Parameter Type
input object The coupon's fields, below.
options RequestOptions idempotencyKey, signal and headers (see retries).

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

const coupon = await 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(id: number, changes: Partial<AdminCouponInput>, options?: UpdateOptions): Promise<AdminCoupon>

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 number The coupon's id.
changes object The fields to change, below.
options UpdateOptions unmodifiedSince (the updatedAt you read; a newer coupon is refused with 409 edit_conflict) and idempotencyKey.

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

const coupon = await admin.coupons.get(5);
await admin.coupons.update(
    5,
    { value: 15 },
    { unmodifiedSince: coupon.updatedAt ?? undefined },
);

Delete a coupon

admin.coupons.delete(id: number): Promise<void>

Deletes a coupon. Scope: marketing:write.

Parameters

Parameter Type
id number 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.