/account/addresses/create
{% form 'address_create' %}
Logged-in only. Adds a saved address; is_default promotes it for its type.
Form fields
-
address_typeRequired shipping or billing.
-
first_nameRequired Recipient first name.
-
last_nameRequired Recipient last name.
-
address1Required Street address.
-
address2Optional Apartment, suite, or additional address line.
-
cityRequired City/locality.
-
country_codeRequired ISO country code.
-
province_codeOptional State/province code where the country uses one.
-
postal_codeOptional Optional; validated against the country's postal format when supplied.
-
companyOptional Company or organization name.
-
phoneOptional Delivery/contact phone.
-
is_defaultOptional true, 1, or on makes this the default for its type.
-
_formatOptional 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.
/account/addresses/delete
{% form 'address_delete' %}
Logged-in only. Removes the saved address.
Form fields
-
address_idRequired Address to remove.
-
_formatOptional 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
}
/account/addresses/set-default
{% form 'address_set_default' %}
Logged-in only. Promotes the address to default for its type.
Form fields
-
address_idRequired Address to make the default for its type.
-
_formatOptional 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
}
/account/addresses/update
{% form 'address_update' %}
Logged-in only. PATCH semantics on the supplied fields.
Form fields
-
address_idRequired Address being edited.
-
address_typeOptional shipping or billing; unchanged when omitted.
-
first_nameOptional Unchanged when omitted.
-
last_nameOptional Unchanged when omitted.
-
address1Optional Street address; unchanged when omitted.
-
address2Optional Apartment, suite, or additional address line; unchanged when omitted.
-
cityOptional Unchanged when omitted.
-
country_codeOptional ISO country code; unchanged when omitted.
-
province_codeOptional State/province code where the country uses one.
-
postal_codeOptional Validated for the resulting country; unchanged when omitted.
-
companyOptional Company or organization name; unchanged when omitted.
-
phoneOptional Delivery/contact phone; unchanged when omitted.
-
is_defaultOptional true, 1, or on makes this the default for its type; unchanged when omitted.
-
_formatOptional 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.
/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
-
providerOptional email or phone; inferred from phone_number when omitted, otherwise email.
-
emailOptional Required when provider is email.
-
phone_numberOptional Required when provider is phone.
-
_formatOptional 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. With the bridge, the theme shows its own verification step from tf:action-success: mode says whether the code signs in or creates an account, and response.message is the notice to show.
/account/email/add
{% form 'email_add' %}
Logged-in only. Attaches an email to a phone-only account as contact-of-record; login identities are only created by a completed auth-code challenge. When the email belongs to a customer record nobody has signed in to (for example from a guest checkout), a code is sent to it first, and the email joins the account, verified, once that code is posted back; the record's orders move to the account.
Form fields
-
emailRequired Email to attach as contact-of-record. Send the same email again with code to finish a verification step.
-
codeOptional 6-digit code sent to the email when the first request answered requires_verification: true.
-
_formatOptional Set to json when submitting with fetch; omit for the normal browser redirect.
Validation
Logged-in customer only; the account must not already carry an email, and the email must be valid. An email no other customer holds is added unverified. An email held by a customer record nobody has signed in to sends a code to that email instead (requires_verification: true); post the same email with code to add it verified and merge that record, with its orders, into the account. An email held by a customer who has signed in, or by a record with merchant-managed data (a note, tags, metafields, saved addresses, store credit, manual groups or discount eligibility), is refused with STOREFRONT_CUST_EMAIL_EXISTS. A wrong or expired code returns STOREFRONT_CUST_INVALID_EXPIRED_CODE.
Limits
One email per account. The code has 6 digits, is bound to the visitor session, and uses the sign-in code expiry, attempt and send limits.
Response
{
success,
response,
requires_verification,
user_errors
}
requires_verification is true when a code was sent and nothing was added yet; response.message then says where the code went. Show a code field and post the action again with email and code; requires_verification is false once the email is added. The code step needs the JSON response: a form submission redirects to the account page either way.
/login
{% form 'login' %}
Completes login with the code — same flow for email and phone.
Form fields
-
providerOptional email or phone; inferred from phone_number when omitted, otherwise email.
-
codeRequired The code from auth_code_send (purpose login).
-
emailOptional Required when provider is email.
-
phone_numberOptional Required when provider is phone.
-
_formatOptional 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; code checks are also limited per client address.
Response
{
success:true,
redirect,
user_errors
}
hosted mode establishes the customer session under a new session cookie. The cart and checkout carry on; forms rendered before sign-in need the next page's CSRF token. redirect is the account page in the shopper's language; the bridge navigates there.
/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. An unpaid order from the shopper's open checkout is cancelled first, as signing out in checkout does. While that order is being created, or when it cannot be cancelled safely, sign-out is refused and the shopper stays signed in.
Limits
Idempotent; no action-specific numeric limit.
Response
{
success,
redirect
}
JSON returns the localized home route. Native form mode clears customer authentication and redirects there with HTTP 303. A refused sign-out returns {success:false, user_errors} in JSON and re-renders the account page with the message in form mode; retrying shortly after succeeds.
/account/orders/cancel
{% form 'order_cancel' %}
Logged-in only. Cancels the customer's own order while the store's cancellation rules allow it; captured money refunds automatically.
Form fields
-
order_idRequired The customer's own order to cancel.
-
_formatOptional Set to json when submitting with fetch; omit for the normal browser redirect.
Validation
Logged-in customer and owned order only. The store's cancellation rule must be enabled and the order inside its window; an order with shipped or delivered goods is never cancellable. Captured money is refunded in full on the original payment rail before the order flips to cancelled.
Limits
Idempotent per order — an already-cancelled order refuses with the same not-available error.
Response
{
success,
user_errors
}
form mode 303s back to the order page.
/account/phone/add
{% form 'phone_add' %}
Logged-in only. Attaches a phone number to an email-only account as contact-of-record, with the same verification step as email_add when a customer record nobody has signed in to holds the number.
Form fields
-
phone_numberRequired E.164 phone number to attach as contact-of-record. Send the same number again with code to finish a verification step.
-
codeOptional 6-digit code sent to the phone when the first request answered requires_verification: true.
-
_formatOptional Set to json when submitting with fetch; omit for the normal browser redirect.
Validation
Logged-in customer only; the account must not already carry a phone number. E.164 format, and phone sign-in must be enabled. The same verification step as email_add applies when a customer record nobody has signed in to holds the number; a number held by a signed-in customer or a merchant-managed record is refused with STOREFRONT_CUST_PHONE_EXISTS.
Limits
One phone number per account. The code has 6 digits, is bound to the visitor session, and uses the sign-in code expiry, attempt and send limits.
Response
{
success,
response,
requires_verification,
user_errors
}
requires_verification and the code step work as for email_add.
/account/profile
{% form 'profile_update' %}
Logged-in only. PATCH semantics: only supplied fields change. The sign-in email address and phone number cannot be changed here.
Form fields
-
first_nameOptional Only supplied fields change (PATCH semantics).
-
last_nameOptional Only supplied fields change.
-
accepts_marketingOptional true/false; only applied when supplied. An unchecked checkbox submits nothing, so place a hidden false field before it so that opting out can be submitted.
-
date_of_birthOptional YYYY-MM-DD; empty clears it. Only applied when supplied.
-
_formatOptional 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, accepts_marketing, and date_of_birth. A future date of birth is rejected. 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
}
/register
{% form 'register' %}
Completes registration with the code. Gated by self-registration; guest state and guest orders on this email attach automatically.
Form fields
-
providerOptional email or phone; inferred from phone_number when omitted, otherwise email.
-
codeRequired The code from auth_code_send (purpose register).
-
emailOptional Required when provider is email.
-
phone_numberOptional Required when provider is phone.
-
first_nameOptional Optional customer first name.
-
last_nameOptional Optional customer last name.
-
accepts_marketingOptional Marketing consent; shown when the store collects it (collect_marketing_consent). Any non-empty value = consented.
-
_formatOptional 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; code checks are also limited per client address; first and last names are each limited to 100 characters.
Response
{
success:true,
redirect,
response,
user_errors
}
hosted mode also establishes the customer session under a new session cookie and attaches eligible guest state/orders. The cart and checkout carry on; forms rendered before sign-in need the next page's CSRF token. redirect is the account page in the shopper's language; the bridge navigates there.
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).