less than a minute read • Updated 10 minutes ago
Customer portal API reference
Reference for the /s/customer API endpoints used to build a custom customer portal.
This reference covers the /s/customer endpoints, used if you’re building your own customer portal interface instead of using the ready-to-go <foxy-customer-portal> element. If you’re not sure you need this, see Add the customer portal to your website instead.
Conventions
CORS: You must specify the domains your portal will run on (see Enable the customer portal). This blocks certain attacks and unauthorized access, and does prevent use in very old browsers.
REST:
GETretrieves data and should have no body.POSTcreates something new.PATCHmodifies an existing thing.Request bodies: For
POSTandPATCH, submit a JSON object as the body.Version header: Pass
FOXY-API-VERSION: 1with every request.Successful requests: A
200status code means success, with a JSON payload.Errors: Non-2XX/3XX status codes, with a JSON body like:
{
"type": "authentication",
"code": "422",
"message": "`password` not defined or invalid."
}
Authenticating
POST /s/customer/authenticate
Required fields: email, password.
fetch('https://foxy-demo.foxycart.com/s/customer/authenticate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"FOXY-API-VERSION": "1"
},
body: JSON.stringify({
email: 'demo@example.com',
password: 'demo12345'
})
})
.then(response => response.json())
.then(data => console.log(data));
Response:
{
"expires_in": 172800,
"session_token": "cf9a7097-bc93-4ff0-8e47-986fffb4c380",
"jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
expires_inis the session lifetime in seconds, as configured in Foxy.jwtuses HS256 (shared secret) signing. This is optional — see JWT.io for details. Contact Foxy if you need a public/private keypair instead.session_tokencan be used to authenticate later requests as aBearertoken:Authorization: Bearer cf9a7097-bc93-4ff0-8e47-986fffb4c380.
Retrieving a customer
GET /s/customer
Optional parameters:
zoom:default_billing_address,default_shipping_address,default_payment_methodsso: returns an SSO URI as_links["fx:checkout"]. See Set up SSO between the customer portal and checkout.
Response fields include email, first_name, last_name, tax_id, id, is_anonymous, last_login_date, and date_created/date_modified, plus embedded resources like fx:attributes, fx:default_billing_address, fx:default_shipping_address, fx:default_payment_method, fx:transactions, and fx:subscriptions (when zoomed).
Modifying a customer
PATCH /s/customer
Accepted values in the JSON body:
first_name,last_name,email,tax_idpassword: a new password (minimum 8 characters). Enforce any complexity requirements in your own UI.password_old: required ifpasswordis passed. Must match the current password, or a temporary password from a reset request._embedded: can containfx:default_billing_address,fx:default_shipping_address,fx:default_payment_method(must be zoomed to appear in the response). Note thatcc_numberis not updatable via the customer portal.
Response: matches a GET /s/customer response.
Retrieving transactions
GET /s/customer/transactions
Optional parameters:
zoom:items,items:item_optionslimit(default 10),offset(default 0),order(defaulttransaction_date desc) — see the API docs for details
Returns a paginated collection of transactions, each with a fx:receipt link and embedded fx:attributes.
Retrieving & modifying subscriptions
GET /s/customer/subscriptions
Optional parameters:
zoom:transactionslimit(default 10),offset(default 0),order(defaultnext_transaction_date asc),is_active(defaulttrue) — see the API docs for details
Each subscription includes _embedded.template_config.allow_next_date_modification, a boolean indicating whether the customer can change the next charge date. This is returned per-subscription, though the underlying setting is store-wide.
PATCH /s/customer/subscriptions/SUBSCRIPTION_ID
Pre-requisites:
Allow Next Date Modification must be enabled in the customer portal settings to modify
next_transaction_date.Allow Frequency Modification must be configured as a JSONata query returning an array of allowed frequency values — for example,
$contains(frequency, "m")allows["1m","2m","3m","6m","1y"]. Only frequencies in the returned array can be patched. The subscription’stransaction_template(withitemsanditem_optionszoomed) is available to your JSONata query.The URI is returned in
_links.selfon the subscription object.
Response: the updated subscription object.
Notes
Loyalty points example: This API can support a homegrown loyalty points system. Roughly: process the transaction webhook to calculate points earned (for example, based on the product total minus coupons), check the transaction’s
attributesfor aLoyalty_Points_Applied_Onflag to avoid double-counting, then update aLoyalty_Pointscustomer attribute (setvisibilitytopublicso it’s readable from the portal). To let customers redeem points, have your portal front-end call your own backend, which validates the request via the session JWT, creates a coupon code for a pre-existing coupon via the coupon codes API, and returns it to the customer to apply. This isn’t a built-in Foxy feature — it requires custom backend code.