Trade-in widget API and webhooks
Embed the widget, sync statuses with HMAC-SHA256 webhooks, and keep the catalog on FastTradein.
Quick start
Embed the widget with two lines of HTML, then add the store domain to the allow-list. The script talks only to FastTradein, not to your CMS.
Paste this into the HTML of the trade-in page. Replace the key with the public widget key from the workspace (Widget embed page).
<!-- FastTradein Widget -->
<script src="https://fasttradein.app/widget/fasttradein.js" async data-no-optimize="1" data-no-defer="1"></script>
<fasttradein-widget key="YOUR_PUBLIC_KEY" api="https://fasttradein.app" lang="en"></fasttradein-widget>
The snippet sets the api attribute to this FastTradein host. Without it, the widget uses the address the fasttradein.js script was loaded from.
Snippet parameters
| Parameter | Required | Description |
|---|---|---|
| key | Required: Yes | Public widget key from Store settings or the Widget embed page. It can read the catalog, request a quote, and submit a trade-in request. It cannot change prices or open other stores. |
| data-key | Required: No | The same public key as key. React and Vue reserve key and do not pass it to the element, so use data-key there. The widget reads key first, then data-key, and restarts when either changes. |
| lang | Required: No | Starting UI language until the customer switches it: en, de, es, pl, ru, uk. |
| api | Required: No | FastTradein origin, for example https://fasttradein.app. Keep it in the snippet. |
| currency | Required: No | Not an HTML attribute. Display currency (EUR, PLN, UAH, USD, and other workspace currencies) comes from Store settings. Catalog prices stay in EUR and convert at the platform rate. |
Events for conversion tracking
The element dispatches fasttradein:quote when the customer gets a quote and fasttradein:order when a request is sent. Both bubble and cross the shadow DOM (composed), so you can listen on the element or on document. event.detail has device and blocked (quote) or device and payout_method (order), never customer data.
CMS snippets
Setup guides for 111 platforms. Add the store hostname to the widget allow-list before going live.
Showing 111 of 111 platforms
WooCommerce Global
Pages → Trade-in page → Custom HTML block: paste the code on the HTML tab and save the page. For many pages, load the <script> line in the theme footer (Appearance → Editor → Patterns → Footer) or with the WPCode plugin, and keep only the widget tag on the pages.
OpenCart Global
Design → Layouts → add an HTML Content module with the snippet to the trade-in page layout. If you load the <script> line in the footer template instead (catalog/view/theme/<theme>/template/common/footer.twig in OpenCart 3, catalog/view/template/common/footer.twig in OpenCart 4), keep only the <fasttradein-widget …></fasttradein-widget> tag in the module, because the footer appears on every page.
Shopify Global
Online Store → Edit theme: create a page template (Pages → Create template), add a Custom Liquid section with the code, and save. Then choose that template for the trade-in page in Online Store → Pages. If your theme has no Custom Liquid section, paste the code into the page template in the theme code editor.
PrestaShop Global
Install the free FastTradein module: Modules → Module Manager → Upload a module, then Configure and paste the code or the key. Write [fasttradein] on its own line in the content of a page in Design → Pages. PrestaShop does not save <script> in page content and strips the widget tag, so the module puts the widget in when the page is shown.
Magento / Adobe Commerce Global
Content → Elements → Blocks → create a static HTML block and place it via Content → Pages.
Wix Global
Add Elements → Embed Code → Custom Element. Choose Source: Server URL = https://fasttradein.app/widget/fasttradein.js, Tag Name = fasttradein-widget. Set Attributes: data-key = YOUR_PUBLIC_KEY, api = https://fasttradein.app, lang = en. This needs a Premium plan with a connected domain. Do not use Embed HTML: it runs in an iframe on another domain, and the widget will not load there.
BigCommerce Global
Add the script in Storefront → Script Manager and place the <fasttradein-widget> tag through Page Builder (HTML widget).
Squarespace Global
Edit the trade-in page → add a Code block and paste the snippet. Code blocks run JavaScript only on the Core, Plus, Advanced, or Commerce plans, and the widget shows only on the live site.
Shopware 6 Europe
Shopware 6.5 and later strip unknown tags and <script> from editor content. Load the <script> line in your theme’s footer.html.twig. Then allow the fasttradein-widget tag in the shopware.html_sanitizer settings (for example config/packages/z-shopware.yaml), open Content → Shopping Experiences, add a Text element to the trade-in page layout, switch its editor to the HTML code view, and paste only the <fasttradein-widget …></fasttradein-widget> tag.
Ecwid by Lightspeed Global
Instant Site: add a Custom code section on the trade-in page (Venture, Business, or Unlimited plan). On your own site, paste the snippet on the trade-in page next to the Ecwid code.
Webflow Global
Add Elements → Components → Embed (HTML Embed Code) on the trade-in page and publish the site. Code embeds need a paid Site or Workspace plan.
Drupal Commerce Global
Structure → Block layout → add a Custom Block with Full HTML format in the target region or Layout Builder.
Framer Global
Add an Embed component on the canvas, set the type to HTML, and paste the script plus the <fasttradein-widget> tag.
nopCommerce Global
Administration → Content Management → Topics (Pages) → open the trade-in page and paste the snippet in Source code mode.
Salesforce Commerce Cloud Global
Merchant Tools → Content → Content Assets → create an HTML asset and place it in Page Designer.
HubSpot CMS Global
Content → Design Manager → create a custom module with the snippet and add it to the trade-in page, or paste the snippet in the source code view of a rich text module.
Ghost Global
Add an HTML card with the snippet in the trade-in page editor. If you prefer, put only the <script> line in Settings → Code injection → Site footer and keep the <fasttradein-widget …></fasttradein-widget> tag in the HTML card.
Weebly Global
Drag an Embed Code (HTML) element onto the trade-in page and click Edit Custom HTML.
SAP Commerce Cloud Global
SmartEdit → add a CMS Paragraph or Custom HTML component to the trade-in page within WCMS.
Oracle Commerce Global
Design Studio → create a Custom Widget containing the HTML snippet and place it in the target page layout.
Square Online Global
Site Editor → Add section → Embed code → paste the snippet and publish the site. Embed code needs Square Online Plus or Premium.
Volusion Global
Design → Site Designer → add a Custom Code (HTML) block with the snippet on the trade-in page. If you load the <script> line through footer_custom.html, keep only the <fasttradein-widget …></fasttradein-widget> tag in the block.
Shift4Shop Global
Content → Site Pages → Edit Page → toggle the editor to HTML Source mode and paste the code.
NetSuite SuiteCommerce Global
SuiteCommerce Advanced → add a Custom Content CMS block or place the snippet in the theme layout template.
Zoho Commerce Global
Settings → Visual Builder → add an Embed code element onto the trade-in page and save changes.
VTEX Global
VTEX IO / Site Editor → create a custom block or include the widget web component in the Store Framework layout.
Carrd Global
Click + → Embed → set Type to Code and Style to Inline, paste the snippet, and publish. Embeds need Carrd Pro Standard or higher.
Hostinger Global
Website Builder → add an Embed code element and paste the snippet.
MODX Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
GoDaddy Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Miva Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Nuvemshop / Tiendanube Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Cafe24 Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
SHOPLINE Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
thebase Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Salla Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Tray Commerce Global
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Shoper Europe
Ustawienia → Zaawansowane → Bezpieczeństwo (Settings → Advanced → Security): turn on “Wyłącz czyszczenie kodu HTML” (disable HTML cleaning). Then Wygląd i treści → Wygląd sklepu → Obecny szablon graficzny → Moduły → Moduł własny in HTML mode: paste the snippet and place the module on the trade-in page.
IdoSell Europe
Sklep → Dodatki HTML/JS (HTML/JS add-ons): create an add-on, set “Wyświetlaj na podstronach” (show on subpages) to “Wybranych” (selected) with the trade-in page address, and paste the snippet into the HTML code field.
JTL-Shop Europe
JTL-Shop 5 has no built-in field for custom code. Load the <script> line through your child template (layout/footer.tpl, block layout-footer-js) or a header and footer code plugin from the JTL-Store, then put the <fasttradein-widget …></fasttradein-widget> tag on the trade-in page in HTML source mode.
Gambio Europe
Inhalte (Content) → Content Manager → create the trade-in page and switch the editor to HTML source mode.
Sylius Europe
Override templates/bundles/SyliusShopBundle/layout.html.twig (the @SyliusShop/layout.html.twig template) to load the <script> line, and put the <fasttradein-widget …></fasttradein-widget> tag in the trade-in page template.
Lightspeed eCom Europe
Settings → Web Extras → Custom JavaScript / HTML, or paste the code into the theme template.
Spryker Europe
Embed the web component in your Yves storefront Twig template or include the script in the base layout.
Plentymarkets Europe
CMS → Container → insert the widget HTML code into the Ceres template or a custom content block.
OXID eShop Europe
Customer Info → CMS Pages: create the trade-in page and paste the snippet in HTML source mode. If the editor strips the script, load the <script> line in your theme’s base layout (OXID 6: Application/views/<theme>/tpl/layout/base.tpl; OXID 7: the matching Twig template) and keep only the <fasttradein-widget …></fasttradein-widget> tag on the page.
Shoptet Europe
Appearance → HTML codes, or add an HTML block on the trade-in page.
Webnode Europe
Open the trade-in page and add an HTML element with the snippet.
Sky-Shop Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
RedCart Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
AtomStore Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Comarch e-Sklep Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Sote Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Selly Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Unas Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
ShopRenter Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
CloudCart Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
MerchantPro Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Gomag Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
CCV Shop Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Mijnwebwinkel Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
MyOnlineStore Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
modified eCommerce Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
xt:Commerce Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Intershop Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
TYPO3 Europe
Add an HTML content element on the trade-in page, or include the snippet in the site template.
Jimdo Europe
Add an HTML element on the trade-in page and paste the snippet.
ePages Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Vilkas Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
MyCashflow Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
DanDomain Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
SmartWeb Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Abicart Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Starweb Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Jetshop Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Mystore Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
VirtueMart Europe
Joomla article for the trade-in page → source mode. If the editor strips the script, add it in the template and leave the widget tag in the article.
Odoo Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
JouwWeb Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Webador Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Upgates Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
EKM Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Visualsoft Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
IONOS Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Strato Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Mozello Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Litium Europe
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Medusa.js Headless
Load the widget script in the Next.js or Remix storefront layout and add the <fasttradein-widget> web component on the trade-in page. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Saleor Headless
Load the widget script in the storefront (React / Next.js) and use the <fasttradein-widget> web component in JSX. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Vendure Headless
Load the widget script in the client storefront layout and add the <fasttradein-widget> tag on the trade-in page. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
commercetools Headless
Include the widget script in your React, Vue, or Next.js storefront and use the <fasttradein-widget> tag. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Swell Headless
Add the widget script into your Origin / Next.js storefront layout and place the tag on the trade-in page. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Strapi Headless
Embed the web component into the frontend client (Next.js, Nuxt, Remix) consuming your Strapi backend. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Contentful Headless
Place the widget component in your frontend codebase (Next.js, Astro, Gatsby) querying Contentful. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Sanity Headless
Integrate the web component into your portable text blocks or directly into your Next.js / Remix layout. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Next.js Storefront Headless
Load the script with <Script src="https://fasttradein.app/widget/fasttradein.js" strategy="afterInteractive" /> from next/script in app/layout. On the trade-in page render <fasttradein-widget data-key="YOUR_PUBLIC_KEY" api="https://fasttradein.app" lang="en"></fasttradein-widget>. React reserves key and does not pass it to the element, so use data-key. With TypeScript, declare fasttradein-widget in JSX.IntrinsicElements.
Nuxt.js Storefront Headless
Load the script with useHead({ script: [{ src: "https://fasttradein.app/widget/fasttradein.js", defer: true }] }) and mark the tag as a custom element in nuxt.config: vue.compilerOptions.isCustomElement = (tag) => tag === "fasttradein-widget". On the trade-in page add <fasttradein-widget data-key="YOUR_PUBLIC_KEY" api="https://fasttradein.app" lang="en"></fasttradein-widget>. Vue reserves key and does not pass it to the element, so use data-key.
Vue Storefront Headless
Load the widget script in the storefront layout and place the <fasttradein-widget> tag on the trade-in page. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Commerce Layer Headless
Load the widget script in the storefront layout and place the <fasttradein-widget> tag on the trade-in page. In React and Vue, pass the key as data-key: both reserve key and do not pass it to the element.
Django Framework
Add the script in the base template and place the <fasttradein-widget> tag on the trade-in page.
Laravel Framework
Add the script in the Blade layout and place the <fasttradein-widget> tag on the trade-in view.
Ruby on Rails Framework
Add the script in the application layout and place the <fasttradein-widget> tag on the trade-in view.
Symfony Framework
Add the script in the base Twig layout and place the <fasttradein-widget> tag on the trade-in template.
Horoshop Ukraine
Settings → General settings → Scripts: paste the <script> line into the “before the </body> tag” field and save. Then open the trade-in page, switch its description editor to HTML code, and paste the <fasttradein-widget …></fasttradein-widget> tag.
Cartum Ukraine
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
OkayCMS Ukraine
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
SoloMono Ukraine
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
ImageCMS Ukraine
Paste the snippet into the trade-in page in HTML or source mode. If the editor removes the script, put the script in the site header or footer and leave the widget tag on the page.
Prom.ua Ukraine
Prom.ua does not allow your own scripts on a company site, so the widget cannot run there. Put the widget on your own website or landing page and link to that page from your Prom store.
Shop-Express Ukraine
Control panel → Settings → Custom scripts / HTML → paste the code on the trade-in page.
Weblium Ukraine
Site settings → Custom code in Head/Body, or add an Embed code block directly onto the trade-in page. Custom code needs the Weblium Pro plan.
No platforms match this query. Change the search or reset the filter.
Security and domain allow-list
The widget API is public on purpose and still locked to your store. It never exposes workspace login, price editing, or other tenants.
Domain allow-list (CORS / Origin)
These are the websites where your widget may run. Browser calls send Origin or Referer. FastTradein allows only the hostnames saved in Store settings (the Website field and “Websites where the widget works”), plus this FastTradein host. A request from any other site is rejected with 403 Forbidden.
Public widget key
The widgetKey in the URL is a public identifier. It can read the store catalog and submit a trade-in request. It cannot change prices, export other customers’ data, or open the workspace.
Rate limiting
Widget routes allow 120 requests per minute per IP for each store. Search is tighter (20/min). Creating a trade-in request is tighter still: 10 attempts per minute and 10 created requests per day per IP for each store, and 8 per hour per customer email. Over the limit the API returns 429.
Bot protection
The call that creates a trade-in request includes a hidden honeypot field. Automated spam that fills it is dropped, and no request is created. Do not send extra unknown fields from a custom client.
Storefront REST API
Base path: /api/widget/{widgetKey}. These routes are the same public widget surface the storefront script uses. Workspace and platform admin routes are not part of this contract.
Pass locale as a query parameter (?locale=de) to receive catalog names, widget copy, and display amounts in that language. formatted_amount and max_buyback_formatted are ready-made strings for the customer: the amount rounded to whole units, with the currency symbol and digit grouping, for example “€1 235”. Their look depends on the language and the currency. For calculations read the numbers in minor units, cents for the euro: max_buyback and quoted_amount_cents. For example, quoted_amount_cents = 123456 means 1234.56 euros.
/api/widget/{widgetKey}
Store configuration
Returns store name, colors, currency, locale, enabled categories, payout methods, and widget copy.
Example cURL
curl -sS "https://fasttradein.app/api/widget/YOUR_PUBLIC_KEY?locale=en" \
-H "Origin: https://shop.example" \
-H "Accept: application/json"
Example response 200 OK
{
"tenant": {
"name": "Your Store",
"currency": "EUR",
"locale": "en",
"primary_color": "#1f3a8a",
"logo_url": null
},
"locale": "en",
"accepting_orders": true,
"payout_methods": [
{
"value": "bank_transfer",
"label": "Bank transfer"
},
{
"value": "store_credit",
"label": "Store credit toward a purchase"
}
],
"categories": [
{
"id": 1,
"slug": "smartphones",
"name": "Smartphones"
}
],
"catalog_version": "3f9a1c0b7e"
}
/api/widget/{widgetKey}/search?q=iPhone+13
Model search
Looks up models by name. If q is shorter than 2 characters, the response lists up to 6 popular models with "popular": true. Results include the current max buyback for that store. At most 8 hits. Hidden variants are omitted.
Example cURL
curl -sS "https://fasttradein.app/api/widget/YOUR_PUBLIC_KEY/search?q=iPhone+13" \
-H "Origin: https://shop.example" \
-H "Accept: application/json"
Example response 200 OK
{
"results": [
{
"model_id": 42,
"name": "iPhone 13",
"brand": "Apple",
"max_buyback": 42000,
"max_buyback_formatted": "€420"
}
]
}
/api/widget/{widgetKey}/orders
Create a trade-in request
Submit a trade-in request from the widget or your own client. A POST without an Origin or Referer header is refused with 403, so a server or app must send Origin: https://<a domain from your allow-list>. Collect variant_id and answer_ids first. Success is HTTP 201 with order_number.
JSON body
| Field | Required | Description |
|---|---|---|
| variant_id | Required: Yes | Active catalog variant. |
| answer_ids | Required: Yes | Answer IDs from the category questionnaire. One answer per question; a question with multiple set to true takes several, and an answer with exclusive set to true must be the only answer to its question. |
| customer_name | Required: Yes | Customer name. |
| customer_email | Required: Yes | Customer email. |
| customer_phone | Required: No | Optional phone. |
| payout_method | Required: No | bank_transfer or store_credit; store_voucher when the store has vouchers enabled. Without this field the request gets bank_transfer. |
Example cURL
curl -sS -X POST "https://fasttradein.app/api/widget/YOUR_PUBLIC_KEY/orders" \
-H "Origin: https://shop.example" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"variant_id":101,"answer_ids":[11,24],"customer_name":"Ada Lovelace","customer_email":"ada@example.com","customer_phone":"+49 170 000000","payout_method":"bank_transfer"}'
Replace https://shop.example with a domain from your widget allow-list.
Example response 201 Created
{
"order_number": "TF-8PGPFFNLM6",
"quoted_amount_cents": 38000,
"formatted_amount": "€380",
"currency": "EUR",
"status": "submitted"
}
Other public widget routes
Needed to collect variant_id and answer_ids before POST /orders. Same key, same CORS rules.
-
GET
/api/widget/{widgetKey}/catalog/{category}Brands, models, and storage variants for a category (id or slug). -
GET
/api/widget/{widgetKey}/questionnaire/{category}Checklist groups, questions, and answer IDs for that category. multiple marks a question that takes several answers, exclusive an answer that must be the only one for its question. -
POST
/api/widget/{widgetKey}/quotesPrice the variant with the selected answers before creating a trade-in request. JSON body: variant_id, answer_ids.
Webhooks
Webhooks are available on the Business and Pro plans. In the workspace open Settings → CRM webhooks, enter your HTTPS URL, and generate the secret key. FastTradein then POSTs JSON there for the events below, so you can sync any CRM or ERP.
Events
-
order.createdThe customer submitted a request from the widget. -
order.receivedThe store marked the device as arrived at the warehouse. -
order.counter_offeredWarehouse inspection changed the payout. The customer received a protected offer link. -
order.paidThe store marked the request as paid. -
order.acceptedThe customer accepted the new price after inspection. -
order.declinedThe request ended without a deal: the customer declined the new price, the device was locked at inspection, or the store declined the device at intake. data.status is declined or cancelled.
JSON payload
The body is compact JSON (unescaped slashes and Unicode). Verify HMAC-SHA256 against these exact bytes. order_number is a string such as TF-8PGPFFNLM6, and event_id is evt_ followed by a UUID. The voucher_* fields are filled for store voucher requests once the voucher is issued; otherwise they are null.
{
"event": "order.created",
"event_id": "evt_c800a9c7-b11c-4b75-810e-e667544d825d",
"timestamp": 1788550000,
"tenant_id": 12,
"data": {
"order_number": "TF-8PGPFFNLM6",
"status": "submitted",
"currency": "EUR",
"quoted_amount_cents": 38000,
"inspected_amount_cents": null,
"final_amount_cents": null,
"device": "Apple iPhone 13 128GB",
"customer": {
"name": "Ada Lovelace",
"email": "ada@example.com",
"phone": "+49 170 000000"
},
"parcel_tracking_number": null,
"payout_method": "bank_transfer",
"voucher_code": null,
"voucher_amount_cents": null,
"voucher_url": null,
"voucher_expires_at": null
}
}
Headers
X-FastTradein-Event: Event name, same as payload.event.X-FastTradein-Signature: HMAC-SHA256, HMAC of the raw body, prefixed with sha256=.User-Agent: FastTradein-Webhook/1.0
Answer with any 2xx status within 10 seconds. Any other status, a timeout, or a redirect counts as a failure, and we retry twice, after 10 and after 60 seconds, with the same event_id and signature. Redirects are not followed, so save the final https address. Use event_id to skip duplicates.
Verify HMAC-SHA256
Compute HMAC-SHA256 over the raw POST body with your workspace secret. Compare it to X-FastTradein-Signature with a constant-time check. The header value starts with sha256=.
PHP
$signature = $_SERVER['HTTP_X_FASTTRADEIN_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input');
$expected = 'sha256='.hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
Node.js
const crypto = require('crypto');
const express = require('express');
const app = express();
// express.raw keeps the exact POST bytes; JSON.stringify(req.body) would not match the signature.
app.post('/fasttradein-webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = String(req.get('X-FastTradein-Signature') || '');
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.FASTTRADEIN_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (
signature.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))
) {
return res.status(401).end('Invalid signature');
}
const event = JSON.parse(req.body.toString('utf8'));
// Skip an event_id you have already processed: a retry sends the same one.
res.status(200).end();
});
Status codes
| Code | Meaning |
|---|---|
| 200 | OK. GET returns the config, search results, catalog, and questionnaire; POST /quotes returns the quote. |
| 201 | Created. POST /orders succeeded; read order_number in the JSON. |
| 402 | The store cannot take new widget requests right now: the trial has ended or the subscription is canceled (TENANT_BILLING_INACTIVE), or this month’s request limit is used up (TENANT_LIMIT_EXCEEDED). |
| 403 | Domain not allowed: Origin / Referer is not on the store allow-list (error WIDGET_DOMAIN_DENIED), or a POST came without either header. |
| 404 | Unknown widget key (error WIDGET_NOT_FOUND), category, or request number. |
| 422 | Validation error: missing answers, an inactive variant, or a disabled category. |
| 429 | Rate limit exceeded. Slow down and retry. |