Coupons
Siren's coupon records in the REST API: the coupon object and the routes to list, link, add, remove, merge, and split coupon codes.
WordPress plugin and Siren Cloud
Last updated: October 28, 2026
Siren keeps one record for each coupon code a store sends it or a shopper uses, with the collaborator it credits. Each plugin or store keeps its own copy of a code, and a coupon can hold several copies after a merge. Manage Coupon Codes explains the screen these routes serve.
Paths are relative to the REST base, /wp-json/siren/v1 on WordPress. The routes need staff access, such as an administrator or Platform Manager, and Siren’s admin screens call them.
records:coupons:read reads coupons, and one with records:coupons:manage also changes them, though no key reads store credit codes. A connected WordPress site’s connector token can call PUT /coupons/link for coupons at its own Property. A team member sees only the coupons and stores they can reach. A team member who can’t reach every store a coupon works at gets 403 when they change it.
The coupon object
| Field | Type | Description |
|---|---|---|
id | integer | The coupon |
code | string | The code as Siren shows it |
holderId | integer or null | The collaborator the code credits |
holder | object or null | That collaborator’s id, name, and status |
mergedIntoId | integer or null | The coupon this one was merged into |
identities | array | Each store copy: id, propertyId, integration, integrationLabel, code (the store’s spelling), bindingCode, platformId (the store’s own ID for it), and deleted (the store removed it) |
uses | object | count and lastUsedAt |
suggestions | array | Up to five open merge suggestions, each with id, couponId, code, signal, strength, and stores |
currency | string or null | null for the coupons GET /coupons lists. Siren manages store credit codes, and refuses to link, rename, remove, or merge them |
dateCreated, dateModified | datetime | When the record was created and last changed |
PUT /coupons/link, POST /coupons/merge, the split route, and the coupons inside a merge suggestion answer a shorter coupon, without holder, uses, or suggestions. Read it again with GET /coupons/:id for the full record.
List coupons
GET /coupons
| Parameter | Description |
|---|---|
search | Matches the code, a store’s spelling or ID, or a collaborator’s name |
integration | One integration, such as wc or edd |
propertyId | One store, 0 on WordPress |
linked | yes for linked codes, no for codes that credit no one |
holderId | Codes one collaborator holds |
includeRemoved | true to include coupons every store removed |
suggested | true for coupons with an open merge suggestion |
page, perPage | Paging. perPage is 1 to 100, default 25 |
Answers { "items": [...], "total", "page", "perPage" }, sorted by code. Unlike most list routes, this one returns an envelope and takes search, page, and perPage rather than the shared pagination parameters.
Get a coupon
GET /coupons/:id
Answers { "coupon": {...}, "mergedFrom": ... }. For a coupon that was merged, it answers with the coupon it joined, and mergedFrom names the ID you asked for. Otherwise mergedFrom is null. An unknown ID answers 404.
Link, unlink, or rename
PATCH /coupons/:id
Send holderId to link the coupon to a collaborator, or null to unlink it. Send code (1 to 255 characters) to change the name Siren shows, which doesn’t change the code shoppers type. Answers 200 with coupon, 400 for a bad holderId or code, or 404.
Add a code a store hasn’t sent
POST /coupons
Send code, integration, propertyId (0 on WordPress), and optionally holderId. Answers 201 with coupon. A missing code or integration, or a store that runs no such integration, answers 400.
Remove a coupon
DELETE /coupons/:id
Removes a coupon no store sent and no shopper used. Answers 200 with deleted, 404 for an unknown ID, or 400 for a coupon a store sent or a shopper used.
Link one store’s code
PUT /coupons/link
Send propertyId, integration, the code or the store’s platformId, and holderId (leave it out or send null to unlink). It links the whole coupon that copy belongs to. On Siren Cloud, when the coupon also works at a store you can’t reach, Siren first splits this store’s copy off and links only that copy. When Siren has no coupon with that code at the store, it records one and links it. Answers 200 with coupon. A missing integration, or neither code nor platformId, answers 400. A store that doesn’t run the integration answers 422. An unknown collaborator, or a platformId Siren doesn’t know at that store, answers 404.
Merge coupons
POST /coupons/merge
Send survivorId, the coupon to keep, and couponIds, the coupons to merge into it. A merge covers at most 20 coupons, the survivor included, so couponIds holds up to 19. When they credit different collaborators, also send holderId. Answers 200 with coupon and mergedIds. Without holderId for coupons that credit different collaborators, or with a holderId the coupons don’t credit, it answers 409 with conflicts, and the error’s code is merge_conflict. Each conflict has key (holderId for this question), options (the collaborator IDs you can send), and multiple. An unknown coupon answers 404. Other refusals, such as a coupon already merged or too many coupons, answer 400.
Split a store copy off
POST /coupons/:id/identities/:identityId/split
Makes that store copy its own coupon, not linked to anyone, with the uses that came through it. Answers 200 with coupon, the original coupon, and split, the new one. A coupon with one store copy answers 400, and an unknown coupon or copy answers 404.
Merge suggestions
GET /coupons/suggestions lists open suggestions, optionally for one propertyId, as { "data": [...] }, strongest first, at most 100. Each has id, signal, strength, and the two coupons. POST /coupons/suggestions/:id/dismiss takes that id, dismisses the suggestion for good, and answers id and state. An unknown suggestion answers 404.
List stores
GET /coupons/stores lists the stores you can reach and the coupon integrations each one runs, as { "data": [...] }. Each store is { id, name, integrations }, and each integration has slug and label. Use the store’s id as propertyId and an integration’s slug as integration in POST /coupons and PUT /coupons/link.