POST
Mark a milestone delivered

Authorizations

Authorization
string
header
default:sk_test_docs_246e232c64ccc7a001bf61ec0f2e6ab0
required

Authorization: Bearer <secret key>. Secret keys belong to your organisation, are shown once when created in the dashboard, and are scoped (see x-required-scope on each operation). Keep them on your server. Live keys are issued after your business is verified. Publishable keys (pk_) are only for @ketapay/checkout and don't work here.

KetaPay-Customer-Token
string
header
required

Proof that your customer approved this call, from POST /customer_sessions/{id}/verify. Sent together with your secret key. Valid for 15 minutes, for that customer's escrows only.

Headers

Idempotency-Key
string
required

Unique key for this operation. Retries with the same key return the first result.

Maximum string length: 255
Example:

"7f3e2a10-6c4d-4b8e-9a1f-2d5c8e7b6a40"

Path Parameters

id
string<uuid>
required
milestone_id
string<uuid>
required

Body

application/json
note
string | null

What was delivered, for the buyer

Maximum string length: 160
attachments
object[]
Maximum array length: 10

Send either file (an id from POST /files) or url (an HTTPS link KetaPay copies, so it survives your copy being deleted). Responses always carry KetaPay's own url.

Response

The updated escrow

id
string<uuid>
required
object
string
required
Allowed value: "escrow"
livemode
boolean
required
status
enum<string>
required

active: money held, milestones in progress. disputed: the buyer reported a problem; KetaPay is handling it. completed: ended with at least one milestone paid to the seller. refunded: ended with everything returned to the buyer. An escrow only exists once the buyer has paid.

Available options:
active,
disputed,
completed,
refunded
amount
integer
required

Amount in kobo

Required range: x >= 0
Example:

45000000

currency
string
required
Allowed value: "NGN"
fees
object
required

Totals for the whole escrow, in kobo. buyer_total = amount + buyer_fee + buyer_vat and seller_payout = amount - seller_fee - commission. Until everything is released these are what will apply; each milestone shows its own share.

category
enum<string>
default:other
required

What kind of deal this is. KetaPay uses it for risk checks and dispute handling.

Available options:
goods,
services,
property,
vehicle,
digital,
other
title
string
required
description
string
required
images
object[]
required

KetaPay's copies of the images sent at checkout; the first is the cover

Send either file (an id from POST /files with purpose agreement) or url (an HTTPS link KetaPay copies). JPEG, PNG, HEIC or WebP. Responses carry KetaPay's own url plus a small thumbnail_url.

attachments
object[]
required

KetaPay's copies of the documents sent at checkout

Send either file (an id from POST /files) or url (an HTTPS link KetaPay copies, so it survives your copy being deleted). Responses always carry KetaPay's own url.

milestones
object[]
required

In order. One entry for a single payment.

buyer
object
required
seller
object
required

The seller, or your business when you sell your own goods

release
object
required
checkout_session_id
string<uuid>
required
open_dispute_id
string<uuid> | null
required

The dispute currently open, if any. GET /escrows/{id}/disputes lists them all.

open_chargeback_id
string<uuid> | null
required

A card chargeback currently being contested, if any

flagged
boolean
required

Whether you have flagged this escrow

timeline
object[]
required

What happened, oldest first

external_reference
string | null
required

Your own id for this object, for example your order or project id. Filterable.

Maximum string length: 255
Example:

"proj_4471"

metadata
object
required

Your own key-value pairs. KetaPay stores them and never reads them.

Example:
created_at
string<date-time>
required
funded_at
string<date-time>
required
ended_at
string<date-time> | null
required

When it became completed or refunded