Skip to content

Complete the sale a held order waits for

POST
/v1/merchant/orders/{order}/sale
curl --request POST \
--url https://driver-staging-api.delivr.no/v1/merchant/orders/DD-123456/sale \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: 2489E9AD-2EE2-8E00-8EC9-32D5F69181C0' \
--data '{ "externalRef": "example" }'

Completes the sale and binds your order id (externalRef), once. The recipient then gets the placement SMS with the tracking link, trackingUrl appears and order.placed is sent. Again with the same externalRef: 200, the order as it is.

Refusals (409): conflict (order not held, or bound to another externalRef), order_ended (cancelled or failed, e.g. the checkout budget passed), external_ref_taken.

Goods picked up or delivered before this call are recorded as a late sale; the call is still required.

order
required
string

Delivr’s order id (UUID) or its DD- reference.

Idempotency-Key
required
string format: uuid

A UUID, one header. A retry of the same request (method, path, canonical JSON body) within 24 h gets the first successful reply again (Idempotent-Replayed: true). Another request under the key is 422 idempotency_key_reused; a retry while the first runs is 409 idempotency_key_in_flight. Refused or failed requests free the key.

Media typeapplication/json
object
externalRef
required
string
>= 1 characters <= 200 characters

Example generated

{
"externalRef": "example"
}

The order.

Media typeapplication/json
object
id
required

Equals quoteId for an order placed on a quote.

string format: uuid
reference
required
string
externalRef
required

Your order id. “” on a held order until its sale completes.

string
type
required
string
Allowed values: on_demand window
status
required

On demand: placed → awaiting_goods → searching → driver_assigned → picked_up → delivered. Window: placed → scheduled → picked_up → delivered. cancelled and failed end either, with reason.

string
Allowed values: placed awaiting_goods scheduled searching driver_assigned picked_up delivered cancelled failed
reason

Why a cancelled or failed order ended.

string
Allowed values: no_driver goods_not_ready no_capacity undeliverable cancelled_by_merchant cancelled_by_delivr other
readyBy

On demand. Goods due.

string format: date-time
readyAt

On demand. Ready time stated (or assumed).

string format: date-time
window
object
start
required
string format: date-time
end
required
string format: date-time
trackingUrl

Recipient’s tracking link. Absent before it exists, once ended (unless a fallback is open) and while a held sale is pending.

string format: uri
timeZone
required
string
createdAt
required
string format: date-time
placedAt
string format: date-time
confirmedAt

Driver accepted (on demand) or transport booked (window).

string format: date-time
updatedAt
required
string format: date-time
version
required

Increases with every change. Keep the highest you saw; ignore older data.

integer format: int64
proofOfDelivery
object
deliveredAt
required
string format: date-time
receiverName
string
eta

Placement reply only. On-demand arrival promised now.

object
from
required
string format: date-time
to
required
string format: date-time
rescheduled

Placement reply only. Window booked on another window than quoted.

boolean
predecessorId

The failed order this successor follows.

string format: uuid
successorId

On a failed order, the newest successor.

string format: uuid
sale

Held orders only (assisted checkout). “Driver found” = status pending and driver assigned. The order status alone is not enough (it stays driver_assigned while a driver gives the job back).

object
status
required
string
Allowed values: pending completed abandoned
driver
required
string
Allowed values: searching assigned reassigning
completeBy

The checkout budget passes then and the order is cancelled at its current fee stage. Present while it runs.

string format: date-time
completedAt
string format: date-time

Example

{
"reference": "DD-123456",
"type": "on_demand",
"status": "placed",
"reason": "no_driver",
"sale": {
"status": "pending",
"driver": "searching"
}
}
X-Request-Id
string

The request’s id (yours if you sent a valid one, up to 64 of A-Za-z0-9._-). Quote it to support.

Idempotent-Replayed
string
Allowed values: true

true when the reply is a replay under the Idempotency-Key.

malformed_json, idempotency_key_required.

Media typeapplication/json
object
error
required
object
code
required

Status per code: 400 malformed_json, idempotency_key_required; 401 unauthenticated; 403 merchant_suspended, insufficient_scope; 404 not_found, quote_not_found; 405 method_not_allowed; 409 conflict, cancellation_not_allowed, idempotency_key_in_flight, price_changed, option_unavailable, fee_changed, quote_already_used, external_ref_taken, window_full, order_ended; 422 invalid_request, idempotency_key_reused, no_delivery_options, manual_quote_required, invalid_address; 429 rate_limited; 500 internal; 503 unavailable.

string
Allowed values: invalid_request malformed_json not_found method_not_allowed unauthenticated merchant_suspended insufficient_scope conflict cancellation_not_allowed idempotency_key_required idempotency_key_reused idempotency_key_in_flight unavailable rate_limited quote_not_found no_delivery_options manual_quote_required invalid_address price_changed option_unavailable fee_changed quote_already_used external_ref_taken window_full order_ended internal
message
required

Human-readable; may change. Branch on code.

string
param

The request field at fault, e.g. delivery.address (an unknown field: its name).

string
requestId
string
details
One of:
object
quotedAmountMinor
required
integer
option
required
object
type
required
string
Allowed values: on_demand window
key
required

Stable key to book (on_demand or window:<start>/<end> in the market’s zone). The same delivery quoted again lists the same keys.

string
eta

On demand. Arrival band.

object
from
required
string format: date-time
to
required
string format: date-time
window

Window option.

object
start
required
string format: date-time
end
required
string format: date-time
cutoffAt

Window option. Book and cancel free before it.

string format: date-time
price
required
object
amountMinor
required

VAT included.

integer
vatMinor
integer
exVatMinor
integer
currency
required
string
supply

On demand only. HINT for the seller, never a promise: drivers near the store when quoted and when the first-ranked could reach it. Do not show a driver count to shoppers.

object
nearbyDrivers
required
integer
pickupEta
required
object
from
required
string format: date-time
to
required
string format: date-time

Example

{
"error": {
"code": "invalid_request",
"details": {
"option": {
"type": "on_demand",
"key": "on_demand",
"price": {
"currency": "NOK"
}
}
}
}
}

unauthenticated: missing, unknown or revoked key.

Media typeapplication/json
object
error
required
object
code
required

Status per code: 400 malformed_json, idempotency_key_required; 401 unauthenticated; 403 merchant_suspended, insufficient_scope; 404 not_found, quote_not_found; 405 method_not_allowed; 409 conflict, cancellation_not_allowed, idempotency_key_in_flight, price_changed, option_unavailable, fee_changed, quote_already_used, external_ref_taken, window_full, order_ended; 422 invalid_request, idempotency_key_reused, no_delivery_options, manual_quote_required, invalid_address; 429 rate_limited; 500 internal; 503 unavailable.

string
Allowed values: invalid_request malformed_json not_found method_not_allowed unauthenticated merchant_suspended insufficient_scope conflict cancellation_not_allowed idempotency_key_required idempotency_key_reused idempotency_key_in_flight unavailable rate_limited quote_not_found no_delivery_options manual_quote_required invalid_address price_changed option_unavailable fee_changed quote_already_used external_ref_taken window_full order_ended internal
message
required

Human-readable; may change. Branch on code.

string
param

The request field at fault, e.g. delivery.address (an unknown field: its name).

string
requestId
string
details
One of:
object
quotedAmountMinor
required
integer
option
required
object
type
required
string
Allowed values: on_demand window
key
required

Stable key to book (on_demand or window:<start>/<end> in the market’s zone). The same delivery quoted again lists the same keys.

string
eta

On demand. Arrival band.

object
from
required
string format: date-time
to
required
string format: date-time
window

Window option.

object
start
required
string format: date-time
end
required
string format: date-time
cutoffAt

Window option. Book and cancel free before it.

string format: date-time
price
required
object
amountMinor
required

VAT included.

integer
vatMinor
integer
exVatMinor
integer
currency
required
string
supply

On demand only. HINT for the seller, never a promise: drivers near the store when quoted and when the first-ranked could reach it. Do not show a driver count to shoppers.

object
nearbyDrivers
required
integer
pickupEta
required
object
from
required
string format: date-time
to
required
string format: date-time

Example

{
"error": {
"code": "invalid_request",
"details": {
"option": {
"type": "on_demand",
"key": "on_demand",
"price": {
"currency": "NOK"
}
}
}
}
}

merchant_suspended, insufficient_scope.

Media typeapplication/json
object
error
required
object
code
required

Status per code: 400 malformed_json, idempotency_key_required; 401 unauthenticated; 403 merchant_suspended, insufficient_scope; 404 not_found, quote_not_found; 405 method_not_allowed; 409 conflict, cancellation_not_allowed, idempotency_key_in_flight, price_changed, option_unavailable, fee_changed, quote_already_used, external_ref_taken, window_full, order_ended; 422 invalid_request, idempotency_key_reused, no_delivery_options, manual_quote_required, invalid_address; 429 rate_limited; 500 internal; 503 unavailable.

string
Allowed values: invalid_request malformed_json not_found method_not_allowed unauthenticated merchant_suspended insufficient_scope conflict cancellation_not_allowed idempotency_key_required idempotency_key_reused idempotency_key_in_flight unavailable rate_limited quote_not_found no_delivery_options manual_quote_required invalid_address price_changed option_unavailable fee_changed quote_already_used external_ref_taken window_full order_ended internal
message
required

Human-readable; may change. Branch on code.

string
param

The request field at fault, e.g. delivery.address (an unknown field: its name).

string
requestId
string
details
One of:
object
quotedAmountMinor
required
integer
option
required
object
type
required
string
Allowed values: on_demand window
key
required

Stable key to book (on_demand or window:<start>/<end> in the market’s zone). The same delivery quoted again lists the same keys.

string
eta

On demand. Arrival band.

object
from
required
string format: date-time
to
required
string format: date-time
window

Window option.

object
start
required
string format: date-time
end
required
string format: date-time
cutoffAt

Window option. Book and cancel free before it.

string format: date-time
price
required
object
amountMinor
required

VAT included.

integer
vatMinor
integer
exVatMinor
integer
currency
required
string
supply

On demand only. HINT for the seller, never a promise: drivers near the store when quoted and when the first-ranked could reach it. Do not show a driver count to shoppers.

object
nearbyDrivers
required
integer
pickupEta
required
object
from
required
string format: date-time
to
required
string format: date-time

Example

{
"error": {
"code": "invalid_request",
"details": {
"option": {
"type": "on_demand",
"key": "on_demand",
"price": {
"currency": "NOK"
}
}
}
}
}

not_found (also another merchant’s order), quote_not_found.

Media typeapplication/json
object
error
required
object
code
required

Status per code: 400 malformed_json, idempotency_key_required; 401 unauthenticated; 403 merchant_suspended, insufficient_scope; 404 not_found, quote_not_found; 405 method_not_allowed; 409 conflict, cancellation_not_allowed, idempotency_key_in_flight, price_changed, option_unavailable, fee_changed, quote_already_used, external_ref_taken, window_full, order_ended; 422 invalid_request, idempotency_key_reused, no_delivery_options, manual_quote_required, invalid_address; 429 rate_limited; 500 internal; 503 unavailable.

string
Allowed values: invalid_request malformed_json not_found method_not_allowed unauthenticated merchant_suspended insufficient_scope conflict cancellation_not_allowed idempotency_key_required idempotency_key_reused idempotency_key_in_flight unavailable rate_limited quote_not_found no_delivery_options manual_quote_required invalid_address price_changed option_unavailable fee_changed quote_already_used external_ref_taken window_full order_ended internal
message
required

Human-readable; may change. Branch on code.

string
param

The request field at fault, e.g. delivery.address (an unknown field: its name).

string
requestId
string
details
One of:
object
quotedAmountMinor
required
integer
option
required
object
type
required
string
Allowed values: on_demand window
key
required

Stable key to book (on_demand or window:<start>/<end> in the market’s zone). The same delivery quoted again lists the same keys.

string
eta

On demand. Arrival band.

object
from
required
string format: date-time
to
required
string format: date-time
window

Window option.

object
start
required
string format: date-time
end
required
string format: date-time
cutoffAt

Window option. Book and cancel free before it.

string format: date-time
price
required
object
amountMinor
required

VAT included.

integer
vatMinor
integer
exVatMinor
integer
currency
required
string
supply

On demand only. HINT for the seller, never a promise: drivers near the store when quoted and when the first-ranked could reach it. Do not show a driver count to shoppers.

object
nearbyDrivers
required
integer
pickupEta
required
object
from
required
string format: date-time
to
required
string format: date-time

Example

{
"error": {
"code": "invalid_request",
"details": {
"option": {
"type": "on_demand",
"key": "on_demand",
"price": {
"currency": "NOK"
}
}
}
}
}

conflict, cancellation_not_allowed, idempotency_key_in_flight, price_changed, option_unavailable, window_full, fee_changed, quote_already_used, external_ref_taken, order_ended. See details for what to do.

Media typeapplication/json
object
error
required
object
code
required

Status per code: 400 malformed_json, idempotency_key_required; 401 unauthenticated; 403 merchant_suspended, insufficient_scope; 404 not_found, quote_not_found; 405 method_not_allowed; 409 conflict, cancellation_not_allowed, idempotency_key_in_flight, price_changed, option_unavailable, fee_changed, quote_already_used, external_ref_taken, window_full, order_ended; 422 invalid_request, idempotency_key_reused, no_delivery_options, manual_quote_required, invalid_address; 429 rate_limited; 500 internal; 503 unavailable.

string
Allowed values: invalid_request malformed_json not_found method_not_allowed unauthenticated merchant_suspended insufficient_scope conflict cancellation_not_allowed idempotency_key_required idempotency_key_reused idempotency_key_in_flight unavailable rate_limited quote_not_found no_delivery_options manual_quote_required invalid_address price_changed option_unavailable fee_changed quote_already_used external_ref_taken window_full order_ended internal
message
required

Human-readable; may change. Branch on code.

string
param

The request field at fault, e.g. delivery.address (an unknown field: its name).

string
requestId
string
details
One of:
object
quotedAmountMinor
required
integer
option
required
object
type
required
string
Allowed values: on_demand window
key
required

Stable key to book (on_demand or window:<start>/<end> in the market’s zone). The same delivery quoted again lists the same keys.

string
eta

On demand. Arrival band.

object
from
required
string format: date-time
to
required
string format: date-time
window

Window option.

object
start
required
string format: date-time
end
required
string format: date-time
cutoffAt

Window option. Book and cancel free before it.

string format: date-time
price
required
object
amountMinor
required

VAT included.

integer
vatMinor
integer
exVatMinor
integer
currency
required
string
supply

On demand only. HINT for the seller, never a promise: drivers near the store when quoted and when the first-ranked could reach it. Do not show a driver count to shoppers.

object
nearbyDrivers
required
integer
pickupEta
required
object
from
required
string format: date-time
to
required
string format: date-time

Example

{
"error": {
"code": "invalid_request",
"details": {
"option": {
"type": "on_demand",
"key": "on_demand",
"price": {
"currency": "NOK"
}
}
}
}
}

invalid_request (with param), idempotency_key_reused, no_delivery_options, manual_quote_required, invalid_address.

Media typeapplication/json
object
error
required
object
code
required

Status per code: 400 malformed_json, idempotency_key_required; 401 unauthenticated; 403 merchant_suspended, insufficient_scope; 404 not_found, quote_not_found; 405 method_not_allowed; 409 conflict, cancellation_not_allowed, idempotency_key_in_flight, price_changed, option_unavailable, fee_changed, quote_already_used, external_ref_taken, window_full, order_ended; 422 invalid_request, idempotency_key_reused, no_delivery_options, manual_quote_required, invalid_address; 429 rate_limited; 500 internal; 503 unavailable.

string
Allowed values: invalid_request malformed_json not_found method_not_allowed unauthenticated merchant_suspended insufficient_scope conflict cancellation_not_allowed idempotency_key_required idempotency_key_reused idempotency_key_in_flight unavailable rate_limited quote_not_found no_delivery_options manual_quote_required invalid_address price_changed option_unavailable fee_changed quote_already_used external_ref_taken window_full order_ended internal
message
required

Human-readable; may change. Branch on code.

string
param

The request field at fault, e.g. delivery.address (an unknown field: its name).

string
requestId
string
details
One of:
object
quotedAmountMinor
required
integer
option
required
object
type
required
string
Allowed values: on_demand window
key
required

Stable key to book (on_demand or window:<start>/<end> in the market’s zone). The same delivery quoted again lists the same keys.

string
eta

On demand. Arrival band.

object
from
required
string format: date-time
to
required
string format: date-time
window

Window option.

object
start
required
string format: date-time
end
required
string format: date-time
cutoffAt

Window option. Book and cancel free before it.

string format: date-time
price
required
object
amountMinor
required

VAT included.

integer
vatMinor
integer
exVatMinor
integer
currency
required
string
supply

On demand only. HINT for the seller, never a promise: drivers near the store when quoted and when the first-ranked could reach it. Do not show a driver count to shoppers.

object
nearbyDrivers
required
integer
pickupEta
required
object
from
required
string format: date-time
to
required
string format: date-time

Example

{
"error": {
"code": "invalid_request",
"details": {
"option": {
"type": "on_demand",
"key": "on_demand",
"price": {
"currency": "NOK"
}
}
}
}
}

rate_limited. Also after repeated failed sign-ins from one address.

Media typeapplication/json
object
error
required
object
code
required

Status per code: 400 malformed_json, idempotency_key_required; 401 unauthenticated; 403 merchant_suspended, insufficient_scope; 404 not_found, quote_not_found; 405 method_not_allowed; 409 conflict, cancellation_not_allowed, idempotency_key_in_flight, price_changed, option_unavailable, fee_changed, quote_already_used, external_ref_taken, window_full, order_ended; 422 invalid_request, idempotency_key_reused, no_delivery_options, manual_quote_required, invalid_address; 429 rate_limited; 500 internal; 503 unavailable.

string
Allowed values: invalid_request malformed_json not_found method_not_allowed unauthenticated merchant_suspended insufficient_scope conflict cancellation_not_allowed idempotency_key_required idempotency_key_reused idempotency_key_in_flight unavailable rate_limited quote_not_found no_delivery_options manual_quote_required invalid_address price_changed option_unavailable fee_changed quote_already_used external_ref_taken window_full order_ended internal
message
required

Human-readable; may change. Branch on code.

string
param

The request field at fault, e.g. delivery.address (an unknown field: its name).

string
requestId
string
details
One of:
object
quotedAmountMinor
required
integer
option
required
object
type
required
string
Allowed values: on_demand window
key
required

Stable key to book (on_demand or window:<start>/<end> in the market’s zone). The same delivery quoted again lists the same keys.

string
eta

On demand. Arrival band.

object
from
required
string format: date-time
to
required
string format: date-time
window

Window option.

object
start
required
string format: date-time
end
required
string format: date-time
cutoffAt

Window option. Book and cancel free before it.

string format: date-time
price
required
object
amountMinor
required

VAT included.

integer
vatMinor
integer
exVatMinor
integer
currency
required
string
supply

On demand only. HINT for the seller, never a promise: drivers near the store when quoted and when the first-ranked could reach it. Do not show a driver count to shoppers.

object
nearbyDrivers
required
integer
pickupEta
required
object
from
required
string format: date-time
to
required
string format: date-time

Example

{
"error": {
"code": "invalid_request",
"details": {
"option": {
"type": "on_demand",
"key": "on_demand",
"price": {
"currency": "NOK"
}
}
}
}
}
Retry-After
integer

Seconds to wait.

RateLimit-Limit
integer

Requests per minute for your merchant (600).

RateLimit-Remaining
integer
RateLimit-Reset
integer

Seconds until the window resets.