Customer actions

Authenticate with one-time codes and manage the signed-in customer's profile and addresses.

POST /account/addresses/create
{% form 'address_create' %}

Logged-in only. Adds a saved address; is_default promotes it for its type.

Form fields

address_type Required

shipping or billing.

first_name Required

Recipient first name.

last_name Required

Recipient last name.

address1 Required

Street address.

address2 Optional

Apartment, suite, or additional address line.

city Required

City/locality.

country_code Required

ISO country code.

province_code Optional

State/province code where the country uses one.

postal_code Optional

Optional; validated against the country's postal format when supplied.

company Optional

Company or organization name.

phone Optional

Delivery/contact phone.

is_default Optional

true, 1, or on makes this the default for its type.

_format Optional

Set to json when submitting with fetch; omit for the normal browser redirect.

Validation

Logged-in customer only; address_type is shipping or billing; country, province, and postal code are checked against the address-format registry.

Limits

250 addresses/customer; names 100; address lines 255; city 100; company 100; postal code 20. Phone must be valid for the selected country and is stored as E.164.

Response

{
  success,
  response,
  user_errors
}

response contains the created address.

POST /account/addresses/delete
{% form 'address_delete' %}

Logged-in only. Removes the saved address.

Form fields

address_id Required

Address to remove.

_format Optional

Set to json when submitting with fetch; omit for the normal browser redirect.

Validation

Logged-in customer and owned address only.

Limits

No action-specific numeric limit.

Response

{
  success,
  response,
  user_errors
}
POST /account/addresses/set-default
{% form 'address_set_default' %}

Logged-in only. Promotes the address to default for its type.

Form fields

address_id Required

Address to make the default for its type.

_format Optional

Set to json when submitting with fetch; omit for the normal browser redirect.

Validation

Logged-in customer and owned address only; promotes the address within its shipping/billing type.

Limits

Exactly one default per customer and address type.

Response

{
  success,
  response,
  user_errors
}
POST /account/addresses/update
{% form 'address_update' %}

Logged-in only. PATCH semantics on the supplied fields.

Form fields

address_id Required

Address being edited.

address_type Optional

shipping or billing; unchanged when omitted.

first_name Optional

Unchanged when omitted.

last_name Optional

Unchanged when omitted.

address1 Optional

Street address; unchanged when omitted.

address2 Optional

Apartment, suite, or additional address line; unchanged when omitted.

city Optional

Unchanged when omitted.

country_code Optional

ISO country code; unchanged when omitted.

province_code Optional

State/province code where the country uses one.

postal_code Optional

Validated for the resulting country; unchanged when omitted.

company Optional

Company or organization name; unchanged when omitted.

phone Optional

Delivery/contact phone; unchanged when omitted.

is_default Optional

true, 1, or on makes this the default for its type; unchanged when omitted.

_format Optional

Set to json when submitting with fetch; omit for the normal browser redirect.

Validation

Logged-in customer and owned address only; PATCH semantics. A changed country must exist and clears the saved province; a changed province and phone are validated against the resulting country. Postal updates are trimmed and length-checked.

Limits

Names 100; address lines 255; city 100; company 100; postal code 20. Phone is stored as E.164. Omitted fields remain unchanged.

Response

{
  success,
  response,
  user_errors
}

response contains the updated address.

POST /auth/code
{% form 'auth_code_send' %}

Step one of every flow. The server derives login vs register from whether the identifier has an account and returns it as mode — the form never declares a purpose. The code is the ONLY credential. Phone requires an active SMS/WhatsApp provider.

Form fields

provider Optional

email or phone; inferred from phone_number when omitted, otherwise email.

email Optional

Required when provider is email.

phone_number Optional

Required when provider is phone.

_format Optional

Set to json when submitting with fetch; omit for the normal browser redirect.

Validation

provider is email or phone when supplied; otherwise phone is inferred from phone_number and email is the default. Email is normalized and validated, phone is normalized to E.164, provider availability and registration policy are checked, and the server derives login versus register.

Limits

Code expires after 5 minutes; 3 verification attempts; 5 sends/identifier/hour; 10 sends/visitor session/hour. A new code invalidates the previous active code.

Response

{
  success:true,
  mode,
  expires_at,
  expiry_minutes,
  response,
  user_errors
}

form mode renders the verification step.

POST /login
{% form 'login' %}

Completes login with the code — same flow for email and phone.

Form fields

provider Optional

email or phone; inferred from phone_number when omitted, otherwise email.

code Required

The code from auth_code_send (purpose login).

email Optional

Required when provider is email.

phone_number Optional

Required when provider is phone.

_format Optional

Set to json when submitting with fetch; omit for the normal browser redirect.

Validation

Valid unconsumed code bound to store, provider, normalized identifier, session, and login mode; identity must resolve to a customer.

Limits

Code expires after 5 minutes with 3 attempts.

Response

{
  success:true,
  user_errors
}

hosted mode establishes the customer session.

POST /logout
{% form 'logout' %}

Ends the customer session.

This action has no form fields beyond the CSRF token emitted by the form tag.

Validation

Ends the current customer authentication state without destroying the visitor session.

Limits

Idempotent; no action-specific numeric limit.

Response

Redirect-only: clears customer authentication and redirects to the localized home route.

POST /account/profile
{% form 'profile_update' %}

Logged-in only. PATCH semantics — only supplied fields change; identity (login email/phone) is NOT editable here.

Form fields

first_name Optional

Only supplied fields change (PATCH semantics).

last_name Optional

Only supplied fields change.

accepts_marketing Optional

true/false; only applied when supplied.

_format Optional

Set to json when submitting with fetch; omit for the normal browser redirect.

Validation

Logged-in customer only; PATCH semantics for first_name, last_name, and accepts_marketing. Login email and phone identities cannot be changed here. Marketing opt-in follows the store's consent and double-opt-in settings.

Limits

First name and last name are each limited to 100 characters.

Response

{
  success,
  response,
  user_errors
}
POST /register
{% form 'register' %}

Completes registration with the code. Gated by self-registration; guest state AND guest orders on this email attach automatically.

Form fields

provider Optional

email or phone; inferred from phone_number when omitted, otherwise email.

code Required

The code from auth_code_send (purpose register).

email Optional

Required when provider is email.

phone_number Optional

Required when provider is phone.

first_name Optional

Optional customer first name.

last_name Optional

Optional customer last name.

accepts_marketing Optional

Marketing consent; shown when the store collects it (collect_marketing_consent). Any non-empty value = consented.

_format Optional

Set to json when submitting with fetch; omit for the normal browser redirect.

Validation

Valid unconsumed code bound to store, provider, normalized identifier, session, and register mode; self-registration must be enabled.

Limits

Code expires after 5 minutes with 3 attempts; first and last names are each limited to 100 characters.

Response

{
  success:true,
  response,
  user_errors
}

hosted mode also establishes the customer session and attaches eligible guest state/orders.

After login, guest state follows the customer: the cart, wishlist, consent choices, pending review photos — and any guest ORDERS placed with the same email — become theirs. Auth pages are themed surfaces; these endpoints are what their forms submit to, and your own sections can use them the same way (the {% form %} kinds are auth_code_send, register, login, logout).