Handling disputes
A dispute stops the money from moving while RekberPay looks at what happened. In this run Rina paid Rp300.000 for a logo design from Budi, the work did not match the brief, and she opens a dispute.
When a dispute is possible
Either party can open one while the escrow is paid, sent or received. Before payment, cancel the escrow instead. After release, the money has left escrow and a dispute is no longer possible.
1. Open the dispute
curl -X POST https://api.rekberpay.com/v1/escrows/55555551-5555-4555-8555-555555555555/dispute \
-H "Authorization: Bearer $REKBERPAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason_category": "item_not_as_described",
"description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati."
}'const res = await fetch('https://api.rekberpay.com/v1/escrows/55555551-5555-4555-8555-555555555555/dispute', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
reason_category: "item_not_as_described",
description: "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati."
}),
});
const data = await res.json();import os
import requests
resp = requests.post(
"https://api.rekberpay.com/v1/escrows/55555551-5555-4555-8555-555555555555/dispute",
headers={
"Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
},
json={
"reason_category": "item_not_as_described",
"description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.",
},
timeout=30,
)
print(resp.status_code, resp.json())<?php
$ch = curl_init('https://api.rekberpay.com/v1/escrows/55555551-5555-4555-8555-555555555555/dispute');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'reason_category' => 'item_not_as_described',
'description' => 'Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.',
]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);201 Created
{
"success": true,
"data": {
"id": "77777771-7777-4777-8777-777777777777",
"escrow_id": "55555551-5555-4555-8555-555555555555",
"initiator_id": "11111110-1111-4111-8111-111111111111",
"reason_category": "item_not_as_described",
"description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.",
"status": "open",
"priority": "normal",
"resolution_note": null,
"resolved_by": null,
"resolved_at": null,
"created_at": "2026-10-13T14:23:18.823Z",
"updated_at": "2026-10-13T14:23:18.823Z"
}
}The escrow is now disputed and both sides and RekberPay are notified. A second dispute on the same escrow is refused:
409 Conflict
{
"success": false,
"error": {
"code": "NOT_DISPUTABLE",
"message": "Cannot dispute escrow in state: disputed. Must be: paid, sent, received"
}
}description is required:
400 Bad Request
{
"success": false,
"error": {
"code": "INVALID_BODY",
"message": "Validasi gagal",
"details": {
"formErrors": [],
"fieldErrors": {
"description": [
"Too small: expected string to have >=1 characters"
]
}
}
}
}2. Add evidence
Upload files with POST /v1/upload/escrow, then post them in the dispute thread. Both parties and RekberPay staff write in the same thread.
curl -X POST https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages \
-H "Authorization: Bearer $REKBERPAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Saya lampirkan brief awal dan hasil yang diterima.",
"evidence_urls": [
"https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png"
]
}'const res = await fetch('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: "Saya lampirkan brief awal dan hasil yang diterima.",
evidence_urls: [
"https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png"
]
}),
});
const data = await res.json();import os
import requests
resp = requests.post(
"https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages",
headers={
"Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
},
json={
"message": "Saya lampirkan brief awal dan hasil yang diterima.",
"evidence_urls": [
"https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png",
],
},
timeout=30,
)
print(resp.status_code, resp.json())<?php
$ch = curl_init('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'message' => 'Saya lampirkan brief awal dan hasil yang diterima.',
'evidence_urls' => [
'https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png',
],
]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);201 Created
{
"success": true,
"data": {
"id": "99999991-9999-4999-8999-999999999999",
"dispute_id": "77777771-7777-4777-8777-777777777777",
"sender_id": "11111110-1111-4111-8111-111111111111",
"body": "Saya lampirkan brief awal dan hasil yang diterima.",
"attachment_url": "https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png?exp=1791979200000&sig=c0ffee5b1a9e3d7f4a2c8e6b0d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5",
"created_at": "2026-10-13T14:23:18.835Z"
}
}3. Follow the thread
Poll the messages. Send the newest created_at you have as after so each poll returns only new messages.
curl "https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages?limit=20" \
-H "Authorization: Bearer $REKBERPAY_API_KEY"const res = await fetch('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages?limit=20', {
headers: {
Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
},
});
const data = await res.json();import os
import requests
resp = requests.get(
"https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages?limit=20",
headers={
"Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
},
timeout=30,
)
print(resp.status_code, resp.json())<?php
$ch = curl_init('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages?limit=20');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);200 OK
{
"success": true,
"data": [
{
"id": "99999991-9999-4999-8999-999999999999",
"dispute_id": "77777771-7777-4777-8777-777777777777",
"sender_id": "11111110-1111-4111-8111-111111111111",
"body": "Saya lampirkan brief awal dan hasil yang diterima.",
"attachment_url": "https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png?exp=1791979200000&sig=c0ffee5b1a9e3d7f4a2c8e6b0d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5",
"created_at": "2026-10-13T14:23:18.835Z",
"sender_email": "[email protected]",
"sender_full_name": "Rina Wijaya",
"sender_role": "user",
"sender_participant_role": "buyer"
},
{
"id": "aaaaaaa1-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"dispute_id": "77777771-7777-4777-8777-777777777777",
"sender_id": "44444440-4444-4444-8444-444444444444",
"body": "Revisi bisa saya kirim besok pagi.",
"attachment_url": null,
"created_at": "2026-10-13T14:23:18.841Z",
"sender_email": null,
"sender_full_name": "Budi Santoso",
"sender_role": "user",
"sender_participant_role": "seller"
}
]
}4. Read the outcome
RekberPay resolves the dispute by releasing the money to the seller, refunding the buyer or holding it. Read the dispute (or the escrow) to see where it stands:
curl https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777 \
-H "Authorization: Bearer $REKBERPAY_API_KEY"const res = await fetch('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777', {
headers: {
Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
},
});
const data = await res.json();import os
import requests
resp = requests.get(
"https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777",
headers={
"Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
},
timeout=30,
)
print(resp.status_code, resp.json())<?php
$ch = curl_init('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);200 OK
{
"success": true,
"data": {
"id": "77777771-7777-4777-8777-777777777777",
"escrow_id": "55555551-5555-4555-8555-555555555555",
"initiator_id": "11111110-1111-4111-8111-111111111111",
"reason_category": "item_not_as_described",
"description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.",
"status": "open",
"priority": "normal",
"resolution_note": null,
"resolved_by": null,
"resolved_at": null,
"created_at": "2026-10-13T14:23:18.823Z",
"updated_at": "2026-10-13T14:23:18.823Z",
"item_name": "Jasa desain logo toko",
"amount": "300000.00",
"escrow_status": "disputed",
"buyer_id": "11111110-1111-4111-8111-111111111111",
"seller_id": "44444440-4444-4444-8444-444444444444",
"buyer_email": "[email protected]",
"buyer_full_name": "Rina Wijaya",
"seller_email": null,
"seller_full_name": "Budi Santoso"
}
}When it is resolved, status changes and resolution_note explains the decision. The escrow becomes released, refunded or hold.
List every dispute
curl "https://api.rekberpay.com/v1/disputes?limit=5" \
-H "Authorization: Bearer $REKBERPAY_API_KEY"const res = await fetch('https://api.rekberpay.com/v1/disputes?limit=5', {
headers: {
Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
},
});
const data = await res.json();import os
import requests
resp = requests.get(
"https://api.rekberpay.com/v1/disputes?limit=5",
headers={
"Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
},
timeout=30,
)
print(resp.status_code, resp.json())<?php
$ch = curl_init('https://api.rekberpay.com/v1/disputes?limit=5');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);200 OK
{
"success": true,
"data": [
{
"id": "77777771-7777-4777-8777-777777777777",
"escrow_id": "55555551-5555-4555-8555-555555555555",
"initiator_id": "11111110-1111-4111-8111-111111111111",
"reason_category": "item_not_as_described",
"description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.",
"status": "open",
"priority": "normal",
"resolution_note": null,
"resolved_by": null,
"resolved_at": null,
"created_at": "2026-10-13T14:23:18.823Z",
"updated_at": "2026-10-13T14:23:18.823Z",
"item_name": "Jasa desain logo toko",
"amount": "300000.00",
"escrow_status": "disputed",
"buyer_id": "11111110-1111-4111-8111-111111111111",
"seller_id": "44444440-4444-4444-8444-444444444444",
"buyer_email": "[email protected]",
"buyer_full_name": "Rina Wijaya",
"seller_email": null,
"seller_full_name": "Budi Santoso"
}
],
"pagination": {
"page": 1,
"limit": 5,
"total": "1"
}
}Tips
- Open a dispute only after talking in the escrow chat; many problems are solved there.
- Put the facts and the evidence in the first message: what was agreed, what arrived, and photos or files.
- Do not open a second escrow for the same order while a dispute is open.
Next steps
- Disputes reference
- Enterprise milestones have their own dispute call