# Elara One > Elara One is commerce, CRM, automation and customer conversations in one platform: one customer record, one admin and one REST API. Bring your own storefront (headless) or start from the MIT-licensed Next.js, Nuxt or Astro + Alpine starters. The API base URL is https://api.elaraone.app/api/v1; every call carries the store key in X-Tenant-Key and server calls also carry X-Tenant-Secret. Money is always { amount, currency, formatted } with amount in minor units (pence). Every docs page is also available as Markdown at its URL plus `.md`. The full docs in one file: https://elaraone.app/llms-full.txt ## Get started - [Introduction](https://elaraone.app/docs/introduction.md): What Elara One is, how a store and its keys fit together, and where to start building. - [Quickstart](https://elaraone.app/docs/quickstart.md): Call the API with your store key, list products, create a cart, add a line and take a test payment, in about five minutes. - [Authentication](https://elaraone.app/docs/authentication.md): The store key, the server secret, registered websites, bearer tokens for customers and merchant integrations, and how to rotate credentials. - [Choosing a starter](https://elaraone.app/docs/starters.md): Three starter storefronts, in Next.js, Nuxt and Astro + Alpine. What they share, how they differ and how to run one. ## Concepts - [Stores and API keys](https://elaraone.app/docs/concepts/stores-and-keys.md): How the API knows which store you mean, the public store key and server secret, registered websites, and how to rotate credentials safely. - [Money](https://elaraone.app/docs/concepts/money.md): How the API represents prices and totals as integer minor units, how to display them, and how tax-inclusive and tax-exclusive prices are labelled. - [Catalogue](https://elaraone.app/docs/concepts/catalogue.md): Products, variants, options, collections, images and prices, and how to filter, sort, include and page through the product list. - [Carts and the cart token](https://elaraone.app/docs/concepts/carts.md): Create a cart, add and change lines, apply coupons, set addresses and shipping, and read totals, tax, gifts and nudges. - [Checkout and orders](https://elaraone.app/docs/concepts/checkout.md): 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. - [Customer accounts](https://elaraone.app/docs/concepts/customers.md): Register and sign in shoppers with bearer tokens, verify email, reset passwords, manage the address book, show order history and delete an account. - [Payments](https://elaraone.app/docs/concepts/payments.md): Take card payments through the store's own Stripe account and PayPal, handle test and live mode, and turn declines into clear messages. - [Search](https://elaraone.app/docs/concepts/search.md): Results pages, instant search suggestions, the merchant's search settings, the anonymous search events beacon, synonyms and search rate limits. - [Responses and errors](https://elaraone.app/docs/concepts/errors.md): The success and error envelopes, every error code with its HTTP status and what to do, the shape of validation errors, and which errors to retry. - [Pagination](https://elaraone.app/docs/concepts/pagination.md): Page through lists with page and perPage, read links and meta, use cursors on merchant lists, and sync CRM records incrementally with filter[updated_since]. - [Idempotency keys](https://elaraone.app/docs/concepts/idempotency.md): Retry requests that change things without doing them twice, which routes accept an Idempotency-Key, and how to generate keys and retry safely. - [Rate limits](https://elaraone.app/docs/concepts/rate-limits.md): The request budgets per store and per caller, the rate-limit headers, per-shopper limits with X-Client-IP, and how to back off on 429. - [Versioning and changes](https://elaraone.app/docs/concepts/versioning.md): How the API is versioned, which changes we treat as breaking and which as additive, how to write clients that keep working, and where changes are announced. ## Guides - [Build a product listing page](https://elaraone.app/docs/guides/product-listing.md): List products with collection, price and attribute filters, sorting, pagination and promotion badges, rendered on your server. - [Checkout with Stripe](https://elaraone.app/docs/guides/stripe-checkout.md): Take a card payment end to end, from cart to placed order, with the Stripe Payment Element and exactly-once order placement. - [Add customer accounts](https://elaraone.app/docs/guides/customer-accounts.md): Sign-up, sign-in, email verification, password reset, address book, order history and account deletion for shoppers. - [Lead forms](https://elaraone.app/docs/guides/lead-forms.md): Render a store form from its schema, submit it safely with spam protection and consent, and know what happens to each lead. - [Web chat](https://elaraone.app/docs/guides/web-chat.md): Add a live chat widget to your storefront that talks to the store's inbox, for guests and signed-in shoppers. - [Flows](https://elaraone.app/docs/guides/flows.md): Automation flows from a developer's point of view, including triggers, actions, the webhook action, loop protection, consent and the merchant API. - [Cookie consent under PECR](https://elaraone.app/docs/guides/cookie-consent.md): Ask for, record and honour a shopper's cookie choices on a headless storefront, with the banner and cookie table served by the API. - [SEO for headless storefronts](https://elaraone.app/docs/guides/seo.md): Server rendering, slugs, CMS page metadata, redirects, canonical URLs, structured data, sitemaps and not-found handling with the Elara One API. ## Webhooks - [CRM change webhooks](https://elaraone.app/docs/webhooks.md): Get a signed HTTPS request whenever a contact, company, task or lead changes in a store's CRM, with ids and field names only. - [Verify signatures](https://elaraone.app/docs/webhooks/verify-signatures.md): Check the X-ElaraOne-Signature header on every CRM webhook, with tested examples for Node, Express, Next.js, PHP and Laravel. - [Retries and delivery](https://elaraone.app/docs/webhooks/retries.md): How CRM webhooks are delivered at least once, retried with backoff, switched off when failing, and sent again from the delivery log. ## API reference: overview - [API reference](https://elaraone.app/docs/api.md): Every Storefront API and Merchant API endpoint, generated from the engine's own OpenAPI document. ## Storefront API - [Check the API](https://elaraone.app/docs/api/storefront/health/check-the-api.md) - [List products](https://elaraone.app/docs/api/storefront/catalogue/list-products.md) - [Get price bounds](https://elaraone.app/docs/api/storefront/catalogue/get-price-bounds.md) - [Get a product](https://elaraone.app/docs/api/storefront/catalogue/get-a-product.md) - [List collections](https://elaraone.app/docs/api/storefront/catalogue/list-collections.md) - [Get a collection](https://elaraone.app/docs/api/storefront/catalogue/get-a-collection.md) - [List products in a collection](https://elaraone.app/docs/api/storefront/catalogue/list-products-in-a-collection.md) - [List promotions](https://elaraone.app/docs/api/storefront/catalogue/list-promotions.md) - [List countries](https://elaraone.app/docs/api/storefront/catalogue/list-countries.md) - [Search products](https://elaraone.app/docs/api/storefront/search/search-products.md): Full product cards for a results page. For the same `q` and `locale` with no filters, `meta.total` equals the suggest endpoint's `data.products.total`. An empty `q` with a filter is a browse (e.g. every product with a tag). `meta.facets` counts the store's facets (Meilisearch only; empty on the database fallback), `meta.facet_labels` names them and `meta.facet_value_labels` names identifier values (`brand_slug` => brand names). Prices in filters are integer minor units of `meta.currency`. Every 200 carries `X-Search-Total` (equal to `meta.total`) and a fresh `X-Search-Id` header (a ULID) for click beacons, cached body or not. - [Get search suggestions](https://elaraone.app/docs/api/storefront/search/get-search-suggestions.md): Grouped suggestions for the typed query: products, collections, brands, tags, CMS pages and posts (only the groups asked for in `types` that the store has enabled, each with its merchant limit). `*_html` fields are escaped text plus ``/`` only. Below the store's `min_chars` the answer is 200 with empty groups; with search switched off it is 200 with no groups and `meta.search_engine: "disabled"`. When Meilisearch is unavailable the answer is still 200: products from the database, the other groups empty, `meta.search_engine: "database"`, `Cache-Control: no-store, private` (never cached). A searched answer carries `X-Search-Total` (products total) and a fresh `X-Search-Id` (ULID) for the search beacons, even when served from the response cache (kept 300 s, dropped on every index write). - [Get search settings](https://elaraone.app/docs/api/storefront/search/get-search-settings.md): The store's public instant-search settings for one locale: autocomplete limits and timing, appearance, overlay, voice and analytics switches, and the localised placeholder and no-results text. `meta.version` changes on every settings save (clear any suggestion cache then). Cache it for 60 s; revalidate with `If-None-Match` for a bodyless `304`. - [Record search events](https://elaraone.app/docs/api/storefront/search/record-search-events.md): Reports, in batches of 1–20, what the shopper did with search answers: `settled` (a suggest answer they stopped at: it becomes a counted search), `click` and `add_to_cart`. Each event names the answer by its `X-Search-Id`; the engine takes the query and the totals from its own 15-minute record of that answer, so the client never sends query text, counts or anything personal. Events for an unknown or expired search id, a repeated `settled`, a `settled` for a results page, or a click on something the answer cannot have shown are dropped silently: every well-formed batch is `202`. Never retry a failed beacon. - [Create a cart](https://elaraone.app/docs/api/storefront/cart/create-a-cart.md) - [Get the cart](https://elaraone.app/docs/api/storefront/cart/get-the-cart.md) - [Add a line](https://elaraone.app/docs/api/storefront/cart/add-a-line.md) - [Update a line](https://elaraone.app/docs/api/storefront/cart/update-a-line.md) - [Remove a line](https://elaraone.app/docs/api/storefront/cart/remove-a-line.md) - [Apply a coupon](https://elaraone.app/docs/api/storefront/cart/apply-a-coupon.md) - [Remove the coupon](https://elaraone.app/docs/api/storefront/cart/remove-the-coupon.md) - [Set addresses](https://elaraone.app/docs/api/storefront/cart/set-addresses.md) - [List shipping options](https://elaraone.app/docs/api/storefront/cart/list-shipping-options.md) - [Choose a shipping option](https://elaraone.app/docs/api/storefront/cart/choose-a-shipping-option.md) - [Get checkout settings](https://elaraone.app/docs/api/storefront/checkout/get-checkout-settings.md) - [Create a Stripe PaymentIntent](https://elaraone.app/docs/api/storefront/checkout/create-a-stripe-paymentintent.md) - [Create a PayPal order](https://elaraone.app/docs/api/storefront/checkout/create-a-paypal-order.md) - [Capture a PayPal order](https://elaraone.app/docs/api/storefront/checkout/capture-a-paypal-order.md) - [Complete checkout](https://elaraone.app/docs/api/storefront/checkout/complete-checkout.md) - [Look up a guest order](https://elaraone.app/docs/api/storefront/orders/look-up-a-guest-order.md) - [Get a guest order](https://elaraone.app/docs/api/storefront/orders/get-a-guest-order.md) - [List the customer's orders](https://elaraone.app/docs/api/storefront/orders/list-the-customers-orders.md) - [Get an order](https://elaraone.app/docs/api/storefront/orders/get-an-order.md) - [Register a customer](https://elaraone.app/docs/api/storefront/customers/register-a-customer.md): Returns a bearer token straight away; verification is not required to use it. A queued verification email linking to the store's storefront verify page is sent once, or none when the store has not set its verify-email URL in Store settings. - [Log in](https://elaraone.app/docs/api/storefront/customers/log-in.md) - [Log out](https://elaraone.app/docs/api/storefront/customers/log-out.md) - [Get the signed-in customer](https://elaraone.app/docs/api/storefront/customers/get-the-signed-in-customer.md) - [Update the profile](https://elaraone.app/docs/api/storefront/customers/update-the-profile.md) - [Request a password reset](https://elaraone.app/docs/api/storefront/customers/request-a-password-reset.md) - [Reset a password](https://elaraone.app/docs/api/storefront/customers/reset-a-password.md) - [Change the password](https://elaraone.app/docs/api/storefront/customers/change-the-password.md) - [Verify an email address](https://elaraone.app/docs/api/storefront/customers/verify-an-email-address.md) - [Resend the verification email](https://elaraone.app/docs/api/storefront/customers/resend-the-verification-email.md) - [List addresses](https://elaraone.app/docs/api/storefront/customers/list-addresses.md) - [Add an address](https://elaraone.app/docs/api/storefront/customers/add-an-address.md) - [Update an address](https://elaraone.app/docs/api/storefront/customers/update-an-address.md) - [Delete an address](https://elaraone.app/docs/api/storefront/customers/delete-an-address.md) - [Delete the account](https://elaraone.app/docs/api/storefront/customers/delete-the-account.md) - [Get a form](https://elaraone.app/docs/api/storefront/forms/get-a-form.md) - [Submit a form](https://elaraone.app/docs/api/storefront/forms/submit-a-form.md) - [List pages](https://elaraone.app/docs/api/storefront/content/list-pages.md) - [Get a page](https://elaraone.app/docs/api/storefront/content/get-a-page.md) - [Resolve a redirect](https://elaraone.app/docs/api/storefront/content/resolve-a-redirect.md) - [Get the consent in force](https://elaraone.app/docs/api/storefront/consent-and-privacy/get-the-consent-in-force.md): The shopper's consent now: what may be used (`categories`), the Google Consent Mode v2 signals, whether to show the banner (and why), and the current banner to render. Everything is denied until the shopper chooses, after 12 months, and after a change of purpose or a new major storage register version, until they answer again. Call it from the storefront server with the shopper's `sid`, `vid` and `consent` cookie values; send none of them and the answer is "no choice yet". - [Record a consent choice](https://elaraone.app/docs/api/storefront/consent-and-privacy/record-a-consent-choice.md): Records the shopper's choice from the banner, the "Cookie settings" link or the account page: a new consent record (the previous one is kept, marked superseded). Withdrawing is the same call with the category set to false. Answers `201` with the consent now in force, like `GET consent`, plus `consent_token`: keep it in the HttpOnly `consent` cookie for 12 months and forward it as `X-Consent-Token` from then on. A visitor id (`X-Visitor-Id`) is linked only when analytics is granted. - [Get the cookie table](https://elaraone.app/docs/api/storefront/consent-and-privacy/get-the-cookie-table.md): Every identifier the store's analytics and conversion tracking keep, on the device or on the servers, with its purpose, lifetime, consent category and when it is deleted; the ad click IDs and their windows; what is never used; and the register's version history. Render it as the store's cookie table (the page the consent banner links to). `register_version` is the version consent records store. Cache it for 5 minutes; revalidate with `If-None-Match` for a bodyless `304`. - [Confirm marketing consent](https://elaraone.app/docs/api/storefront/consent-and-privacy/confirm-marketing-consent.md) - [Get chat settings](https://elaraone.app/docs/api/storefront/chat/get-chat-settings.md) - [Start a conversation](https://elaraone.app/docs/api/storefront/chat/start-a-conversation.md) - [Get the conversation](https://elaraone.app/docs/api/storefront/chat/get-the-conversation.md) - [Send a message](https://elaraone.app/docs/api/storefront/chat/send-a-message.md) ## Merchant API - [List contacts](https://elaraone.app/docs/api/merchant/crm/list-contacts.md) - [Create a contact](https://elaraone.app/docs/api/merchant/crm/create-a-contact.md) - [Get a contact](https://elaraone.app/docs/api/merchant/crm/get-a-contact.md) - [Update a contact](https://elaraone.app/docs/api/merchant/crm/update-a-contact.md) - [List companies](https://elaraone.app/docs/api/merchant/crm/list-companies.md) - [Create a company](https://elaraone.app/docs/api/merchant/crm/create-a-company.md) - [Get a company](https://elaraone.app/docs/api/merchant/crm/get-a-company.md) - [Update a company](https://elaraone.app/docs/api/merchant/crm/update-a-company.md) - [Delete a company](https://elaraone.app/docs/api/merchant/crm/delete-a-company.md) - [List tasks](https://elaraone.app/docs/api/merchant/crm/list-tasks.md) - [Create a task](https://elaraone.app/docs/api/merchant/crm/create-a-task.md) - [Get a task](https://elaraone.app/docs/api/merchant/crm/get-a-task.md) - [Update a task](https://elaraone.app/docs/api/merchant/crm/update-a-task.md) - [Complete a task](https://elaraone.app/docs/api/merchant/crm/complete-a-task.md) - [Cancel a task](https://elaraone.app/docs/api/merchant/crm/cancel-a-task.md) - [Reopen a task](https://elaraone.app/docs/api/merchant/crm/reopen-a-task.md) - [Get field history](https://elaraone.app/docs/api/merchant/crm/get-field-history.md) - [List a record's associations](https://elaraone.app/docs/api/merchant/crm/list-a-records-associations.md) - [Associate two records](https://elaraone.app/docs/api/merchant/crm/associate-two-records.md) - [Remove an association](https://elaraone.app/docs/api/merchant/crm/remove-an-association.md) - [List notes](https://elaraone.app/docs/api/merchant/crm/list-notes.md) - [Add a note](https://elaraone.app/docs/api/merchant/crm/add-a-note.md) - [Update a note](https://elaraone.app/docs/api/merchant/crm/update-a-note.md) - [Delete a note](https://elaraone.app/docs/api/merchant/crm/delete-a-note.md) - [List lifecycle stages](https://elaraone.app/docs/api/merchant/crm/list-lifecycle-stages.md) - [List custom fields](https://elaraone.app/docs/api/merchant/crm/list-custom-fields.md) - [List association labels](https://elaraone.app/docs/api/merchant/crm/list-association-labels.md) - [List orders](https://elaraone.app/docs/api/merchant/orders/list-orders.md) - [Dispatch an order](https://elaraone.app/docs/api/merchant/orders/dispatch-an-order.md) - [Mark an order delivered](https://elaraone.app/docs/api/merchant/orders/mark-an-order-delivered.md) - [Record an offline refund](https://elaraone.app/docs/api/merchant/orders/record-an-offline-refund.md) - [List forms](https://elaraone.app/docs/api/merchant/forms/list-forms.md) - [Save a form](https://elaraone.app/docs/api/merchant/forms/save-a-form.md) - [List flows](https://elaraone.app/docs/api/merchant/flows/list-flows.md) - [Save a flow](https://elaraone.app/docs/api/merchant/flows/save-a-flow.md) - [List pages](https://elaraone.app/docs/api/merchant/pages/list-pages.md) - [Create a page](https://elaraone.app/docs/api/merchant/pages/create-a-page.md) - [Get a page](https://elaraone.app/docs/api/merchant/pages/get-a-page.md) - [Save a draft](https://elaraone.app/docs/api/merchant/pages/save-a-draft.md) - [Publish a page](https://elaraone.app/docs/api/merchant/pages/publish-a-page.md) - [Unpublish a page](https://elaraone.app/docs/api/merchant/pages/unpublish-a-page.md) - [Roll back a page](https://elaraone.app/docs/api/merchant/pages/roll-back-a-page.md) - [Create a preview link](https://elaraone.app/docs/api/merchant/pages/create-a-preview-link.md) - [List conversations](https://elaraone.app/docs/api/merchant/conversations/list-conversations.md) - [Get the consent banner](https://elaraone.app/docs/api/merchant/consent/get-the-consent-banner.md) - [Publish the consent banner](https://elaraone.app/docs/api/merchant/consent/publish-the-consent-banner.md): Sends the whole banner. Any change to the wording, categories, links or privacy notice version publishes a new, immutable version (`201`); an identical banner publishes nothing (`200`, the current version). Shoppers are asked again only when the banner offers a new category or the new privacy notice version is marked `notice_purpose_change`. - [Get a consent record](https://elaraone.app/docs/api/merchant/consent/get-a-consent-record.md): One consent record: the choice, where and when it was made, the banner, privacy notice and storage register versions in force, whether it was replaced, and the banner version exactly as the shopper saw it. `404 NOT_FOUND` for an unknown id or a record removed by retention. ## Site - [Home](https://elaraone.app/): What Elara One is and who it is for - [Pricing](https://elaraone.app/pricing): Plans and prices, in GBP excluding VAT - [Developers](https://elaraone.app/developers): The API, starters and tooling - [Starters](https://elaraone.app/starters): Starter storefronts for Next.js, Nuxt and Astro + Alpine - [Changelog](https://elaraone.app/changelog): What shipped, newest first - [Security](https://elaraone.app/security): How customer data is protected - [Contact](https://elaraone.app/contact): Book a demo or ask a question