Bestellingen & offertes
Offerteaanvragen
Een winkelwagen indienen als B2B-offerteaanvraag (RFQ), de offertestatusflow, en de klantgerichte offertevorm.
Bekijk als MarkdownMet de offerteflow (RFQ) kan een koper een winkelwagen bij de merchant indienen voor een geprijsd aanbod in plaats van direct te betalen. Deze is alleen beschikbaar wanneer de winkel de sales-module heeft ingeschakeld en offerteaanvragen aan heeft staan in de instellingen; op een winkel zonder een van beide retourneert het endpoint 404. Bepaalde winkelwagens moeten via deze flow: wanneer een quote trigger afgaat, weigert de checkout met 409 QUOTE_REQUIRED en is het veld requires_quote van de winkelwagen true.
Met de offerteflow (RFQ) kan een koper een winkelwagen bij de merchant indienen voor een geprijsd aanbod in plaats van direct te betalen. Deze is alleen beschikbaar wanneer de winkel de sales-module heeft ingeschakeld en offerteaanvragen aan heeft staan in de instellingen; op een winkel zonder een van beide retourneert het endpoint 404. Bepaalde winkelwagens moeten via deze flow: wanneer een quote trigger afgaat, weigert de checkout met 409 QUOTE_REQUIRED en is het veld requires_quote van de winkelwagen true.
Offertestatusflow
| Status | Betekenis |
|---|---|
submitted | Aangemaakt door dit endpoint. De winkelwagen is geconverteerd; de merchant ziet de aanvraag. |
offered | De merchant heeft de regels geprijsd en het aanbod verzonden. Totalen zijn bevroren en een accept token van 48 tekens is per e-mail naar de koper gestuurd (alleen de SHA-256-hash ervan wordt server-side opgeslagen). |
accepted | De koper heeft geaccepteerd via het token. Er is een bestelling aangemaakt tegen de geoffreerde prijzen; converted_order_id is gezet. Terminaal. |
declined | De koper heeft afgewezen via het token. De merchant kan nog opnieuw een aanbod doen of annuleren. |
expired | Een aangeboden offerte waarvan valid_until is verstreken, klapt lazy om naar expired bij de eerstvolgende token- of merchant-actie. |
cancelled | Geannuleerd door de merchant (mogelijk vanuit submitted, offered, declined, expired). Terminaal. |
Accepteren en afwijzen gebeurt via de token-endpoints (zie de pagina Offertetokens).
Offertestatusflow
| Status | Betekenis |
|---|---|
submitted | Aangemaakt door dit endpoint. De winkelwagen is geconverteerd; de merchant ziet de aanvraag. |
offered | De merchant heeft de regels geprijsd en het aanbod verzonden. Totalen zijn bevroren en een accept token van 48 tekens is per e-mail naar de koper gestuurd (alleen de SHA-256-hash ervan wordt server-side opgeslagen). |
accepted | De koper heeft geaccepteerd via het token. Er is een bestelling aangemaakt tegen de geoffreerde prijzen; converted_order_id is gezet. Terminaal. |
declined | De koper heeft afgewezen via het token. De merchant kan nog opnieuw een aanbod doen of annuleren. |
expired | Een aangeboden offerte waarvan valid_until is verstreken, klapt lazy om naar expired bij de eerstvolgende token- of merchant-actie. |
cancelled | Geannuleerd door de merchant (mogelijk vanuit submitted, offered, declined, expired). Terminaal. |
Accepteren en afwijzen gebeurt via de token-endpoints (zie de pagina Offertetokens).
Quote triggers
Wanneer de winkel de sales-module heeft ingeschakeld en offerteaanvragen aan heeft staan, dwingen deze condities een winkelwagen in de RFQ-flow. Anders gaat er geen trigger af, blijft requires_quote false en weigert de checkout nooit met QUOTE_REQUIRED. Ze verschijnen live op elke winkelwagenrespons als requires_quote en quote_reasons:
| Reden | Gaat af wanneer |
|---|---|
cart_threshold | Het winkelwagentotaal bereikt het geconfigureerde drempelbedrag, of de som van de hoeveelheden bereikt de drempelhoeveelheid. |
configurator_choice | Een gekozen configurator-optiekeuze is gemarkeerd als offerteplichtig. |
customer_group | De contactgroep van de klant staat op altijd offreren (een sales-instelling op de groep). |
product_purchasability | Een product in de winkelwagen heeft purchasability quote. Zo'n product kan nog steeds aan een winkelwagen worden toegevoegd; de winkelwagen meldt dan deze reden en gaat via dit endpoint in plaats van de checkout. |
Een offerteaanvraag indienen is ook toegestaan voor winkelwagens die geen enkele trigger raken; de koper kan altijd om een aanbod vragen.
Quote triggers
Wanneer de winkel de sales-module heeft ingeschakeld en offerteaanvragen aan heeft staan, dwingen deze condities een winkelwagen in de RFQ-flow. Anders gaat er geen trigger af, blijft requires_quote false en weigert de checkout nooit met QUOTE_REQUIRED. Ze verschijnen live op elke winkelwagenrespons als requires_quote en quote_reasons:
| Reden | Gaat af wanneer |
|---|---|
cart_threshold | Het winkelwagentotaal bereikt het geconfigureerde drempelbedrag, of de som van de hoeveelheden bereikt de drempelhoeveelheid. |
configurator_choice | Een gekozen configurator-optiekeuze is gemarkeerd als offerteplichtig. |
customer_group | De contactgroep van de klant staat op altijd offreren (een sales-instelling op de groep). |
product_purchasability | Een product in de winkelwagen heeft purchasability quote. Zo'n product kan nog steeds aan een winkelwagen worden toegevoegd; de winkelwagen meldt dan deze reden en gaat via dit endpoint in plaats van de checkout. |
Een offerteaanvraag indienen is ook toegestaan voor winkelwagens die geen enkele trigger raken; de koper kan altijd om een aanbod vragen.
De klantgerichte offertevorm
Het offerteaanvraag-endpoint en beide token-read-endpoints retourneren dezelfde envelope: {"data": {...quote...}}. Dit is de klantgerichte serialisatie: merchant_note, cart_id, customer_id en contact_id zijn nooit aanwezig, en het accept token (of de hash ervan) wordt nooit blootgesteld. Het offerte-object bevat ook origin ("storefront" voor een offerte die hier is aangemaakt), intro, terms, signed_at, acceptance_mode, pdf_url en signed_pdf_url, gedocumenteerd op de pagina Offertetokens. Anders dan bij winkelwagen- en bestelresponses zijn alle offertebedragen kale integers in minor units, geen money-objecten. Datums zijn ISO-8601-strings.
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
id | string (UUID) | altijd | Offerte-id. |
number | string | altijd | Klantgericht offertenummer, "Q-" plus een integer per winkel, bijvoorbeeld "Q-17". |
status | string | altijd | Zie de statustabel hierboven. |
email | string | altijd | E-mailadres van de aanvrager. |
name | string | altijd | Naam van de aanvrager. |
phone | string of null | altijd | Telefoonnummer van de aanvrager. |
billing_address | object of null | altijd | Zoals ingediend. |
shipping_address | object of null | altijd | Zoals ingediend. |
currency | string | altijd | EUR. |
customer_note | string of null | altijd | De notitie van de koper uit de aanvraag. |
message_to_customer | string of null | altijd | Het bericht van de merchant, gezet bij het aanbieden. |
valid_until | string (ISO-8601) of null | altijd | Vervaldatum van het aanbod, gezet bij het aanbieden. |
subtotal_amount | integer of null | altijd | Bevroren op het moment van aanbieden; null zolang submitted. Minor units. |
tax_total_amount | integer of null | altijd | Bevroren op het moment van aanbieden; null zolang submitted. |
shipping_total_amount | integer of null | altijd | Bevroren op het moment van aanbieden; null zolang submitted. |
total_amount | integer of null | altijd | Bevroren op het moment van aanbieden; null zolang submitted. |
tax_breakdown | array of null | altijd | Uitsplitsing per tarief {"rate": float, "base": int, "tax": int}; null zolang submitted. |
converted_order_id | string (UUID) of null | altijd | De bestelling die bij acceptatie is aangemaakt, anders null. |
submitted_at | string (ISO-8601) of null | altijd | Wanneer de aanvraag is ingediend. |
offered_at | string (ISO-8601) of null | altijd | Wanneer de merchant het aanbod heeft verzonden. |
accepted_at | string (ISO-8601) of null | altijd | Wanneer de koper heeft geaccepteerd. |
declined_at | string (ISO-8601) of null | altijd | Wanneer de koper heeft afgewezen. |
cancelled_at | string (ISO-8601) of null | altijd | Wanneer de merchant heeft geannuleerd. |
created_at | string (ISO-8601) of null | altijd | Aanmaaktijd van de rij. |
updated_at | string (ISO-8601) of null | altijd | Laatste wijzigingstijd. |
lines | array | altijd | Offerteregels, zie hieronder. |
lines[]
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
id | string (UUID) | altijd | Offerteregel-id. |
product_id | string (UUID) of null | altijd | Het product; null voor custom regels die de merchant heeft toegevoegd. |
variant_id | string (UUID) of null | altijd | De variant, indien van toepassing. |
is_custom | boolean | altijd | True voor door de merchant toegevoegde custom regels. |
title | string | altijd | Regeltitel (productnaam-snapshot, of vrije tekst voor custom regels). |
sku | string of null | altijd | SKU-snapshot. |
quantity | number | altijd | Hoeveelheid, overgenomen van de winkelwagenregel: een geheel getal voor een product dat per piece verkocht wordt, tot drie decimalen voor elke andere eenheid (bijvoorbeeld 0.75). Dienst- en materiaalregels van de merchant kunnen ook decimalen hebben. |
indicative_unit_price | integer of null | altijd | Stukprijs (minor units), gesnapshot uit de prijscontext van de aanvrager op het moment van indienen. |
quoted_unit_price | integer of null | altijd | De geoffreerde stukprijs van de merchant; null totdat er geprijsd is. |
tax_class_id | string (UUID) of null | altijd | Btw-klasse die de merchant heeft toegewezen, indien aanwezig. |
attributes | object of null | altijd | Configuratie-snapshot voor configureerbare regels, anders null. |
sort_order | integer | altijd | Weergavevolgorde. |
kind | string | altijd | product voor regels die uit een winkelwagen zijn gemaakt; regels van de merchant kunnen service, material of other zijn. |
unit | string of null | altijd | Eenheidslabel. Een regel uit een winkelwagen heeft pcs voor een product dat per piece verkocht wordt en anders de eenheid van het product (kg, m2, hour, ...). |
description | string of null | altijd | Optionele notitie op regelniveau. |
tax_rate | string of null | altijd | Decimaal btw-tarief, vastgelegd wanneer de merchant het aanbod verstuurt (bijvoorbeeld "21.00"); tot dan null. |
unit_price | integer of null | altijd | Alias van quoted_unit_price. |
De klantgerichte offertevorm
Het offerteaanvraag-endpoint en beide token-read-endpoints retourneren dezelfde envelope: {"data": {...quote...}}. Dit is de klantgerichte serialisatie: merchant_note, cart_id, customer_id en contact_id zijn nooit aanwezig, en het accept token (of de hash ervan) wordt nooit blootgesteld. Het offerte-object bevat ook origin ("storefront" voor een offerte die hier is aangemaakt), intro, terms, signed_at, acceptance_mode, pdf_url en signed_pdf_url, gedocumenteerd op de pagina Offertetokens. Anders dan bij winkelwagen- en bestelresponses zijn alle offertebedragen kale integers in minor units, geen money-objecten. Datums zijn ISO-8601-strings.
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
id | string (UUID) | altijd | Offerte-id. |
number | string | altijd | Klantgericht offertenummer, "Q-" plus een integer per winkel, bijvoorbeeld "Q-17". |
status | string | altijd | Zie de statustabel hierboven. |
email | string | altijd | E-mailadres van de aanvrager. |
name | string | altijd | Naam van de aanvrager. |
phone | string of null | altijd | Telefoonnummer van de aanvrager. |
billing_address | object of null | altijd | Zoals ingediend. |
shipping_address | object of null | altijd | Zoals ingediend. |
currency | string | altijd | EUR. |
customer_note | string of null | altijd | De notitie van de koper uit de aanvraag. |
message_to_customer | string of null | altijd | Het bericht van de merchant, gezet bij het aanbieden. |
valid_until | string (ISO-8601) of null | altijd | Vervaldatum van het aanbod, gezet bij het aanbieden. |
subtotal_amount | integer of null | altijd | Bevroren op het moment van aanbieden; null zolang submitted. Minor units. |
tax_total_amount | integer of null | altijd | Bevroren op het moment van aanbieden; null zolang submitted. |
shipping_total_amount | integer of null | altijd | Bevroren op het moment van aanbieden; null zolang submitted. |
total_amount | integer of null | altijd | Bevroren op het moment van aanbieden; null zolang submitted. |
tax_breakdown | array of null | altijd | Uitsplitsing per tarief {"rate": float, "base": int, "tax": int}; null zolang submitted. |
converted_order_id | string (UUID) of null | altijd | De bestelling die bij acceptatie is aangemaakt, anders null. |
submitted_at | string (ISO-8601) of null | altijd | Wanneer de aanvraag is ingediend. |
offered_at | string (ISO-8601) of null | altijd | Wanneer de merchant het aanbod heeft verzonden. |
accepted_at | string (ISO-8601) of null | altijd | Wanneer de koper heeft geaccepteerd. |
declined_at | string (ISO-8601) of null | altijd | Wanneer de koper heeft afgewezen. |
cancelled_at | string (ISO-8601) of null | altijd | Wanneer de merchant heeft geannuleerd. |
created_at | string (ISO-8601) of null | altijd | Aanmaaktijd van de rij. |
updated_at | string (ISO-8601) of null | altijd | Laatste wijzigingstijd. |
lines | array | altijd | Offerteregels, zie hieronder. |
lines[]
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
id | string (UUID) | altijd | Offerteregel-id. |
product_id | string (UUID) of null | altijd | Het product; null voor custom regels die de merchant heeft toegevoegd. |
variant_id | string (UUID) of null | altijd | De variant, indien van toepassing. |
is_custom | boolean | altijd | True voor door de merchant toegevoegde custom regels. |
title | string | altijd | Regeltitel (productnaam-snapshot, of vrije tekst voor custom regels). |
sku | string of null | altijd | SKU-snapshot. |
quantity | number | altijd | Hoeveelheid, overgenomen van de winkelwagenregel: een geheel getal voor een product dat per piece verkocht wordt, tot drie decimalen voor elke andere eenheid (bijvoorbeeld 0.75). Dienst- en materiaalregels van de merchant kunnen ook decimalen hebben. |
indicative_unit_price | integer of null | altijd | Stukprijs (minor units), gesnapshot uit de prijscontext van de aanvrager op het moment van indienen. |
quoted_unit_price | integer of null | altijd | De geoffreerde stukprijs van de merchant; null totdat er geprijsd is. |
tax_class_id | string (UUID) of null | altijd | Btw-klasse die de merchant heeft toegewezen, indien aanwezig. |
attributes | object of null | altijd | Configuratie-snapshot voor configureerbare regels, anders null. |
sort_order | integer | altijd | Weergavevolgorde. |
kind | string | altijd | product voor regels die uit een winkelwagen zijn gemaakt; regels van de merchant kunnen service, material of other zijn. |
unit | string of null | altijd | Eenheidslabel. Een regel uit een winkelwagen heeft pcs voor een product dat per piece verkocht wordt en anders de eenheid van het product (kg, m2, hour, ...). |
description | string of null | altijd | Optionele notitie op regelniveau. |
tax_rate | string of null | altijd | Decimaal btw-tarief, vastgelegd wanneer de merchant het aanbod verstuurt (bijvoorbeeld "21.00"); tot dan null. |
unit_price | integer of null | altijd | Alias van quoted_unit_price. |
POST /v1/api/commerce/carts/{id}/quote-request
Dient de winkelwagen in als offerteaanvraag. Vereist commerce:write, een active niet-lege winkelwagen, en doorloopt de eigenaarschapscontrole van de winkelwagen. Bij succes wordt de winkelwagen converted, wordt een offerte aangemaakt in status submitted waarbij elke winkelwagenregel wordt gesnapshot tegen een indicatieve stukprijs uit de prijscontext van de aanvrager, wordt een ontvangstbevestigingsmail voor de aanvrager in de wachtrij gezet, en wordt de klantgerichte offerte geretourneerd met status 201.
Contactresolutie: email en name zijn in totaal verplicht, maar elk kan komen uit ofwel de request body ofwel, wanneer een geldige X-Customer-Token wordt meegestuurd, het profiel van de klant. Een geldig token koppelt de offerte bovendien aan de klant.
Parameters
Pad
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
id | string (UUID) | ja | Winkelwagen-id. Moet een active, niet-lege winkelwagen zijn. |
Body
Alle body-velden zijn optioneel en nullable; email en name worden verplicht wanneer het klantprofiel ze niet kan leveren.
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
email | string | conditioneel | Geldig e-mailadres. Valt terug op het profiel-e-mailadres van de klant met token. |
name | string | conditioneel | Naam van de aanvrager. Valt terug op de naam uit het klantprofiel. |
phone | string | nee | Contacttelefoonnummer. |
billing_address | object | nee | Vrij adresobject. |
shipping_address | object | nee | Vrij adresobject. |
customer_note | string | nee | Bericht aan de merchant. |
Headers
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
X-Customer-Token | string | nee | Indien aanwezig moet deze herleidbaar zijn, anders 401. Koppelt de offerte aan de klant, levert contact-fallbacks, en selecteert de prijscontext voor indicatieve prijzen. |
Na het indienen is er geen storefront-endpoint om de offerte op id te pollen: de koper ontvangt het aanbod per e-mail, en de token-endpoints nemen het vanaf daar over.
Fouten
| Status | Body | Wanneer |
|---|---|---|
| 404 | {"error": "Module not enabled: sales"} | De winkel heeft de sales-module niet ingeschakeld. Let op de key error en de status 404 (andere module-gates antwoorden 403). |
| 404 | {"message": "..."} | Offerteaanvragen zijn uitgeschakeld voor de winkel, of de winkelwagen is onbekend, verlopen, of niet active. |
| 401 | {"message": "Invalid customer token."} | X-Customer-Token aanwezig maar niet herleidbaar. |
| 422 | {"message": "...", "errors": {"email": ["Email is required."], "name": ["Name is required."]}} | Noch de body noch het klantprofiel levert e-mailadres of naam. |
| 422 | {"message": "...", "errors": {"cart": ["Cart is empty."]}} | De winkelwagen heeft geen regels. |
| 403 | eigenaarschaps-, scope-, commerce-module- of suspensie-body | Zie de pagina Winkelwagens. |
| 429 | {"message": "Too Many Attempts."} | Rate limit overschreden. |
curl -X POST https://api.borkol.com/v1/api/commerce/carts/9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4/quote-request \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"email": "buyer@corp.example",
"name": "Bob Buyer",
"phone": "+31 6 12345678",
"customer_note": "Need delivery before October.",
"billing_address": {
"name": "Corp BV",
"street": "Main St 1",
"postal_code": "1000 AA",
"city": "Amsterdam",
"country": "NL"
}
}'const res = await fetch(
`https://api.borkol.com/v1/api/commerce/carts/${cartId}/quote-request`,
{
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "buyer@corp.example",
name: "Bob Buyer",
customer_note: "Need delivery before October.",
}),
}
);
const { data: quote } = await res.json();{
"data": {
"id": "6e7f8a9b-0c1d-4e2f-a3b4-c5d6e7f8a9b0",
"number": "Q-17",
"status": "submitted",
"email": "buyer@corp.example",
"name": "Bob Buyer",
"phone": "+31 6 12345678",
"billing_address": {
"name": "Corp BV",
"street": "Main St 1",
"postal_code": "1000 AA",
"city": "Amsterdam",
"country": "NL"
},
"shipping_address": null,
"currency": "EUR",
"customer_note": "Need delivery before October.",
"message_to_customer": null,
"valid_until": null,
"subtotal_amount": null,
"tax_total_amount": null,
"shipping_total_amount": null,
"total_amount": null,
"tax_breakdown": null,
"converted_order_id": null,
"submitted_at": "2026-08-14T10:15:30+00:00",
"offered_at": null,
"accepted_at": null,
"declined_at": null,
"cancelled_at": null,
"created_at": "2026-08-14T10:15:30+00:00",
"updated_at": "2026-08-14T10:15:30+00:00",
"lines": [
{
"id": "9b0c1d2e-3f4a-4b5c-d6e7-f8a9b0c1d2e3",
"product_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"variant_id": null,
"is_custom": false,
"title": "Garden Chair",
"sku": "CHAIR-GRN",
"quantity": 25,
"indicative_unit_price": 2250,
"quoted_unit_price": null,
"tax_class_id": null,
"attributes": null,
"sort_order": 0,
"kind": "product",
"unit": "pcs",
"description": null,
"tax_rate": null,
"unit_price": null
}
],
"origin": "storefront",
"intro": null,
"terms": null,
"signed_at": null,
"acceptance_mode": "click",
"pdf_url": null,
"signed_pdf_url": null
}
}POST /v1/api/commerce/carts/{id}/quote-request
Dient de winkelwagen in als offerteaanvraag. Vereist commerce:write, een active niet-lege winkelwagen, en doorloopt de eigenaarschapscontrole van de winkelwagen. Bij succes wordt de winkelwagen converted, wordt een offerte aangemaakt in status submitted waarbij elke winkelwagenregel wordt gesnapshot tegen een indicatieve stukprijs uit de prijscontext van de aanvrager, wordt een ontvangstbevestigingsmail voor de aanvrager in de wachtrij gezet, en wordt de klantgerichte offerte geretourneerd met status 201.
Contactresolutie: email en name zijn in totaal verplicht, maar elk kan komen uit ofwel de request body ofwel, wanneer een geldige X-Customer-Token wordt meegestuurd, het profiel van de klant. Een geldig token koppelt de offerte bovendien aan de klant.
Parameters
Pad
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
id | string (UUID) | ja | Winkelwagen-id. Moet een active, niet-lege winkelwagen zijn. |
Body
Alle body-velden zijn optioneel en nullable; email en name worden verplicht wanneer het klantprofiel ze niet kan leveren.
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
email | string | conditioneel | Geldig e-mailadres. Valt terug op het profiel-e-mailadres van de klant met token. |
name | string | conditioneel | Naam van de aanvrager. Valt terug op de naam uit het klantprofiel. |
phone | string | nee | Contacttelefoonnummer. |
billing_address | object | nee | Vrij adresobject. |
shipping_address | object | nee | Vrij adresobject. |
customer_note | string | nee | Bericht aan de merchant. |
Headers
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
X-Customer-Token | string | nee | Indien aanwezig moet deze herleidbaar zijn, anders 401. Koppelt de offerte aan de klant, levert contact-fallbacks, en selecteert de prijscontext voor indicatieve prijzen. |
curl -X POST https://api.borkol.com/v1/api/commerce/carts/9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4/quote-request \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"email": "buyer@corp.example",
"name": "Bob Buyer",
"phone": "+31 6 12345678",
"customer_note": "Need delivery before October.",
"billing_address": {
"name": "Corp BV",
"street": "Main St 1",
"postal_code": "1000 AA",
"city": "Amsterdam",
"country": "NL"
}
}'const res = await fetch(
`https://api.borkol.com/v1/api/commerce/carts/${cartId}/quote-request`,
{
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "buyer@corp.example",
name: "Bob Buyer",
customer_note: "Need delivery before October.",
}),
}
);
const { data: quote } = await res.json();{
"data": {
"id": "6e7f8a9b-0c1d-4e2f-a3b4-c5d6e7f8a9b0",
"number": "Q-17",
"status": "submitted",
"email": "buyer@corp.example",
"name": "Bob Buyer",
"phone": "+31 6 12345678",
"billing_address": {
"name": "Corp BV",
"street": "Main St 1",
"postal_code": "1000 AA",
"city": "Amsterdam",
"country": "NL"
},
"shipping_address": null,
"currency": "EUR",
"customer_note": "Need delivery before October.",
"message_to_customer": null,
"valid_until": null,
"subtotal_amount": null,
"tax_total_amount": null,
"shipping_total_amount": null,
"total_amount": null,
"tax_breakdown": null,
"converted_order_id": null,
"submitted_at": "2026-08-14T10:15:30+00:00",
"offered_at": null,
"accepted_at": null,
"declined_at": null,
"cancelled_at": null,
"created_at": "2026-08-14T10:15:30+00:00",
"updated_at": "2026-08-14T10:15:30+00:00",
"lines": [
{
"id": "9b0c1d2e-3f4a-4b5c-d6e7-f8a9b0c1d2e3",
"product_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"variant_id": null,
"is_custom": false,
"title": "Garden Chair",
"sku": "CHAIR-GRN",
"quantity": 25,
"indicative_unit_price": 2250,
"quoted_unit_price": null,
"tax_class_id": null,
"attributes": null,
"sort_order": 0,
"kind": "product",
"unit": "pcs",
"description": null,
"tax_rate": null,
"unit_price": null
}
],
"origin": "storefront",
"intro": null,
"terms": null,
"signed_at": null,
"acceptance_mode": "click",
"pdf_url": null,
"signed_pdf_url": null
}
}Na het indienen is er geen storefront-endpoint om de offerte op id te pollen: de koper ontvangt het aanbod per e-mail, en de token-endpoints nemen het vanaf daar over.
Fouten
| Status | Body | Wanneer |
|---|---|---|
| 404 | {"error": "Module not enabled: sales"} | De winkel heeft de sales-module niet ingeschakeld. Let op de key error en de status 404 (andere module-gates antwoorden 403). |
| 404 | {"message": "..."} | Offerteaanvragen zijn uitgeschakeld voor de winkel, of de winkelwagen is onbekend, verlopen, of niet active. |
| 401 | {"message": "Invalid customer token."} | X-Customer-Token aanwezig maar niet herleidbaar. |
| 422 | {"message": "...", "errors": {"email": ["Email is required."], "name": ["Name is required."]}} | Noch de body noch het klantprofiel levert e-mailadres of naam. |
| 422 | {"message": "...", "errors": {"cart": ["Cart is empty."]}} | De winkelwagen heeft geen regels. |
| 403 | eigenaarschaps-, scope-, commerce-module- of suspensie-body | Zie de pagina Winkelwagens. |
| 429 | {"message": "Too Many Attempts."} | Rate limit overschreden. |