Siren

Products

Siren's product records in the REST API: the product object and the routes to list, add, rename, merge, and split products and to set their owners.

WordPress plugin and Siren Cloud

Last updated: October 28, 2026

Siren keeps one record for each product your stores sell, with the collaborators who own it. A store’s copy of a product is a listing, and a merged product holds one listing for each store copy. Owners belong to the product, so they earn on every store that sells it. Assign Product Owners explains how owners earn.

Paths are relative to the REST base, /wp-json/siren/v1 on WordPress, and Authentication explains how to sign requests. The routes need staff access, an administrator or Platform Manager. propertyId names a store, and it’s 0 on WordPress. A route with a product ID in its path answers with the product it joined when that ID was merged. The merge routes refuse a merged ID.

On Siren Cloud, the dashboard calls these routes for Admins and Platform Managers, though only Admins see the Products screen, as Manage Products on Siren Cloud describes. An API key with records:products:read reads them, and one with records:products:manage also changes them. A connected WordPress site’s connector token can call GET /products/listing, which is how its “Product owners” boxes show owners. Setting owners, merging, previewing a merge, splitting, and dismissing a match need the Essentials, Plus, or Pro plan, and answer 403 with “Your plan does not include this feature.” on a plan without them. A team member sees only products sold at the Properties they can reach. They get 403 when they add a product to a store they can’t reach, or when a merge or split touches one.

The product object

FieldTypeDescription
idintegerThe product
namestringThe name Siren shows. Each store keeps its own name on its listing
mergedIntoIdinteger or nullThe product this one was merged into
listingsarrayEach store’s listing: id, propertyId, integration, platformId (the store’s own ID for it), name, sku, removed (the store removed it), and lastSeenAt
ownersarrayThe owners, each with id and name, up to 10
openSuggestionsintegerHow many merge suggestions wait for this product
dateCreateddatetimeWhen the record was created
mergedFromintegerOnly when you asked for a product that was merged: the ID you asked for. The answer is the product it joined

A WooCommerce variation has no listing of its own. Its sales count for the parent product.

List products

GET /products

ParameterDescription
searchMatches the product’s name, a store’s name for it, its SKU, or a store’s ID for it
propertyIdOne store. Leave it out for every store
integrationOne integration, such as wc or edd
ownerIdProducts one collaborator owns
sold1 for products a store sells now
hasMatches1 for products with an open merge suggestion
page, perPagePaging. perPage is 1 to 100, default 25

Answers { "products": [...], "total", "page", "perPage", "maxOwners", "capability" }. Merged products are left out. maxOwners is 10. capability serves the Products screen and can be null, so ignore it unless you build that screen.

Find the product for a store’s listing

GET /products/listing

Send integration and platformId, the store’s own ID for the product, plus propertyId (0 on WordPress). Answers { "product": {...} }, or { "product": null } when Siren hasn’t seen that listing. For WooCommerce, integration is wc and platformId is the product’s ID in WooCommerce, never a variation’s. When the answer is null, add the product with POST /products.

For example, to set the owners of WooCommerce product 123, look up its Siren product, then send the owners’ collaborator IDs to that product:

GET /wp-json/siren/v1/products/listing?integration=wc&platformId=123&propertyId=0

PUT /wp-json/siren/v1/products/45/owners
{"owners": [12, 15]}

The first call answers {"product": {"id": 45, ...}}, and 45 is the ID the second call uses. If it answers {"product": null}, add the product first with POST /products and a body such as {"propertyId": 0, "integration": "wc", "platformId": "123", "name": "Watercolor course"}, and use the id it answers. Send the bodies as JSON. Collaborators lists your collaborators and their IDs.

Get a product

GET /products/:id

Answers { "product": {...} }. For a product that was merged, it answers with the product it joined, and mergedFrom names the ID you asked for. An unknown ID answers 404.

Add a product a store hasn’t sent

POST /products

Send propertyId (0 on WordPress), integration, platformId, and name. Answers 201 with product. A missing or bad field answers 400, and a store that doesn’t run that integration answers 422.

Rename a product

PATCH /products/:id

Send name. It changes the name Siren shows, not the stores’ names. Answers 200 with product, 400 for a bad name, or 404.

Set the owners

PUT /products/:id/owners

Send owners, a list of collaborator IDs, such as {"owners": [12, 15]}. The list replaces the product’s owners, and an empty list clears them. Answers 200 with product. Repeated IDs count once. A missing owners, or a value that isn’t a list of positive IDs, answers 400. More than 10 owners, or an ID that isn’t a collaborator in your organization, answers 422. An unknown product answers 404. The change applies to sales from then on.

Merge suggestions

GET /products/:id/matches lists the products Siren thinks are the same one, as { "matches": [...] }. Each has id, signal (same_sku or same_name), strength (20 for the same SKU, 10 for the same name), and the other product. Siren suggests matches only between products on different stores.

POST /products/:id/matches/:matchId/dismiss dismisses that suggestion for good and answers the remaining matches.

Merge products

POST /products/merge/preview takes survivorId, the product to keep, and productIds, the products to merge into it. Answers conflicts, the questions a merge would ask, and names, the names the kept product can take.

POST /products/merge takes survivorId, productIds, and optionally name. A merge covers at most 20 products, the survivor included. When the products have different owners, also send owners: combine gives the merged product everyone who owns any of them, as long as that’s 10 or fewer, and survivor keeps only the kept product’s owners. Every listing and sale moves to the survivor. Answers 200 with product.

Without owners when the owners differ, it answers 409. It does the same for an owners answer the question doesn’t offer, such as combine when the owners would come to more than 10, where the question offers only survivor. The error’s context.type is merge_conflict, and context.conflicts lists each question with key, options, and multiple.

A non-text owners or name answers 400. Missing or unknown products, or products you can’t reach, answer 404. Siren refuses some merges with 422: merging a product into itself, no product to merge, more than 20 products, or a product that was already merged.

Split a listing off

POST /products/:id/listings/:listingId/split

Makes that listing a product of its own, with a copy of the current owners and the sales made through it. Answers 201 with the new product. Splitting a product’s only listing answers 422, and an unknown product or listing answers 404.

A collaborator’s products

Request a collaborator with ?fields=products to get the products they own, each with id and name. A merged product shows as the product it joined. Collaborators lists the other fields.

Owners through mappings

The /mappings routes also read and change owners, as Mappings describes. Those calls answer with a Deprecation header and a Link to /products.

Your privacy choices

Account, checkout and chat you request work without optional tracking. Choose whether to allow these other uses on this website.

You can change or withdraw your choices at any time using “Privacy choices.” We remember your choice for 180 days. Read our privacy policy.