curl --request POST \
--url https://staging.api.payluk.ng/v1/escrow/create \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form amount=150000 \
--form 'purpose=MacBook Pro 14"' \
--form whoPays=both \
--form maxDelivery=3 \
--form deliveryTimeline=days \
--form 'description=Space grey, sealed' \
--form totalQuantity=1 \
--form categoryId=665f1b2c9a1e4d0012ab3c30 \
--form imageUrl='@example-file'import requests
url = "https://staging.api.payluk.ng/v1/escrow/create"
files = { "imageUrl": ("example-file", open("example-file", "rb")) }
payload = {
"amount": "150000",
"purpose": "MacBook Pro 14\"",
"whoPays": "both",
"maxDelivery": "3",
"deliveryTimeline": "days",
"description": "Space grey, sealed",
"totalQuantity": "1",
"categoryId": "665f1b2c9a1e4d0012ab3c30"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('amount', '150000');
form.append('purpose', 'MacBook Pro 14"');
form.append('whoPays', 'both');
form.append('maxDelivery', '3');
form.append('deliveryTimeline', 'days');
form.append('description', 'Space grey, sealed');
form.append('totalQuantity', '1');
form.append('categoryId', '665f1b2c9a1e4d0012ab3c30');
form.append('imageUrl', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://staging.api.payluk.ng/v1/escrow/create', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://staging.api.payluk.ng/v1/escrow/create",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"amount\"\r\n\r\n150000\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\nMacBook Pro 14\"\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"whoPays\"\r\n\r\nboth\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"maxDelivery\"\r\n\r\n3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"deliveryTimeline\"\r\n\r\ndays\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nSpace grey, sealed\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"totalQuantity\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"categoryId\"\r\n\r\n665f1b2c9a1e4d0012ab3c30\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"imageUrl\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://staging.api.payluk.ng/v1/escrow/create"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"amount\"\r\n\r\n150000\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\nMacBook Pro 14\"\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"whoPays\"\r\n\r\nboth\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"maxDelivery\"\r\n\r\n3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"deliveryTimeline\"\r\n\r\ndays\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nSpace grey, sealed\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"totalQuantity\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"categoryId\"\r\n\r\n665f1b2c9a1e4d0012ab3c30\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"imageUrl\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://staging.api.payluk.ng/v1/escrow/create")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"amount\"\r\n\r\n150000\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\nMacBook Pro 14\"\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"whoPays\"\r\n\r\nboth\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"maxDelivery\"\r\n\r\n3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"deliveryTimeline\"\r\n\r\ndays\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nSpace grey, sealed\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"totalQuantity\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"categoryId\"\r\n\r\n665f1b2c9a1e4d0012ab3c30\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"imageUrl\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/escrow/create")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"amount\"\r\n\r\n150000\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\nMacBook Pro 14\"\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"whoPays\"\r\n\r\nboth\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"maxDelivery\"\r\n\r\n3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"deliveryTimeline\"\r\n\r\ndays\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nSpace grey, sealed\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"totalQuantity\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"categoryId\"\r\n\r\n665f1b2c9a1e4d0012ab3c30\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"imageUrl\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"status": 201,
"message": "Created successfully",
"data": {
"id": "665f1b2c9a1e4d0012ab3c10",
"amount": 150000,
"purpose": "MacBook Pro 14\"",
"description": "Space grey, sealed",
"whoPays": "both",
"imageUrl": [
"https://cdn.payluk.ng/escrow/abc.png"
],
"fee": 3750,
"paymentToken": "PY_8AB12C9D3045",
"paidAt": null,
"status": "PENDING",
"state": "AWAITING_PAYMENT",
"logs": [],
"channel": "API",
"isSeller": true,
"dispute": null,
"paymentDetails": null,
"category": null,
"completedAt": null,
"approvedClaimBy": null,
"refundedBy": null,
"maxDelivery": 3,
"deliveryTimeline": "days",
"totalQuantity": 1,
"settlementType": "STANDARD",
"milestones": [],
"createdAt": "2026-06-22T10:15:00.000Z",
"updatedAt": "2026-06-22T10:15:00.000Z"
}
}Create escrow
Generates a standard escrow payment link. Sent as multipart/form-data so up to 5 images can be attached under imageUrl.
The seller is the account the request acts as: send customer-id with the selling customer’s id. Omit the header only if your merchant account is itself a business account and is the seller; a merchant that is not a business account gets 401 Merchant cannot create escrow for itself via API.
amount, purpose, whoPays, maxDelivery and deliveryTimeline are all required. Amounts are naira with at most two decimal places (kobo), minimum 1000. maxDelivery is 1 to 365 deliveryTimeline units.
curl --request POST \
--url https://staging.api.payluk.ng/v1/escrow/create \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form amount=150000 \
--form 'purpose=MacBook Pro 14"' \
--form whoPays=both \
--form maxDelivery=3 \
--form deliveryTimeline=days \
--form 'description=Space grey, sealed' \
--form totalQuantity=1 \
--form categoryId=665f1b2c9a1e4d0012ab3c30 \
--form imageUrl='@example-file'import requests
url = "https://staging.api.payluk.ng/v1/escrow/create"
files = { "imageUrl": ("example-file", open("example-file", "rb")) }
payload = {
"amount": "150000",
"purpose": "MacBook Pro 14\"",
"whoPays": "both",
"maxDelivery": "3",
"deliveryTimeline": "days",
"description": "Space grey, sealed",
"totalQuantity": "1",
"categoryId": "665f1b2c9a1e4d0012ab3c30"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('amount', '150000');
form.append('purpose', 'MacBook Pro 14"');
form.append('whoPays', 'both');
form.append('maxDelivery', '3');
form.append('deliveryTimeline', 'days');
form.append('description', 'Space grey, sealed');
form.append('totalQuantity', '1');
form.append('categoryId', '665f1b2c9a1e4d0012ab3c30');
form.append('imageUrl', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://staging.api.payluk.ng/v1/escrow/create', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://staging.api.payluk.ng/v1/escrow/create",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"amount\"\r\n\r\n150000\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\nMacBook Pro 14\"\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"whoPays\"\r\n\r\nboth\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"maxDelivery\"\r\n\r\n3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"deliveryTimeline\"\r\n\r\ndays\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nSpace grey, sealed\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"totalQuantity\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"categoryId\"\r\n\r\n665f1b2c9a1e4d0012ab3c30\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"imageUrl\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://staging.api.payluk.ng/v1/escrow/create"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"amount\"\r\n\r\n150000\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\nMacBook Pro 14\"\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"whoPays\"\r\n\r\nboth\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"maxDelivery\"\r\n\r\n3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"deliveryTimeline\"\r\n\r\ndays\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nSpace grey, sealed\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"totalQuantity\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"categoryId\"\r\n\r\n665f1b2c9a1e4d0012ab3c30\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"imageUrl\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://staging.api.payluk.ng/v1/escrow/create")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"amount\"\r\n\r\n150000\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\nMacBook Pro 14\"\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"whoPays\"\r\n\r\nboth\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"maxDelivery\"\r\n\r\n3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"deliveryTimeline\"\r\n\r\ndays\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nSpace grey, sealed\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"totalQuantity\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"categoryId\"\r\n\r\n665f1b2c9a1e4d0012ab3c30\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"imageUrl\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/escrow/create")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"amount\"\r\n\r\n150000\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\nMacBook Pro 14\"\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"whoPays\"\r\n\r\nboth\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"maxDelivery\"\r\n\r\n3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"deliveryTimeline\"\r\n\r\ndays\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nSpace grey, sealed\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"totalQuantity\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"categoryId\"\r\n\r\n665f1b2c9a1e4d0012ab3c30\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"imageUrl\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"status": 201,
"message": "Created successfully",
"data": {
"id": "665f1b2c9a1e4d0012ab3c10",
"amount": 150000,
"purpose": "MacBook Pro 14\"",
"description": "Space grey, sealed",
"whoPays": "both",
"imageUrl": [
"https://cdn.payluk.ng/escrow/abc.png"
],
"fee": 3750,
"paymentToken": "PY_8AB12C9D3045",
"paidAt": null,
"status": "PENDING",
"state": "AWAITING_PAYMENT",
"logs": [],
"channel": "API",
"isSeller": true,
"dispute": null,
"paymentDetails": null,
"category": null,
"completedAt": null,
"approvedClaimBy": null,
"refundedBy": null,
"maxDelivery": 3,
"deliveryTimeline": "days",
"totalQuantity": 1,
"settlementType": "STANDARD",
"milestones": [],
"createdAt": "2026-06-22T10:15:00.000Z",
"updatedAt": "2026-06-22T10:15:00.000Z"
}
}Authorizations
Your secret key as a Bearer token. The key prefix selects the environment: sk_test_... (staging) or sk_live_... (production); a key on the wrong host is refused with 403 Unauthorized Access. Each key is limited to 10 requests per minute (429 beyond that) and, on production, to the IP addresses on your dashboard allowlist when one is configured.
Headers
The merchant customer this request acts on behalf of. Omit it to act as your own business account (only a business-type account can sell on its own behalf).
Body
Escrow amount in major units (NGN), not kobo: send 150000 for ₦150,000. Kobo are allowed as decimals (₦100.20 is 100.2) and are rounded to two places. Minimum 1000.
x >= 1000150000
Short title of what is being sold.
"MacBook Pro 14\""
Which party pays the Payluk fee.
buyer, seller, both "both"
Length of the delivery window, in deliveryTimeline units. Required. Between 1 and 365.
1 <= x <= 3653
Unit for maxDelivery. Required.
minutes, hours, days "days"
"Space grey, sealed"
Units for sale off this link. Above 1, each buyer's payment mints its own escrow; see the multi-quantity guide.
1
"665f1b2c9a1e4d0012ab3c30"
Product image. Attach the field up to 5 times to upload multiple images.