Get milestones
curl --request GET \
--url https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken} \
--header 'Authorization: Bearer <token>'import requests
url = "https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://staging.api.payluk.ng/v1/escrow/milestone/{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/{paymentToken}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken}"
req, _ := http.NewRequest("GET", url, nil)
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.get("https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Milestones fetched successfully",
"data": [
{
"id": "665f1b2c9a1e4d0012ab3c21",
"title": "Design",
"amount": 300000,
"dueDate": "2026-07-15",
"status": "RELEASED",
"releasedAt": "1750584900"
},
{
"id": "665f1b2c9a1e4d0012ab3c22",
"title": "Development",
"amount": 500000,
"dueDate": "2026-08-15",
"status": "PENDING",
"releasedAt": null
},
{
"id": "665f1b2c9a1e4d0012ab3c23",
"title": "Deployment",
"amount": 200000,
"dueDate": null,
"status": "PENDING",
"releasedAt": null
}
]
}{
"status": 400,
"message": "Escrow not found",
"data": {}
}{
"status": 429,
"message": "Too many request"
}4. Create the deal: Milestone Escrow
Get milestones
Returns the milestone list for an escrow, by payment token. Returns an empty array for standard (non-milestone) escrows.
GET
/
v1
/
escrow
/
milestone
/
{paymentToken}
Get milestones
curl --request GET \
--url https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken} \
--header 'Authorization: Bearer <token>'import requests
url = "https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://staging.api.payluk.ng/v1/escrow/milestone/{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/{paymentToken}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken}"
req, _ := http.NewRequest("GET", url, nil)
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.get("https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/escrow/milestone/{paymentToken}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Milestones fetched successfully",
"data": [
{
"id": "665f1b2c9a1e4d0012ab3c21",
"title": "Design",
"amount": 300000,
"dueDate": "2026-07-15",
"status": "RELEASED",
"releasedAt": "1750584900"
},
{
"id": "665f1b2c9a1e4d0012ab3c22",
"title": "Development",
"amount": 500000,
"dueDate": "2026-08-15",
"status": "PENDING",
"releasedAt": null
},
{
"id": "665f1b2c9a1e4d0012ab3c23",
"title": "Deployment",
"amount": 200000,
"dueDate": null,
"status": "PENDING",
"releasedAt": null
}
]
}{
"status": 400,
"message": "Escrow not found",
"data": {}
}{
"status": 429,
"message": "Too many request"
}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.
Path Parameters
The escrow's payment token (e.g. PY_8AB12C9D3045).