Members reference
Every member endpoint, with full request and response shapes.
All paths are relative to your base URL and require
Authorization: Bearer {token}.
| Method | Path | Purpose |
|---|---|---|
POST | /api/v2.0/stores/{storeId}/members | Create with consent — the webshop signup call |
POST | /api/v2.0/stores/{storeId}/members/enroll | Create from a phone number, send activation SMS |
GET | /api/v2.0/stores/{storeId}/members/search | Find by phone, email, identifier, card or activation token |
GET | /api/v2.0/stores/{storeId}/members/{memberId} | Read one member |
PUT | /api/v2.0/stores/{storeId}/members/{memberId} | Update — see what an omitted field does |
DELETE | /api/v2.0/stores/{storeId}/members/{memberId} | Mark for deletion |
GET | /api/v2.0/stores/{storeId}/members/{memberId}/coupons/ | Member’s coupons |
GET | /api/v2.0/stores/{storeId}/members/{memberId}/stamp-cards | Member’s stamp cards |
GET | /api/v2.0/stores/{storeId}/members/{memberId}/widgets/profile | Signed URL for an embeddable profile |
POST | /api/v2.0/stores/{storeId}/members/{memberId}/reset-phone | Start a phone change |
POST | /api/v2.0/stores/{storeId}/members/{memberId}/reset-phone-verification | Confirm a phone change |
POST | /api/v2.0/stores/{storeId}/members/{memberId}/otp | Send a one-time code for an action, such as login |
POST | /api/v2.0/stores/{storeId}/members/{memberId}/otp-verification | Verify a one-time code |
GET/POST | /api/v2.0/stores/{storeId}/members/{memberId}/dependents | Family members |
GET | /api/v2.0/stores/{storeId}/members/{memberId}/invited-friends | Referrals |
The member object
Section titled “The member object”Returned by create, read, update and search.
{ "id": "m_nsr714RRBEHX", "first_name": "Ola", "last_name": "Nordmann", "email": "ola.nordmann@example.com", "additional_identifiers": [], "remarks": null, "phone": { "country_code": "+47", "number": "99900001" }, "birth_date": "1988-04-12T00:00:00", "address": { "street": "Karl Johans gate 3", "city": "Oslo", "zip_code": "0154", "state": null, "country_code": "NO" }, "gender": "NotShared", "consent": { "gdpr_accepted": true, "save_order_history": true, "receive_sms": true, "receive_email": false }, "membership_detail": { "points": 250.0, "qualification_points": 340.0, "pending_points": 0.0, "remaining_points": 160.0, "level_title": "Gold", "next_level_title": "Platinum", "next_level_points": 500.0, "level_expire_date": "2027-06-16T00:00:00" }, "department_ids": ["101"], "segments": [ { "id": 633, "text": "What are you interested in?", "type": "Checkbox", "is_visible_to_follower": true, "is_required": false, "value": null, "selected_options": [4101, 4103] } ]}| Field | Notes |
|---|---|
id | The member id. Opaque, case-sensitive |
gender | Male, Female, NotShared, NonBinary |
consent | All four booleans always present on responses |
membership_detail.points | The balance — show this one. See Points |
segments[].id | The segment id. Sent back as segment_id — see Update a member |
additional_identifiers | Deprecated. Use the identifiers endpoints |
Create a member
Section titled “Create a member”POST /api/v2.0/stores/{storeId}/membersThe webshop signup call, for when consent has already been collected on
your form. Returns 200 with the created member.
Request
Section titled “Request”{ "phone": { "country_code": "+47", "number": "99900001" }, "first_name": "Ola", "last_name": "Nordmann", "email": "ola.nordmann@example.com", "birth_date": "1988-04-12T00:00:00", "gender": "NotShared", "address": { "street": "Karl Johans gate 3", "city": "Oslo", "zip_code": "0154", "state": null, "country_code": "NO" }, "department_ids": ["101"], "consent": { "gdpr_accepted": true, "save_order_history": true, "receive_sms": true, "receive_email": false }, "segments": [ { "segment_id": 633, "selected_options": [4101] } ], "origin": { "system_id": "my-webshop", "employee_id": null, "department_id": "101", "channel": "OnlineStore" }}| Field | Required | Notes |
|---|---|---|
phone | Yes | country_code is a dial code (+47) |
first_name, last_name | Validated non-empty | |
email | Validated as an address when present | |
consent | Yes | gdpr_accepted must be true |
consent.receive_sms, consent.receive_email | Send both | Left out, each takes the value of gdpr_accepted — that is, true |
address.country_code | ISO alpha-2 | Rejected if not a real code |
department_ids | Array of strings | |
origin.channel | Set to "OnlineStore" | See the one field everyone forgets |
password, repeat_password | Optional, write-only | Min 8, max 64, uppercase + numbers |
The endpoint sends a welcome SMS, or a welcome email if the store has no SMS configured.
Enrol a member
Section titled “Enrol a member”POST /api/v2.0/stores/{storeId}/members/enrollCreates a member from a phone number and sends an activation link by SMS. The member is not active until they accept.
{ "phone": { "country_code": "+47", "number": "99900001" }, "department_id": "101", "origin": { "system_id": "my-webshop", "department_id": "101", "channel": "OnlineStore" }, "additional_info": { "first_name": "Ola", "last_name": "Nordmann", "email": "ola.nordmann@example.com" }}phone and department_id are required. additional_info is optional.
If the member already exists and has not yet accepted, we send a fresh activation link — which makes this safe to call as a “resend”.
Search
Section titled “Search”GET /api/v2.0/stores/{storeId}/members/search?phone=%2B4799900001| Parameter | Notes |
|---|---|
phone | International format (+47… or 0047…). National format assumes the store’s country |
email | |
identifierValue | Your own customer id, if configured |
cardIdentifier | The card identifier linked to the member |
activationToken | For completing an in-store signup |
At least one is required. Returns an array of members for every
parameter, including activationToken.
[ { "id": "m_nsr714RRBEHX", "first_name": "Ola", "...": "..." } ]| Situation | Response |
|---|---|
| Found | 200 with a one-element array |
| Not found | 200 with [] |
| No parameter given | 400, naming the parameters you can send |
| Malformed email | 400 “Email is not valid” |
| Malformed phone | 400 “Phone number is not valid” |
Read a member
Section titled “Read a member”GET /api/v2.0/stores/{storeId}/members/{memberId}Returns the member object. Call this to refresh points and level before rendering a loyalty panel.
Update a member
Section titled “Update a member”PUT /api/v2.0/stores/{storeId}/members/{memberId}Same body as create, with no phone field. See changing a phone
number.
PUT is neither a full replace nor a patch. What happens to a field you
leave out depends on the field:
| Left out of the body | Result |
|---|---|
first_name, last_name, email, birth_date, gender | Kept — the current value stays |
address, department_ids, segments | Cleared |
consent.receive_sms, consent.receive_email | Set to false — the member is unsubscribed from that channel |
Sending segments back
Section titled “Sending segments back”Segments come back from GET in the read shape — id, text, type and
the rest. PUT takes the write shape, keyed by segment_id. Sending the
read shape back unchanged returns:
Segment ids are duplicated.Map them before you send:
const segments = current.segments.map(s => s.type === 'Text' || s.type === 'DateTime' ? { segment_id: s.id, value: s.value } : { segment_id: s.id, selected_options: s.selected_options });The full read-modify-write is in Keeping profiles in sync.
gdpr_accepted: false returns 400:
The 'gdpr_accepted' property on the 'Consent' object must be set to true.If your goal is to delete the member, please use the DELETE endpoint.Deleting a member
Section titled “Deleting a member”DELETE /api/v2.0/stores/{storeId}/members/{memberId}{ "is_ok": true, "details": "" }This is the correct response to a GDPR erasure request, and the correct response to a customer withdrawing consent entirely.
Clear diller_member_id on your own customer record at the same time.
Changing a phone number
Section titled “Changing a phone number”The phone number is the member’s identity, so changing it is a verified, two-step flow rather than a field update.
POST /api/v2.0/stores/{storeId}/members/{memberId}/reset-phone{ "country_code": "+47", "number": "99900002" }POST /api/v2.0/stores/{storeId}/members/{memberId}/reset-phone-verification{ "phone": { "country_code": "+47", "number": "99900002" }, "otp_code": 123456}Login by SMS code
Section titled “Login by SMS code”If you want customers to reach their loyalty profile without a password.
POST /api/v2.0/stores/{storeId}/members/{memberId}/otp{ "action": "login" }Sends a code by SMS. Sending is all this call does — it does not log anyone in or change anything.
POST /api/v2.0/stores/{storeId}/members/{memberId}/otp-verification{ "otp_code": 123456, "action": "login" }{ "is_ok": true, "details": "" }The action must match the one you sent the code for.
The embeddable profile widget
Section titled “The embeddable profile widget”Rather than building loyalty pages yourself, you can embed ours.
GET /api/v2.0/stores/{storeId}/members/{memberId}/widgets/profile{ "details_url": "https://diller.app/member/widgets/profile/?token=..." }Put that URL in an iframe.
A quick way to give a merchant a working “My loyalty” page on day one, while you build something bespoke later.
Dependents
Section titled “Dependents”Family members attached to a membership, where the merchant has enabled it.
GET /api/v2.0/stores/{storeId}/members/{memberId}/dependentsPOST /api/v2.0/stores/{storeId}/members/{memberId}/dependents[ { "id": 0, "name": "Kari", "birthdate": "2015-06-01", "gender": "Female" }, { "id": 77, "name": "Jonas", "birthdate": "2018-02-14", "gender": "Male" }]POST replaces the whole collection:
- add — include with
"id": 0 - update — include the complete object with its real id
- delete — leave it out of the array
Returns 204. name is limited to 50 characters. If a birth date’s day or
month is unknown, use 1.
Referrals
Section titled “Referrals”GET /api/v2.0/stores/{storeId}/members/{memberId}/invited-friendsGET /api/v2.0/stores/{storeId}/members/{memberId}/invited-friend?invitationToken={token}[ { "first_name": "Kari", "last_name": "Nordmann", "email": "kari@example.com", "created_at": "2026-08-01T09:12:00", "is_accepted": true, "points": 50 }]Available when the store has friend_referral_enabled: true.
