Create a member
POST/v1/members
Enrolls a guest. Call it when someone signs up in your app, or the first time an existing account of yours opens the rewards screen. It is safe to call again for a guest you already enrolled: the same external_id returns the existing member.
Permissions: Secret key with members:write.
Guide
Members and sign-inRequest headers#
Idempotency-KeystringRequiredRequired on this endpoint. Any string up to 255 characters; use a UUID v4. Missing returns400 idempotency_key_required.Max Length 255
Request body#
external_idstringRequiredYour id for this guest. Up to 128 characters, unique in your brand.Max Length 128first_namestringlast_namestringemailstring (email)Saved in lowercase.phonestringE.164. See phone rules below.phone_verifiedbooleanSendtrueonly if you confirmed the number with an SMS code. Defaultfalse.birthdaystring (date)YYYY-MM-DD.communication_preferencesobjectemail_marketing,sms_marketing,push_marketing. Send what the guest agreed to at sign-up.Show attributesHide attributes
email_marketingbooleansms_marketingbooleanpush_marketingboolean
metadataobjectUp to 20 keys, 500 characters each.
Response fields#
Returns 201 or 200 with Member
idstring (uuid)unPLUG's id for the member. Store it next to your user record.external_idstringNullableYour id for the guest, up to 128 characters.nullfor a guest who has only earned at the register and isn't linked to your login yet.Max Length 128statusstringactive. Themember.deletedwebhook carriesdeleted; after that, calls about the member return410 member_deleted.One ofactive,deletedfirst_namestringNullablelast_namestringNullableemailstring (email)NullableSaved in lowercase.phonestringNullableE.164, for example+15125550142.phone_verifiedbooleantruewhen you confirmed the guest owns the number, for example with an SMS code. Only verified phones link to existing members.birthdaystring (date)NullableYYYY-MM-DD.points_balanceintegerPoints the member has now. Never below zero.lifetime_pointsintegerAll points ever earned, used for tiers. Spending doesn't lower it.tierTierRefidandnameof the current tier.Show attributesTierRef
idstring (uuid)namestring
next_tierobjectNullableid,nameandpoints_needed(lifetime points still to earn).nullat the top tier.Show attributesHide attributes
idstring (uuid)namestringpoints_neededinteger
communication_preferencesobjectShow attributesHide attributes
email_marketingbooleansms_marketingbooleanpush_marketingboolean
metadataobjectYour own string values. Up to 20 keys, 500 characters each. Don't put personal data here.linked_existingbooleanOnly on create: true when an existing member was linked by verified phone.enrolled_atstring (date-time)When the guest joined the program.created_atstring (date-time)updated_atstring (date-time)
Which response you get#
| Situation | Status | What happens |
|---|---|---|
New external_id, no phone match | 201 | A new member is created. |
external_id already exists | 200 | The existing member is returned unchanged. Use PATCH to change their details. |
Verified phone matches a member with no external_id | 200 | That member is linked to your external_id and returned with "linked_existing": true. Their points, tier and history stay. |
Phone belongs to another member who has an external_id | 409 | phone_in_use. Nothing is created. |
Phone rules#
- Verified phones link. A guest who earned at the register before downloading your app already has a member under their phone number. Send
phone_verified: trueand they keep those points. - Unverified phones never link. They create a new member and the phone is saved with
phone_verified: false. This stops someone from typing another guest's number to take their points. - One phone per linked member. If a member with an
external_idalready has the number, you get409 phone_in_use. Ask the guest to sign in to their existing account, or create the member without the phone. - Sandbox test numbers
+15005550100to+15005550199count as verified in the sandbox.
Maya has been earning at the South Congress register under +15125550142 since June 2025, so the same request finds that member, links it to usr_10482 and returns it:
{
"id": "3f2b8c1e-6d0a-4e7b-9f3c-2a1d5e8b7c40",
"external_id": "usr_10482",
"phone": "+15125550142",
"phone_verified": true,
"points_balance": 420,
"lifetime_points": 1880,
"enrolled_at": "2025-06-14T15:02:44Z",
"linked_existing": true
}The response above is trimmed. The full response is a member object.
Error descriptions#
The Idempotency-Key header is missing.
external_id is missing.
A field has the wrong format, for example a phone that isn't E.164 or more than 20 metadata keys. param names the field.
Another member with an external_id has this phone.
A request with this Idempotency-Key is still running. Retry after a second.
This key was used with a different body.
Any endpoint can also return the common errors.