curl --request PUT \
--url https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'customer-id: <customer-id>' \
--data '
{
"amount": 1200000,
"purpose": "Company website build (revised scope)",
"description": "3-phase delivery (updated budget)",
"whoPays": "buyer",
"maxDelivery": 45,
"deliveryTimeline": "days",
"totalQuantity": 1,
"categoryId": "665f1b2c9a1e4d0012ab3c30",
"milestones": [
{
"title": "Design",
"description": "Figma mockups",
"amount": 400000,
"dueDate": "2026-07-20",
"customerId": "665f1b2c9a1e4d0012ab3c40"
},
{
"title": "Development",
"description": "Frontend + backend",
"amount": 600000,
"dueDate": "2026-08-20"
},
{
"title": "Deployment",
"description": "Go-live + handover",
"amount": 200000
}
]
}
'import requests
url = "https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken}"
payload = {
"amount": 1200000,
"purpose": "Company website build (revised scope)",
"description": "3-phase delivery (updated budget)",
"whoPays": "buyer",
"maxDelivery": 45,
"deliveryTimeline": "days",
"totalQuantity": 1,
"categoryId": "665f1b2c9a1e4d0012ab3c30",
"milestones": [
{
"title": "Design",
"description": "Figma mockups",
"amount": 400000,
"dueDate": "2026-07-20",
"customerId": "665f1b2c9a1e4d0012ab3c40"
},
{
"title": "Development",
"description": "Frontend + backend",
"amount": 600000,
"dueDate": "2026-08-20"
},
{
"title": "Deployment",
"description": "Go-live + handover",
"amount": 200000
}
]
}
headers = {
"customer-id": "<customer-id>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'customer-id': '<customer-id>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 1200000,
purpose: 'Company website build (revised scope)',
description: '3-phase delivery (updated budget)',
whoPays: 'buyer',
maxDelivery: 45,
deliveryTimeline: 'days',
totalQuantity: 1,
categoryId: '665f1b2c9a1e4d0012ab3c30',
milestones: [
{
title: 'Design',
description: 'Figma mockups',
amount: 400000,
dueDate: '2026-07-20',
customerId: '665f1b2c9a1e4d0012ab3c40'
},
{
title: 'Development',
description: 'Frontend + backend',
amount: 600000,
dueDate: '2026-08-20'
},
{title: 'Deployment', description: 'Go-live + handover', amount: 200000}
]
})
};
fetch('https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken}', 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/milestone/edit/{paymentToken}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 1200000,
'purpose' => 'Company website build (revised scope)',
'description' => '3-phase delivery (updated budget)',
'whoPays' => 'buyer',
'maxDelivery' => 45,
'deliveryTimeline' => 'days',
'totalQuantity' => 1,
'categoryId' => '665f1b2c9a1e4d0012ab3c30',
'milestones' => [
[
'title' => 'Design',
'description' => 'Figma mockups',
'amount' => 400000,
'dueDate' => '2026-07-20',
'customerId' => '665f1b2c9a1e4d0012ab3c40'
],
[
'title' => 'Development',
'description' => 'Frontend + backend',
'amount' => 600000,
'dueDate' => '2026-08-20'
],
[
'title' => 'Deployment',
'description' => 'Go-live + handover',
'amount' => 200000
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"customer-id: <customer-id>"
],
]);
$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/milestone/edit/{paymentToken}"
payload := strings.NewReader("{\n \"amount\": 1200000,\n \"purpose\": \"Company website build (revised scope)\",\n \"description\": \"3-phase delivery (updated budget)\",\n \"whoPays\": \"buyer\",\n \"maxDelivery\": 45,\n \"deliveryTimeline\": \"days\",\n \"totalQuantity\": 1,\n \"categoryId\": \"665f1b2c9a1e4d0012ab3c30\",\n \"milestones\": [\n {\n \"title\": \"Design\",\n \"description\": \"Figma mockups\",\n \"amount\": 400000,\n \"dueDate\": \"2026-07-20\",\n \"customerId\": \"665f1b2c9a1e4d0012ab3c40\"\n },\n {\n \"title\": \"Development\",\n \"description\": \"Frontend + backend\",\n \"amount\": 600000,\n \"dueDate\": \"2026-08-20\"\n },\n {\n \"title\": \"Deployment\",\n \"description\": \"Go-live + handover\",\n \"amount\": 200000\n }\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("customer-id", "<customer-id>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken}")
.header("customer-id", "<customer-id>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 1200000,\n \"purpose\": \"Company website build (revised scope)\",\n \"description\": \"3-phase delivery (updated budget)\",\n \"whoPays\": \"buyer\",\n \"maxDelivery\": 45,\n \"deliveryTimeline\": \"days\",\n \"totalQuantity\": 1,\n \"categoryId\": \"665f1b2c9a1e4d0012ab3c30\",\n \"milestones\": [\n {\n \"title\": \"Design\",\n \"description\": \"Figma mockups\",\n \"amount\": 400000,\n \"dueDate\": \"2026-07-20\",\n \"customerId\": \"665f1b2c9a1e4d0012ab3c40\"\n },\n {\n \"title\": \"Development\",\n \"description\": \"Frontend + backend\",\n \"amount\": 600000,\n \"dueDate\": \"2026-08-20\"\n },\n {\n \"title\": \"Deployment\",\n \"description\": \"Go-live + handover\",\n \"amount\": 200000\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["customer-id"] = '<customer-id>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 1200000,\n \"purpose\": \"Company website build (revised scope)\",\n \"description\": \"3-phase delivery (updated budget)\",\n \"whoPays\": \"buyer\",\n \"maxDelivery\": 45,\n \"deliveryTimeline\": \"days\",\n \"totalQuantity\": 1,\n \"categoryId\": \"665f1b2c9a1e4d0012ab3c30\",\n \"milestones\": [\n {\n \"title\": \"Design\",\n \"description\": \"Figma mockups\",\n \"amount\": 400000,\n \"dueDate\": \"2026-07-20\",\n \"customerId\": \"665f1b2c9a1e4d0012ab3c40\"\n },\n {\n \"title\": \"Development\",\n \"description\": \"Frontend + backend\",\n \"amount\": 600000,\n \"dueDate\": \"2026-08-20\"\n },\n {\n \"title\": \"Deployment\",\n \"description\": \"Go-live + handover\",\n \"amount\": 200000\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Milestone escrow updated successfully",
"data": {
"id": "665f1b2c9a1e4d0012ab3c10",
"amount": 1200000,
"purpose": "Company website build (revised scope)",
"whoPays": "buyer",
"fee": 30000,
"paymentToken": "PY_8AB12C9D3045",
"status": "PENDING",
"state": "AWAITING_PAYMENT",
"settlementType": "MILESTONE",
"milestones": [
{
"id": "665f1b2c9a1e4d0012ab3c24",
"title": "Design",
"description": "Figma mockups",
"amount": 400000,
"dueDate": "2026-07-20",
"status": "PENDING",
"releasedAt": null
},
{
"id": "665f1b2c9a1e4d0012ab3c25",
"title": "Development",
"description": "Frontend + backend",
"amount": 600000,
"dueDate": "2026-08-20",
"status": "PENDING",
"releasedAt": null
},
{
"id": "665f1b2c9a1e4d0012ab3c26",
"title": "Deployment",
"description": "Go-live + handover",
"amount": 200000,
"dueDate": null,
"status": "PENDING",
"releasedAt": null
}
],
"updatedAt": "2026-06-23T09:30:00.000Z"
}
}Edit milestone escrow
Replaces the details and the full milestone set of a milestone escrow (JSON body, no file upload). Editable only while the escrow is still AWAITING_PAYMENT, and only by the seller that created it. The same rules as creation apply: at least 2 milestones, every milestone amount is a positive integer, and the sum of milestone amounts must equal amount. The platform fee is recalculated from the new amount and the milestone ids are regenerated. Requires the customer-id header (the seller).
curl --request PUT \
--url https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'customer-id: <customer-id>' \
--data '
{
"amount": 1200000,
"purpose": "Company website build (revised scope)",
"description": "3-phase delivery (updated budget)",
"whoPays": "buyer",
"maxDelivery": 45,
"deliveryTimeline": "days",
"totalQuantity": 1,
"categoryId": "665f1b2c9a1e4d0012ab3c30",
"milestones": [
{
"title": "Design",
"description": "Figma mockups",
"amount": 400000,
"dueDate": "2026-07-20",
"customerId": "665f1b2c9a1e4d0012ab3c40"
},
{
"title": "Development",
"description": "Frontend + backend",
"amount": 600000,
"dueDate": "2026-08-20"
},
{
"title": "Deployment",
"description": "Go-live + handover",
"amount": 200000
}
]
}
'import requests
url = "https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken}"
payload = {
"amount": 1200000,
"purpose": "Company website build (revised scope)",
"description": "3-phase delivery (updated budget)",
"whoPays": "buyer",
"maxDelivery": 45,
"deliveryTimeline": "days",
"totalQuantity": 1,
"categoryId": "665f1b2c9a1e4d0012ab3c30",
"milestones": [
{
"title": "Design",
"description": "Figma mockups",
"amount": 400000,
"dueDate": "2026-07-20",
"customerId": "665f1b2c9a1e4d0012ab3c40"
},
{
"title": "Development",
"description": "Frontend + backend",
"amount": 600000,
"dueDate": "2026-08-20"
},
{
"title": "Deployment",
"description": "Go-live + handover",
"amount": 200000
}
]
}
headers = {
"customer-id": "<customer-id>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'customer-id': '<customer-id>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 1200000,
purpose: 'Company website build (revised scope)',
description: '3-phase delivery (updated budget)',
whoPays: 'buyer',
maxDelivery: 45,
deliveryTimeline: 'days',
totalQuantity: 1,
categoryId: '665f1b2c9a1e4d0012ab3c30',
milestones: [
{
title: 'Design',
description: 'Figma mockups',
amount: 400000,
dueDate: '2026-07-20',
customerId: '665f1b2c9a1e4d0012ab3c40'
},
{
title: 'Development',
description: 'Frontend + backend',
amount: 600000,
dueDate: '2026-08-20'
},
{title: 'Deployment', description: 'Go-live + handover', amount: 200000}
]
})
};
fetch('https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken}', 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/milestone/edit/{paymentToken}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 1200000,
'purpose' => 'Company website build (revised scope)',
'description' => '3-phase delivery (updated budget)',
'whoPays' => 'buyer',
'maxDelivery' => 45,
'deliveryTimeline' => 'days',
'totalQuantity' => 1,
'categoryId' => '665f1b2c9a1e4d0012ab3c30',
'milestones' => [
[
'title' => 'Design',
'description' => 'Figma mockups',
'amount' => 400000,
'dueDate' => '2026-07-20',
'customerId' => '665f1b2c9a1e4d0012ab3c40'
],
[
'title' => 'Development',
'description' => 'Frontend + backend',
'amount' => 600000,
'dueDate' => '2026-08-20'
],
[
'title' => 'Deployment',
'description' => 'Go-live + handover',
'amount' => 200000
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"customer-id: <customer-id>"
],
]);
$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/milestone/edit/{paymentToken}"
payload := strings.NewReader("{\n \"amount\": 1200000,\n \"purpose\": \"Company website build (revised scope)\",\n \"description\": \"3-phase delivery (updated budget)\",\n \"whoPays\": \"buyer\",\n \"maxDelivery\": 45,\n \"deliveryTimeline\": \"days\",\n \"totalQuantity\": 1,\n \"categoryId\": \"665f1b2c9a1e4d0012ab3c30\",\n \"milestones\": [\n {\n \"title\": \"Design\",\n \"description\": \"Figma mockups\",\n \"amount\": 400000,\n \"dueDate\": \"2026-07-20\",\n \"customerId\": \"665f1b2c9a1e4d0012ab3c40\"\n },\n {\n \"title\": \"Development\",\n \"description\": \"Frontend + backend\",\n \"amount\": 600000,\n \"dueDate\": \"2026-08-20\"\n },\n {\n \"title\": \"Deployment\",\n \"description\": \"Go-live + handover\",\n \"amount\": 200000\n }\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("customer-id", "<customer-id>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken}")
.header("customer-id", "<customer-id>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 1200000,\n \"purpose\": \"Company website build (revised scope)\",\n \"description\": \"3-phase delivery (updated budget)\",\n \"whoPays\": \"buyer\",\n \"maxDelivery\": 45,\n \"deliveryTimeline\": \"days\",\n \"totalQuantity\": 1,\n \"categoryId\": \"665f1b2c9a1e4d0012ab3c30\",\n \"milestones\": [\n {\n \"title\": \"Design\",\n \"description\": \"Figma mockups\",\n \"amount\": 400000,\n \"dueDate\": \"2026-07-20\",\n \"customerId\": \"665f1b2c9a1e4d0012ab3c40\"\n },\n {\n \"title\": \"Development\",\n \"description\": \"Frontend + backend\",\n \"amount\": 600000,\n \"dueDate\": \"2026-08-20\"\n },\n {\n \"title\": \"Deployment\",\n \"description\": \"Go-live + handover\",\n \"amount\": 200000\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/escrow/milestone/edit/{paymentToken}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["customer-id"] = '<customer-id>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 1200000,\n \"purpose\": \"Company website build (revised scope)\",\n \"description\": \"3-phase delivery (updated budget)\",\n \"whoPays\": \"buyer\",\n \"maxDelivery\": 45,\n \"deliveryTimeline\": \"days\",\n \"totalQuantity\": 1,\n \"categoryId\": \"665f1b2c9a1e4d0012ab3c30\",\n \"milestones\": [\n {\n \"title\": \"Design\",\n \"description\": \"Figma mockups\",\n \"amount\": 400000,\n \"dueDate\": \"2026-07-20\",\n \"customerId\": \"665f1b2c9a1e4d0012ab3c40\"\n },\n {\n \"title\": \"Development\",\n \"description\": \"Frontend + backend\",\n \"amount\": 600000,\n \"dueDate\": \"2026-08-20\"\n },\n {\n \"title\": \"Deployment\",\n \"description\": \"Go-live + handover\",\n \"amount\": 200000\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Milestone escrow updated successfully",
"data": {
"id": "665f1b2c9a1e4d0012ab3c10",
"amount": 1200000,
"purpose": "Company website build (revised scope)",
"whoPays": "buyer",
"fee": 30000,
"paymentToken": "PY_8AB12C9D3045",
"status": "PENDING",
"state": "AWAITING_PAYMENT",
"settlementType": "MILESTONE",
"milestones": [
{
"id": "665f1b2c9a1e4d0012ab3c24",
"title": "Design",
"description": "Figma mockups",
"amount": 400000,
"dueDate": "2026-07-20",
"status": "PENDING",
"releasedAt": null
},
{
"id": "665f1b2c9a1e4d0012ab3c25",
"title": "Development",
"description": "Frontend + backend",
"amount": 600000,
"dueDate": "2026-08-20",
"status": "PENDING",
"releasedAt": null
},
{
"id": "665f1b2c9a1e4d0012ab3c26",
"title": "Deployment",
"description": "Go-live + handover",
"amount": 200000,
"dueDate": null,
"status": "PENDING",
"releasedAt": null
}
],
"updatedAt": "2026-06-23T09:30:00.000Z"
}
}Authorizations
Your secret key as a Bearer token. The key prefix selects the environment: sk_test_... (test) or sk_live_... (live).
Headers
The merchant customer this request acts on behalf of.
Path Parameters
The escrow's payment token (e.g. PY_8AB12C9D3045).
Body
1000000
"Company website build"
For milestone escrows the buyer always pays the Payluk fee; buyer is the only accepted value.
buyer "buyer"
At least 2 milestones whose amounts sum to amount.
2Show child attributes
Show child attributes
"3-phase delivery"
30
minutes, hours, days "days"
1
"665f1b2c9a1e4d0012ab3c30"