curl --request POST \
--url https://api.rach.finance/caas/v1/escrows/{id}/dispute \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"on_behalf_of": "BUYER",
"reason": "buyer confirmed delivery"
}
'import requests
url = "https://api.rach.finance/caas/v1/escrows/{id}/dispute"
payload = {
"on_behalf_of": "BUYER",
"reason": "buyer confirmed delivery"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({on_behalf_of: 'BUYER', reason: 'buyer confirmed delivery'})
};
fetch('https://api.rach.finance/caas/v1/escrows/{id}/dispute', 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://api.rach.finance/caas/v1/escrows/{id}/dispute",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'on_behalf_of' => 'BUYER',
'reason' => 'buyer confirmed delivery'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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://api.rach.finance/caas/v1/escrows/{id}/dispute"
payload := strings.NewReader("{\n \"on_behalf_of\": \"BUYER\",\n \"reason\": \"buyer confirmed delivery\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
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.post("https://api.rach.finance/caas/v1/escrows/{id}/dispute")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"on_behalf_of\": \"BUYER\",\n \"reason\": \"buyer confirmed delivery\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rach.finance/caas/v1/escrows/{id}/dispute")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"on_behalf_of\": \"BUYER\",\n \"reason\": \"buyer confirmed delivery\"\n}"
response = http.request(request)
puts response.read_body{
"amount": "250000000",
"auto_release_at": "<string>",
"chain_id": 123,
"created_at": "<string>",
"dispute_reason": "<string>",
"disputed_at": "<string>",
"escrow_address": "<string>",
"funded_at": "<string>",
"funding_expires_at": "<string>",
"id": "<string>",
"network": "<string>",
"payout_pending": true,
"payout_tx_hash": "<string>",
"rail": "<string>",
"reference": "<string>",
"refunded_at": "<string>",
"released_at": "<string>",
"resolution_note": "<string>",
"state": "CREATED",
"token": "<string>",
"updated_at": "<string>"
}{}{}Raise a dispute
Records a nonempty reason and changes FUNDED to DISPUTED. Disputed escrows are excluded from timer release and require a Rach decision. This is a reason/history API, not evidence uploads, appeals or a contractual dispute SLA. A payout already claimed causes a conflict; a dispute cannot recall a broadcast transaction. Disputes and payouts serialize against the same escrow row. on_behalf_of records the partner’s assertion only.
curl --request POST \
--url https://api.rach.finance/caas/v1/escrows/{id}/dispute \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"on_behalf_of": "BUYER",
"reason": "buyer confirmed delivery"
}
'import requests
url = "https://api.rach.finance/caas/v1/escrows/{id}/dispute"
payload = {
"on_behalf_of": "BUYER",
"reason": "buyer confirmed delivery"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({on_behalf_of: 'BUYER', reason: 'buyer confirmed delivery'})
};
fetch('https://api.rach.finance/caas/v1/escrows/{id}/dispute', 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://api.rach.finance/caas/v1/escrows/{id}/dispute",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'on_behalf_of' => 'BUYER',
'reason' => 'buyer confirmed delivery'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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://api.rach.finance/caas/v1/escrows/{id}/dispute"
payload := strings.NewReader("{\n \"on_behalf_of\": \"BUYER\",\n \"reason\": \"buyer confirmed delivery\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
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.post("https://api.rach.finance/caas/v1/escrows/{id}/dispute")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"on_behalf_of\": \"BUYER\",\n \"reason\": \"buyer confirmed delivery\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rach.finance/caas/v1/escrows/{id}/dispute")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"on_behalf_of\": \"BUYER\",\n \"reason\": \"buyer confirmed delivery\"\n}"
response = http.request(request)
puts response.read_body{
"amount": "250000000",
"auto_release_at": "<string>",
"chain_id": 123,
"created_at": "<string>",
"dispute_reason": "<string>",
"disputed_at": "<string>",
"escrow_address": "<string>",
"funded_at": "<string>",
"funding_expires_at": "<string>",
"id": "<string>",
"network": "<string>",
"payout_pending": true,
"payout_tx_hash": "<string>",
"rail": "<string>",
"reference": "<string>",
"refunded_at": "<string>",
"released_at": "<string>",
"resolution_note": "<string>",
"state": "CREATED",
"token": "<string>",
"updated_at": "<string>"
}{}{}Authorizations
Your Rach B2B API key. Use rach_sk_live_* for production (on-chain) or rach_sk_test_* for sandbox (no-chain simulation).
Path Parameters
Escrow id
Body
Reason is required
OnBehalfOf is BUYER or SELLER when the partner is acting for one of its users. It is recorded as evidence of what the partner asserted; the authority for the action remains the partner's own and is recorded separately. Omit it when the partner is acting in its own right.
"BUYER"
Reason is required to raise a dispute and optional elsewhere. It becomes part of the escrow's permanent history.
"buyer confirmed delivery"
Response
Accepted
Amount is in base units, unlike the create request's whole-token amount. For the implemented TRON USDT adapter, "250000000" means 250 USDT.
"250000000"
AutoReleaseAt is when a funded escrow releases to the seller with no further action. Absent means it never does and someone must decide.
EscrowAddress is where the buyer sends the money. It belongs to this deal alone and is never reused.
FundingExpiresAt is when an unpaid escrow closes.
PayoutPending is true while a payout has been authorised and dispatched but not yet confirmed. Surfaced rather than hidden because during this window the honest answer to "has the seller been paid" is "not yet".
PayoutTxHash is the on-chain transaction that moved the money out. It is the partner's evidence that a release or refund really happened.
Recorded admin reasoning once a disputed payout settles.
CREATED, FUNDED, DISPUTED, RELEASED, REFUNDED, EXPIRED, CANCELLED 
