Loading theme toggle

Storefront BFF API

The Storefront BFF API is a REST API that provides a stable, domain-oriented interface for building customer experiences on the Horizon Storefront.

The API uses predictable resource-oriented URLs, accepts JSON request bodies, returns JSON responses, and uses standard HTTP response codes and authentication.

All API requests should be made to this base URL. See Environments for staging and development URLs.

Endpoints are organised by domain.

Check out our development quickstart guide.

Authentication

The Storefront API uses different authentication methods depending on the caller type.

The API supports two authentication schemes depending on the use case.

Public endpoints require no authentication. These include:

  • Product and category browse
  • Search suggestions
  • CMS content and static pages

These endpoints do not expose PII and can be cached at the edge.

Customer flows (cart, checkout, orders, profile) require a BFF session token obtained via login.

Login flow

  1. Call POST /auth/login with credentials and reCAPTCHA response
  2. Receive accessToken, tokenType, expiresIn, and customer object
  3. Include the token in X-BFF-Token header on subsequent requests

The login response contains:

accessTokenstringrequired

JWT token to include in subsequent requests.

tokenTypestringrequired

Token type, always "Bearer".

expiresInintegerrequired

Token validity in seconds.

customerobjectrequired

Customer profile object with id, emailAddress, firstName, lastName.

Include the token in the X-BFF-Token header for all authenticated requests.

  • expiresIn indicates token validity in seconds
  • 401 Unauthorized indicates an expired or invalid token
  • 403 Forbidden indicates insufficient permissions

Tokens are short-lived. Handle expiry by re-authenticating or using the refresh flow at POST /auth/token.

Internal services use Google Cloud identity tokens.

These endpoints must not be exposed to the public internet.

Common headers used for authentication.

Errors

The Storefront BFF uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a validation failed, etc.). Codes in the 5xx range indicate an error with the server (these should be rare).

Some 4xx errors that could be handled programmatically include an error code that briefly explains the error reported.

codestring

For some errors that could be handled programmatically, a short string indicating the error code reported.

messagestringrequired

A human-readable message providing more details about the error. These messages can be shown to your users or logged for debugging.

statusintegerrequired

HTTP status code (e.g., 400, 401, 404, 422, 429, 500).

errorsarray

For validation errors, a list of detailed field-level errors. Each error contains field, code, and message properties.

typeenum

The type of error returned. One of api_error, auth_error, validation_error, not_found_error, conflict_error, or rate_limit_error.

Within the errors array, each detailed error contains:

fieldstring

If the error is field-specific, the field path related to the error. For example, you can use this to display a message near the correct form field (e.g., email, shippingAddress.postcode).

codestring

Machine-readable error code for this specific field error (e.g., REQUIRED, INVALID_FORMAT, OUT_OF_RANGE).

messagestring

Human-readable explanation for this field error.

Our API libraries raise exceptions for many reasons, such as invalid parameters, authentication errors, and network unavailability. We recommend writing code that gracefully handles all possible API exceptions.

Requests

The Storefront BFF is a JSON-over-HTTP API. This page covers the common patterns used across endpoints.

Standard HTTP methods for CRUD operations.

Any request with a body must set Content-Type: application/json.

Resources have stable, unique identifiers. Treat IDs as opaque strings.

Monetary values use minor units (cents).

Do not send floating-point dollar values. Always use the structured Money object.

typestringrequired

Precision type, always "centPrecision".

currencyCodestringrequired

ISO 4217 currency code (e.g., AUD, NZD).

centAmountintegerrequired

Amount in minor units (cents).

fractionDigitsintegerrequired

Number of decimal places for the currency.

Text that varies by locale uses LocalizedString.

Keys are IETF language tags (e.g., en-AU).

All timestamps use RFC 3339 / ISO 8601 format in UTC.

Always include the trailing Z for UTC. Do not send local time zone offsets.

Collection endpoints return a paged envelope.

See Pagination for details.

limitintegerrequired

Maximum number of results requested.

offsetintegerrequired

Number of results to skip.

countintegerrequired

Number of results in this response.

totalintegerrequired

Total number of results available.

resultsarrayrequired

Array of result objects.

All errors use a standard structure.

See Errors for the full list of status codes and error types.

Environments

The Storefront API runs in multiple environments with the same contract but different base URLs.

Choose the environment appropriate for your use case.

Live customer traffic with real data. Subject to SLOs, monitoring, and change controls.

Use for:

  • Validating behaviour with feature flags after deployment
  • Investigating production issues with appropriate access

Never run synthetic load tests or use fake customer data against production.

Mirrors production topology. Used for pre-release verification and regression testing.

Use for:

  • End-to-end test scenarios
  • QA and UAT flows
  • Verifying migrations and contract changes

Data may be synthetic or sanitised production records.

Shared integration environment for feature development.

Use for:

  • Testing API changes from feature branches
  • Manual testing from local frontend instances
  • Early integration testing with other teams

Data and configuration may change frequently.

Runs the BFF on http://localhost:8080.

Typical setup:

  • Storefront Next on http://localhost:3000
  • Frontend proxies API calls to localhost:8080

See the storefront-bff README for setup details.

Select the right environment for your task.

Pagination

All top-level API resources have support for bulk fetches through "list" API methods. These list API methods share a common structure and accept, at a minimum, the following parameters: limit and offset.

The Storefront BFF uses offset-based pagination through the limit and offset parameters.

limitinteger

This specifies a limit on the number of objects to return, ranging between 1 and 100. Default is 20.

offsetinteger

The number of results to skip before returning results. Use this to page through results. Default is 0.

limitintegerrequired

The limit that was applied to this request.

offsetintegerrequired

The offset that was applied to this request.

countintegerrequired

The number of results in this response (may be less than limit on the last page).

totalintegerrequired

The total number of results available across all pages.

resultsarrayrequired

An array containing the actual response elements.

To paginate through results:

  1. Make an initial request with your desired limit
  2. Check if offset + count < total to determine if more pages exist
  3. Increment offset by limit for the next page
  4. Repeat until you've retrieved all results
  • Use reasonable page sizes (20-50 items) for optimal performance
  • Cache results where appropriate to reduce API calls
  • Handle the case where total may change between requests (items added/removed)
  • Consider using filtering to reduce result sets before pagination

Filtering

The Storefront BFF provides several filtering mechanisms for collection endpoints.

Many endpoints expose explicit parameters for common filters:

  • Boolean flags: inStock, featured, isDefault
  • Value ranges: minPrice, maxPrice (in cents)
  • Enumerations: status=active|inactive|discontinued
  • Identifiers: category, brand, customerId

Endpoints with search use the query parameter.

The query is passed to the search system and may support stemming, synonyms, and fuzzy matching.

For complex conditions, use the filter parameter with operators.

Operators

OperatorDescription
[eq]Equal (default)
[ne]Not equal
[gt]Greater than
[gte]Greater than or equal
[lt]Less than
[lte]Less than or equal

Combine multiple filter parameters in a single request.

Content endpoints support a locale parameter.

Pattern: ^[a-z]{2}-[A-Z]{2}$ (e.g., en-AU). Default: en-AU.

Invalid filters return 400 Bad Request with details about the invalid parameter.

Headers

Standard HTTP headers used by the Storefront BFF.

Headers to include with your API requests.

Required for any request with a body.

If missing or incorrect, returns 415 Unsupported Media Type.

Customer session token from the login flow.

Required for customer endpoints (cart, orders, profile). See Authentication.

Google Cloud identity token for service-to-service calls.

Used by internal services and batch jobs.

Selects the resource schema version.

Pattern: v{major}.{minor}. Required on requests, echoed in responses.

UUID for correlating logs and traces across services.

Optional. If not provided, the BFF generates one. Reuse the same ID for related requests in a single user flow (e.g., checkout).

Headers returned in API responses.

Sorting

Collection endpoints support sorting via the sort query parameter.

Direction must be asc (ascending) or desc (descending).

Sort by a single field with ascending or descending direction.

Repeat the sort parameter for multiple fields.

Sort is applied in parameter order:

  1. Featured products first
  2. Then by popularity
  3. Then alphabetically by name

Available fields vary by endpoint.

Unsupported sort fields return 400 Bad Request.

Sorting is applied before pagination. Always use the same sort parameters when paginating to maintain stable ordering.

Versioning

The Storefront BFF uses resource versioning to evolve endpoints while preserving client compatibility.

Versions follow vMAJOR.MINOR (e.g., v1.0, v1.1).

Specify the desired version using the X-Api-Version request header.

The response echoes the version used.

The API maintains backward compatibility within a major version.

Non-breaking changes do not require a new API version and may be deployed at any time.

When a major version is deprecated:

  1. At least 6 months notice is provided
  2. Migration guides are published
  3. Sunset dates are communicated via release notes

Continue using the latest stable version to minimize migration effort.

  • Always send X-Api-Version to ensure consistent behaviour
  • Ignore unknown fields in responses (forward compatibility)
  • Subscribe to release notes for deprecation notices
  • Test against staging before upgrading in production

Idempotency

The API supports idempotency for safely retrying requests without performing the same operation twice.

Understand which methods are safe to retry.

These operations can be retried on network failures or 5xx errors:

  • GET, HEAD, OPTIONS - always safe
  • PUT, DELETE - idempotent by design
  • POST - only where explicitly documented

Prefer state-setting operations over action-style operations.

The client sends the desired state. Retries produce the same outcome.

Action endpoints are harder to make safe. Prefer state-setting alternatives.

When actions are necessary, implement them to be retry-safe:

Server behaviour:

  • If confirmable, confirm and return the result
  • If already confirmed, return the same result (not an error)
  • If in an incompatible state, return 4xx

The API does not currently require explicit idempotency keys. If introduced in future, they will:

  • Use an Idempotency-Key header
  • Be scoped to method, path, and principal
  • Store and replay original responses for matching requests

When to retry a request.

Rate Limits

The API applies rate limiting to protect downstream systems and ensure consistent performance.

When you exceed a rate limit, the API returns a 429 status code.

The response may include a Retry-After header indicating how many seconds to wait before retrying.

Rate limits may be applied by:

  • IP address - protects against abusive traffic
  • Customer session - prevents UI loops
  • Service account - for server-to-server integrations
  • Endpoint - expensive operations (e.g., search) may have stricter limits

Exact thresholds are environment-specific and may change without notice.

  • Debounce search and autocomplete requests
  • Cache static data lookups
  • On 429, wait per Retry-After and show a friendly message
  • Don't retry aggressively
  • Implement exponential backoff with jitter: 1s, 2s, 4s, 8s (capped)
  • Reuse HTTP clients with connection pooling
  • Stagger retries after outages to avoid thundering herd

Implement exponential backoff with jitter for production clients.

Rate limits in development and staging may be less strict but can still apply to expensive endpoints like search.

Design your clients to handle 429 gracefully in all environments.