Siren

Customers

Siren's customer records in the REST API: the customer object and the routes to list, merge, and split customers and to link them to collaborators for lifetime commissions.

WordPress plugin and Siren Cloud

Last updated: October 26, 2026

Siren keeps one record for each shopper who buys, signs in or registers after a referral, or is linked to a collaborator. Each way a store knows the shopper is an identity, such as a store account or a guest checkout, and a merged customer holds the identities of every customer merged into it. Customers explains the screen these routes serve, and Lifetime Commissions explains links.

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. Linking and unlinking need Siren Plus or Pro. On WordPress, other plans answer 403 with the code rest_forbidden and “Your plan does not include this feature.” in WordPress’s error shape. On Siren Cloud, the refusal answers 403 with error.code plan_required.

On Siren Cloud, the dashboard calls these routes, and API keys can’t. A team member limited to some Properties sees a customer only when every identity is at a Property they reach, and gets 403 when a merge or split touches a store they can’t reach. Customers at different Properties can’t be merged, and the merge answers 400, until an Admin confirms the stores are one business with PUT /customers/matching/cross-store and {"confirmed": true}, which also lets Siren suggest matches across them. GET /customers/matching/cross-store answers { "confirmed" }.

The customer object

FieldTypeDescription
idintegerThe customer
labelstring”Customer #” and the ID
namestring or nullThe newest name a store reported
mergedIntoIdinteger or nullThe customer this one was merged into
lastSeenAtdatetime or nullWhen Siren last saw the customer
identitiesarrayEach way a store knows them: id, propertyId, integration (such as wordpress, wc, or edd), platformId (the store’s ID, null for a guest), name, hasEmail, guest, deleted, and lastSeenAt
collaboratorIdsarrayThe collaborators linked to the customer for lifetime commissions
opportunityCountintegerHow many visits belong to the customer
openSuggestionsintegerHow many merge suggestions wait for this customer

Siren never returns an email address. It keeps only a keyed hash, and hasEmail says whether an identity has one.

List customers

GET /customers

ParameterDescription
searchA customer ID with or without #, a store’s ID for the customer, or an exact email
integrationOne integration, such as wc
propertyIdOne store. Leave it out for every store
linked1 for linked customers, 0 for customers no one is linked to
collaboratorIdCustomers linked to one collaborator
matches1 for customers with an open merge suggestion
page, perPagePaging. perPage is 1 to 100, default 25

Answers { "customers": [...], "total" }, most recently seen first. Merged customers are left out.

Get a customer

GET /customers/:id

Answers { "customer": {...}, "suggestions": [...], "sales": [...], "crossStoreConfirmed" }. sales lists up to 50 transactions credited from the customer’s visits, each with id, date, and status. A merged customer answers with its own record, and its mergedIntoId names the customer to read instead. An unknown ID answers 404. Each suggestion has id, signal, strength, and the other customer. crossStoreConfirmed says whether customers can be matched and merged across stores, and it’s false on WordPress, where every customer is at one store.

Merge suggestions

GET /customers/suggestions lists open suggestions, optionally for one customerId, as { "data": [...] }, strongest first, at most 100. Each has id, signal, strength, and the two customers. signal is same_email_same_store for the same email at one store, or same_email for the same email at two stores once cross-store matching is confirmed.

POST /customers/suggestions/:id/dismiss dismisses that suggestion for good, or answers 404 for an unknown one, and answers id and state.

Merge customers

POST /customers/merge

Send survivorId, the customer to keep, and customerIds, the customers to merge into it. A merge covers at most 20 customers, the survivor included. Identities, visits, and sales move to the survivor. Answers 200 with customer and mergedIds. Send "preview": true to get only the questions the merge would ask, as conflicts.

When the customers are linked to more than one collaborator, the merge asks which stay linked. Without an answer it answers 409 with conflicts, and the error’s code is merge_conflict. Each conflict has key, options, and multiple. Answer it with collaboratorIds, a list of at least one of the offered collaborators. An answer that names a collaborator not offered repeats the 409. A missing survivorId or customerIds, an empty collaboratorIds, or a merge Siren refuses, such as one with a customer already merged, answers 400. An unknown customer answers 404.

Split an identity off

POST /customers/:id/identities/:identityId/split

Makes that identity a customer of its own, with the visits and sales that came through it and no collaborator linked. Answers 200 with customer, the original, and split, the new one. Splitting a customer’s only identity answers 400, and an identity that isn’t part of the customer answers 404.

POST /customers/:id/collaborators with {"collaboratorId": 12} links the customer, so the collaborator earns from their later purchases in programs that track Opportunity Bound To Collaborator. Answers 200 with customer and changed, which is false when the link already existed. A missing collaboratorId or an unknown collaborator answers 400, and so does a customer that was merged, naming the customer to link instead.

DELETE /customers/:id/collaborators/:collaboratorId unlinks them. Rewards already earned stay. It answers 200 with customer and changed, which is false when there was no link, and an unknown customer answers 404.

Linked customers on other records

  • A collaborator’s linkedCustomerCount field, requested with ?fields=linkedCustomerCount, counts the customers linked to them.
  • GET /opportunities?collaboratorId= lists the visits linked to a collaborator.
  • PUT /opportunities/:id takes customerCollaborators, a list of collaborator IDs that replaces the links on that visit’s customer, and cascadeRejectOnUnbind, a list of collaborator IDs. It works only with customerCollaborators in the same request. When that list drops a collaborator named in cascadeRejectOnUnbind, Siren also rejects that collaborator’s unpaid rewards (draft and approved) from that visit. Sending customerCollaborators needs Plus or Pro.

Data requests

WordPress’s Export Personal Data and Erase Personal Data tools cover Siren’s records, as Answer a Customer’s Data Request describes. On Siren Cloud, POST /customer-data/export and POST /customer-data/erase answer a shopper’s data request, as Answer a Customer’s Data Request describes. Send email (up to 254 characters), references (a list of {type, id}, such as stripe_customer@property:5), or opportunityIds, at most 50 identifiers in all. Export answers { "items": [...] }, each with groupId, groupLabel, itemId, and fields. Erase answers found, removed, retained, messages, unlinkedCollaborators (a count), and complete. A bad body answers 400, and a request that can’t run answers 503. Admins can call them, and so can a connected WordPress site for its own WordPress users. An Admin’s call with no active plan answers 403 with plan_required.

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.