Customer accounts
Register and sign in shoppers with bearer tokens, verify email, reset passwords, manage the address book, show order history and delete an account.
Shoppers can create an account with the store to save addresses and see their orders. Accounts belong to one store: the same email can have separate accounts at two stores. The API uses bearer tokens, never cookies, so your storefront server keeps the token and sends it as Authorization: Bearer ….
Endpoints
| Endpoint | Does |
|---|---|
POST /v1/auth/register | Creates an account and returns a token |
POST /v1/auth/login | Signs in and returns a token |
POST /v1/auth/logout | Revokes the current token |
GET /v1/auth/me | The signed-in account |
PATCH /v1/auth/me | Changes the name or email |
POST /v1/auth/verify | Confirms an email address from the verification link |
POST /v1/auth/verify/resend | Sends the verification email again |
POST /v1/auth/password/forgot | Emails a password reset link |
POST /v1/auth/password/reset | Sets a new password with the token from that link |
POST /v1/auth/password | Changes the password of a signed-in account |
GET, POST /v1/account/addresses | Lists or adds saved addresses |
PATCH, DELETE /v1/account/addresses/{id} | Changes or deletes a saved address |
GET /v1/orders, GET /v1/orders/{reference} | Order history |
DELETE /v1/account | Erases the account |
Register and sign in
curl -X POST https://api.elaraone.app/api/v1/auth/register \
-H "X-Tenant-Key: $ELARAONE_TENANT_KEY" \
-H "X-Tenant-Secret: $ELARAONE_TENANT_SECRET" \
-H "X-Cart-Token: $CART_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Katherine Johnson",
"email": "[email protected]",
"password": "correct-horse-battery",
"password_confirmation": "correct-horse-battery"
}'{
"data": {
"user": {
"id": 77,
"name": "Katherine Johnson",
"email": "[email protected]",
"email_verified_at": null,
"customer_id": 204
},
"token": "12|q8V…",
"expires_at": "2026-11-23T10:12:31+00:00"
}
}- Registration returns
201and login returns200, both with the same shape. - Passwords need at least 8 characters, and
password_confirmationmust match. - Wrong credentials, or an email already registered, return
422 VALIDATION_FAILEDwith the field indetails. - The token can be used straight away, before the email is verified.
expires_atsays when it stops working. - Send the guest's
X-Cart-Tokenwith login or registration to merge their basket into the customer's cart. An unknown or expired cart token is ignored; it never stops the sign-in. - Register, login, password reset, profile changes and password changes share a tight rate limit: 10 a minute per store and IP. See rate limits.
Keep the token on your server
Treat the bearer token like a password. Keep it in an httpOnly, secure cookie on your storefront's domain, and have your server add it to API calls. Never put it in localStorage.
Send the token on every call made for that customer, together with the store key and secret:
curl https://api.elaraone.app/api/v1/auth/me \
-H "X-Tenant-Key: $ELARAONE_TENANT_KEY" \
-H "X-Tenant-Secret: $ELARAONE_TENANT_SECRET" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"A missing, expired or revoked token returns 401 UNAUTHENTICATED. POST /v1/auth/logout revokes the token it was sent with.
Change the name or email
PATCH /v1/auth/me takes name, email or both. Changing the email also needs current_password.
Verify the email address
When an account is created, the store sends a verification email, if the store has set its storefront's verify-email page in Store settings. The link opens that page on your storefront with a signed query string.
Your page sends that query string to the API exactly as it arrived, as the query string of POST /v1/auth/verify:
// incomingUrl is the URL the shopper opened, e.g. https://hearthandoak.example/verify?expires=…&hash=…&id=…&signature=…
const query = new URL(incomingUrl).search // keep it byte for byte: same order, same encoding
const res = await fetch(`https://api.elaraone.app/api/v1/auth/verify${query}`, {
method: 'POST',
headers: {
'X-Tenant-Key': process.env.ELARAONE_TENANT_KEY!,
'X-Tenant-Secret': process.env.ELARAONE_TENANT_SECRET!,
},
})
// 200 { "data": { "status": "verified" } }, or 403 when the link is invalid or has expiredThe signature is checked against the exact query string, so do not re-encode, reorder or add parameters. POST /v1/auth/verify/resend (signed in) sends a fresh link, or answers already-verified.
Reset a forgotten password
POST /v1/auth/password/forgotwith{ "email": "…" }. It always answers200withreset-link-sent, whether or not the address has an account, so it cannot be used to find out who shops at the store.- The store emails a link to the reset page you set in Store settings, with the token and email filled in. The token works once, for 60 minutes. If the store has not set a reset page, no email is sent.
- Your reset page sends
POST /v1/auth/password/resetwithtoken,email,passwordandpassword_confirmation. A bad or expired token returns422 VALIDATION_FAILEDontoken.
Change the password
POST /v1/auth/password (signed in) takes current_password, password and password_confirmation. The token that made the request keeps working; every other token on the account is revoked, and revoked_tokens says how many.
The address book
{
"data": [
{
"id": 42,
"label": "Home",
"title": null,
"first_name": "Ada",
"last_name": "Lovelace",
"company_name": null,
"line_one": "221B Baker Street",
"line_two": null,
"line_three": null,
"city": "London",
"state": null,
"postcode": "NW1 6XE",
"country_id": 235,
"delivery_instructions": null,
"contact_email": null,
"contact_phone": "+447700900123",
"shipping_default": true,
"billing_default": true
}
]
}GETlists the customer's addresses, newest first.POSTcreates one (201).first_name,last_name,line_oneandcityare required.PATCH /v1/account/addresses/{id}changes any field.DELETEremoves the address.labelis an optional nickname such as "Home" or "Work", up to 50 characters.titleis the salutation.- Setting
shipping_defaultorbilling_defaulttotruemoves that default to this address, so only one address holds each. Deleting a default moves it to the newest remaining address. - Another customer's address id returns
404 NOT_FOUND.
At checkout, a signed-in customer can use a saved address with address_id, or save a new one with save_to_account. See carts.
Order history
GET /v1/orders lists the signed-in customer's orders, newest first, with page and perPage (1 to 100, default 24). GET /v1/orders/{reference} returns one order in the same shape checkout returns. See checkout.
When a customer verifies their email, orders they placed earlier as a guest with that address become part of their account.
Delete the account
DELETE /v1/account lets a shopper erase their own account. It needs the bearer token and the account password as current_password:
curl -X DELETE "https://api.elaraone.app/api/v1/account?current_password=correct-horse-battery" \
-H "X-Tenant-Key: $ELARAONE_TENANT_KEY" \
-H "X-Tenant-Secret: $ELARAONE_TENANT_SECRET" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"On success it answers { "data": { "status": "erased" } }, and:
- the account can never sign in again, and every token on it is revoked, including the one that made the request;
- saved addresses and open carts are deleted;
- orders are kept as the store's records, with names, street, email and phone removed;
- guest orders, carts and form submissions made with the account's verified email are anonymised the same way;
- the verified email and phone numbers are kept only as one-way hashes on the store's do-not-contact list, so automated messages never reach them again.
A missing or wrong password returns 422 VALIDATION_FAILED. 409 ACCOUNT_SHARED means the account shares its customer record with other accounts (the store linked them), so only the store can erase it; nothing is changed. Deletion is rate limited to 3 a minute and 10 an hour per account, and 20 an hour per IP.
Checkout and orders
Set up payment with Stripe or PayPal, place the order exactly once, give guests access to their order, and follow an order through its states.
Payments
Take card payments through the store's own Stripe account and PayPal, handle test and live mode, and turn declines into clear messages.