Skip to content

Enterprise deals and milestones ​

A deal holds 1 to 20 milestones. Each milestone is funded, gets evidence, is approved and is released on its own. The deal's total_amount, funded_amount, released_amount and status are always worked out from its milestones; you never set them. Auth, roles, the workspace header and the shared limits are explained in Enterprise overview.

Endpoints ​

MethodPathEndpointAuth
GET/v1/enterprise/dealsList dealsviewer
GET/v1/enterprise/deals/:idGet a dealviewer
POST/v1/enterprise/dealsCreate a dealoperator
PATCH/v1/enterprise/deals/:idUpdate a draft dealoperator
POST/v1/enterprise/deals/:id/milestonesAdd a milestoneoperator
PATCH/v1/enterprise/deals/:id/milestones/:midUpdate a draft milestoneoperator
POST/v1/enterprise/deals/:id/activateActivate a dealoperator
POST/v1/enterprise/deals/:id/cancelCancel a dealoperator
POST/v1/enterprise/deals/:id/milestones/:mid/fundFund a milestone (sandbox)finance
POST/v1/enterprise/deals/:id/milestones/:mid/submit-evidenceSubmit evidenceoperator
POST/v1/enterprise/deals/:id/milestones/:mid/disputeDispute a milestoneoperator

Milestone and deal statuses ​

text
Milestone:  draft -> awaiting_funding -> funded -> evidence_submitted -> approved -> released
                                           |              |      \
                                           |              |       -> revision_requested -> evidence_submitted
                                           +--------------+--------> disputed (from funded, evidence_submitted or approved)

A deal is draft, awaiting_funding, funded, in_progress (at least one milestone released), disputed (any milestone disputed), completed (every live milestone released) or cancelled.

Write routes on this page honour Idempotency-Key. Send one on every create, fund, evidence and dispute call.


List deals ​

GET/v1/enterprise/deals

Deals newest first, with amounts, the counterparty name and milestone counts.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: Any workspace member (viewer and up).
  • Rate limit: 300 requests a minute per user, shared by every route.
  • Idempotency: Not needed. Reading has no side effects.

Query parameters ​

NameTypeRequiredDescription
statusstringNoOne deal status
qstringNoTitle or reference contains, up to 100 characters
pageintegerNoDefault 1
limitintegerNo1 to 50. Default 20

Example request ​

bash
curl "https://api.rekberpay.com/v1/enterprise/deals?limit=2" \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals?limit=2', {
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.get(
    "https://api.rekberpay.com/v1/enterprise/deals?limit=2",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals?limit=2');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
    ],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": [
        {
            "id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
            "reference": "DEAL-2026-0009",
            "title": "Packaging run Q4",
            "status": "disputed",
            "currency": "IDR",
            "total_amount": 60000000,
            "funded_amount": 50000000,
            "released_amount": 30000000,
            "cross_border": false,
            "counterparty_name": "Harbourline Components Pte Ltd",
            "milestone_count": 3,
            "released_count": 1,
            "created_at": "2026-10-13T14:33:16.361Z",
            "updated_at": "2026-10-13T14:33:16.496Z"
        },
        {
            "id": "99999996-9999-4999-8999-999999999999",
            "reference": "DEAL-2026-0008",
            "title": "Spare parts framework, 2027",
            "status": "draft",
            "currency": "IDR",
            "total_amount": 60000000,
            "funded_amount": 0,
            "released_amount": 0,
            "cross_border": true,
            "counterparty_name": "Selangor Precision Parts Sdn Bhd",
            "milestone_count": 2,
            "released_count": 0,
            "created_at": "2026-10-12T18:33:06.162Z",
            "updated_at": "2026-10-13T14:33:06.237Z"
        }
    ],
    "pagination": {
        "page": 1,
        "limit": 2,
        "total": 9,
        "total_pages": 5
    }
}

Errors ​

StatusCodeCause
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Get a deal ​

GET/v1/enterprise/deals/:id

The deal, every milestone with its approvals, documents and payouts, the last 100 events of the deal and an outcome summary.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: Any workspace member (viewer and up).
  • Rate limit: 300 requests a minute per user, shared by every route.
  • Idempotency: Not needed. Reading has no side effects.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID

Example request ​

bash
curl https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee', {
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.get(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
    ],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": {
        "deal": {
            "id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
            "reference": "DEAL-2026-0009",
            "title": "Packaging run Q4",
            "description": "Printed cartons for the Q4 export order, 2 colours.",
            "external_ref": "PO-2026-1188",
            "status": "disputed",
            "currency": "IDR",
            "total_amount": 60000000,
            "funded_amount": 50000000,
            "released_amount": 30000000,
            "cross_border": false,
            "owner": {
                "id": "33333333-3333-4333-8333-333333333333",
                "name": "Dimas Hidayat"
            },
            "created_at": "2026-10-13T14:33:16.361Z",
            "updated_at": "2026-10-13T14:33:16.496Z",
            "counterparty": {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd",
                "country_code": "SG",
                "kyb_status": "verified",
                "relationship": "seller"
            }
        },
        "milestones": [
            {
                "id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
                "sequence_no": 1,
                "title": "Tooling and proof approval",
                "required_evidence": "Signed proof sheet",
                "amount": 30000000,
                "status": "released",
                "due_at": null,
                "funded_at": "2026-10-13T14:33:16.404Z",
                "funding_method": "sandbox",
                "evidence_summary": "Proof sheet signed by both sides on 10 October.",
                "evidence_submitted_at": "2026-10-13T14:33:16.429Z",
                "approved_at": "2026-10-13T14:33:16.456Z",
                "released_at": "2026-10-13T14:33:16.480Z",
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [
                    {
                        "id": "eeeeeee5-eeee-4eee-8eee-eeeeeeeeeeee",
                        "approver": {
                            "id": "33333333-3333-4333-8333-333333333333",
                            "name": "Dimas Hidayat"
                        },
                        "status": "approved",
                        "note": "Proof matches the spec sheet.",
                        "decided_at": "2026-10-13T14:33:16.455Z"
                    }
                ],
                "documents": [
                    {
                        "id": "88888885-8888-4888-8888-888888888888",
                        "title": "Signed proof sheet",
                        "document_type": "inspection",
                        "file_url": "https://files.example.com/northline/proof-sheet-q4.pdf",
                        "checksum_sha256": "a3f1c2d4e5b60718293a4b5c6d7e8f90112233445566778899aabbccddeeff00",
                        "visibility": "account",
                        "uploaded_by": "33333333-3333-4333-8333-333333333333",
                        "created_at": "2026-10-13T14:33:16.424Z"
                    }
                ],
                "disbursements": [
                    {
                        "id": "55555556-5555-4555-8555-555555555555",
                        "amount": 5000000,
                        "status": "queued",
                        "instruction_label": "Harbourline freight and duties",
                        "settled_at": null
                    },
                    {
                        "id": "44444446-4444-4444-8444-444444444444",
                        "amount": 25000000,
                        "status": "queued",
                        "instruction_label": "Harbourline IDR collection account",
                        "settled_at": null
                    }
                ]
            },
            {
                "id": "11111115-1111-4111-8111-111111111111",
                "sequence_no": 2,
                "title": "First 20,000 cartons",
                "required_evidence": "Delivery note and inspection report",
                "amount": 20000000,
                "status": "disputed",
                "due_at": null,
                "funded_at": "2026-10-13T14:33:16.419Z",
                "funding_method": "sandbox",
                "evidence_summary": "Inspection report attached as requested by finance.",
                "evidence_submitted_at": "2026-10-13T14:33:16.488Z",
                "approved_at": null,
                "released_at": null,
                "disputed_at": "2026-10-13T14:33:16.495Z",
                "dispute_reason": "Supplier has not sent the inspection report after two requests.",
                "approvals_required": 1,
                "approvals": [
                    {
                        "id": "22222226-2222-4222-8222-222222222222",
                        "approver": {
                            "id": "77777776-7777-4777-8777-777777777777",
                            "name": "Maya Santoso"
                        },
                        "status": "revision_requested",
                        "note": "Inspection report is missing.",
                        "decided_at": "2026-10-13T14:33:16.464Z"
                    },
                    {
                        "id": "88888886-8888-4888-8888-888888888888",
                        "approver": null,
                        "status": "pending",
                        "note": null,
                        "decided_at": null
                    }
                ],
                "documents": [],
                "disbursements": []
            }
        ],
        "events": [
            {
                "seq": 140528,
                "event": "deal.created",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 50000000,
                "summary": "Created deal DEAL-2026-0009: Packaging run Q4",
                "created_at": "2026-10-13T14:33:16.361Z"
            },
            {
                "seq": 140529,
                "event": "deal.updated",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": null,
                "summary": "Updated deal DEAL-2026-0009",
                "created_at": "2026-10-13T14:33:16.369Z"
            }
        ],
        "outcome": {
            "time_to_release_minutes": 0,
            "approvals_by_people": 2,
            "revisions": 1
        }
    }
}

Lists are cut to the first 2 items and long text is shortened here.

FieldTypeDescription
dealobjectThe deal with its reference (for example DEAL-2026-0013), amounts, owner and counterparty
milestonesarrayEach with status, amount, approvals_required, approvals, documents, disbursements and timestamps
eventsarrayThe deal's latest events, newest first
outcomeobjecttime_to_release_minutes, approvals_by_people and revisions

Errors ​

StatusCodeCause
404NOT_FOUNDNo deal with this ID in the workspace
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Create a deal ​

POST/v1/enterprise/deals

Creates a draft deal with its milestones. Nothing can be funded until you activate it.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 300 requests a minute per user, shared by every route.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Body (JSON) ​

NameTypeRequiredDescription
titlestringYes2 to 180 characters
milestonesarrayYes1 to 20 milestones, see below
counterparty_idUUIDNoA counterparty of the workspace. Needed before activation
descriptionstringNoAt most 1,000 characters
external_refstringNoYour own reference, for example a PO number. At most 80 characters
currencystringNoThree letters. Default IDR
cross_borderbooleanNoDefault false
fee_allocationstringNoWho pays the platform fee: buyer (your workspace), seller (the counterparty) or split. Default: the workspace default split
fee_buyer_percentintegerNo0 to 100, your workspace's share of the fee. Required with split

The answer carries the fee snapshot in deal.fee and each milestone's buyer_fee, seller_fee, funding_amount and payout_amount. The rate and minimum are taken from your workspace pricing now and never change for this deal; see Enterprise platform fee.

Each milestone:

NameTypeRequiredDescription
titlestringYes2 to 180 characters
amountintegerYesWhole rupiah, 10,000 to 50,000,000,000
required_evidencestringNoWhat the supplier must show, at most 300 characters
due_atstringNoISO 8601 date-time with offset

Example request ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/deals \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: ddddddd4-dddd-4ddd-8ddd-dddddddddddd" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Packaging run Q4",
    "description": "Printed cartons for the Q4 export order.",
    "external_ref": "PO-2026-1188",
    "counterparty_id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
    "currency": "IDR",
    "milestones": [
      {
        "title": "Tooling and proof approval",
        "amount": 30000000,
        "required_evidence": "Signed proof sheet"
      },
      {
        "title": "First 20,000 cartons",
        "amount": 20000000,
        "required_evidence": "Delivery note and inspection report"
      }
    ]
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': 'ddddddd4-dddd-4ddd-8ddd-dddddddddddd',
    },
    body: JSON.stringify({
        title: "Packaging run Q4",
        description: "Printed cartons for the Q4 export order.",
        external_ref: "PO-2026-1188",
        counterparty_id: "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
        currency: "IDR",
        milestones: [
            {
                title: "Tooling and proof approval",
                amount: 30000000,
                required_evidence: "Signed proof sheet"
            },
            {
                title: "First 20,000 cartons",
                amount: 20000000,
                required_evidence: "Delivery note and inspection report"
            }
        ]
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/deals",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "ddddddd4-dddd-4ddd-8ddd-dddddddddddd",
    },
    json={
        "title": "Packaging run Q4",
        "description": "Printed cartons for the Q4 export order.",
        "external_ref": "PO-2026-1188",
        "counterparty_id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
        "currency": "IDR",
        "milestones": [
            {
                "title": "Tooling and proof approval",
                "amount": 30000000,
                "required_evidence": "Signed proof sheet",
            },
            {
                "title": "First 20,000 cartons",
                "amount": 20000000,
                "required_evidence": "Delivery note and inspection report",
            },
        ],
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: ddddddd4-dddd-4ddd-8ddd-dddddddddddd',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'title' => 'Packaging run Q4',
        'description' => 'Printed cartons for the Q4 export order.',
        'external_ref' => 'PO-2026-1188',
        'counterparty_id' => 'eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee',
        'currency' => 'IDR',
        'milestones' => [
            [
                'title' => 'Tooling and proof approval',
                'amount' => 30000000,
                'required_evidence' => 'Signed proof sheet',
            ],
            [
                'title' => 'First 20,000 cartons',
                'amount' => 20000000,
                'required_evidence' => 'Delivery note and inspection report',
            ],
        ],
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

201 Created

json
{
    "success": true,
    "data": {
        "deal": {
            "id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
            "reference": "DEAL-2026-0009",
            "title": "Packaging run Q4",
            "description": "Printed cartons for the Q4 export order.",
            "external_ref": "PO-2026-1188",
            "status": "draft",
            "currency": "IDR",
            "total_amount": 50000000,
            "funded_amount": 0,
            "released_amount": 0,
            "cross_border": false,
            "owner": {
                "id": "33333333-3333-4333-8333-333333333333",
                "name": "Dimas Hidayat"
            },
            "created_at": "2026-10-13T14:33:16.361Z",
            "updated_at": "2026-10-13T14:33:16.361Z",
            "counterparty": {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd",
                "country_code": "SG",
                "kyb_status": "verified",
                "relationship": "seller"
            }
        },
        "milestones": [
            {
                "id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
                "sequence_no": 1,
                "title": "Tooling and proof approval",
                "required_evidence": "Signed proof sheet",
                "amount": 30000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            },
            {
                "id": "11111115-1111-4111-8111-111111111111",
                "sequence_no": 2,
                "title": "First 20,000 cartons",
                "required_evidence": "Delivery note and inspection report",
                "amount": 20000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            }
        ],
        "events": [
            {
                "seq": 140528,
                "event": "deal.created",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 50000000,
                "summary": "Created deal DEAL-2026-0009: Packaging run Q4",
                "created_at": "2026-10-13T14:33:16.361Z"
            }
        ],
        "outcome": {
            "time_to_release_minutes": null,
            "approvals_by_people": 0,
            "revisions": 0
        }
    }
}

Errors ​

StatusCodeCause
400INVALID_BODYA field failed validation. error.details.fieldErrors names it
404COUNTERPARTY_NOT_FOUNDThe counterparty is not in this workspace
409DEAL_CREATE_BUSYAnother deal is being created at the same moment. Try again
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below operator
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Update a draft deal ​

PATCH/v1/enterprise/deals/:id

Changes deal fields while the deal is a draft. Returns the full deal, like Get a deal.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 300 requests a minute per user, shared by every route.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID

Body (JSON) ​

NameTypeRequiredDescription
titlestringNo2 to 180 characters
descriptionstring | nullNoAt most 1,000 characters. null clears it
external_refstring | nullNoAt most 80 characters
counterparty_idUUID | nullNoA counterparty of the workspace
cross_borderbooleanNoCross-border flag
fee_allocationstringNobuyer, seller or split: change who pays the platform fee while the deal is a draft
fee_buyer_percentintegerNo0 to 100. Required with split

Example request ​

bash
curl -X PATCH https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 22222225-2222-4222-8222-222222222222" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Printed cartons for the Q4 export order, 2 colours."
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee', {
    method: 'PATCH',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '22222225-2222-4222-8222-222222222222',
    },
    body: JSON.stringify({
        description: "Printed cartons for the Q4 export order, 2 colours."
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.patch(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "22222225-2222-4222-8222-222222222222",
    },
    json={
        "description": "Printed cartons for the Q4 export order, 2 colours.",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PATCH',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 22222225-2222-4222-8222-222222222222',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'description' => 'Printed cartons for the Q4 export order, 2 colours.',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": {
        "deal": {
            "id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
            "reference": "DEAL-2026-0009",
            "title": "Packaging run Q4",
            "description": "Printed cartons for the Q4 export order, 2 colours.",
            "external_ref": "PO-2026-1188",
            "status": "draft",
            "currency": "IDR",
            "total_amount": 50000000,
            "funded_amount": 0,
            "released_amount": 0,
            "cross_border": false,
            "owner": {
                "id": "33333333-3333-4333-8333-333333333333",
                "name": "Dimas Hidayat"
            },
            "created_at": "2026-10-13T14:33:16.361Z",
            "updated_at": "2026-10-13T14:33:16.369Z",
            "counterparty": {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd",
                "country_code": "SG",
                "kyb_status": "verified",
                "relationship": "seller"
            }
        },
        "milestones": [
            {
                "id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
                "sequence_no": 1,
                "title": "Tooling and proof approval",
                "required_evidence": "Signed proof sheet",
                "amount": 30000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            },
            {
                "id": "11111115-1111-4111-8111-111111111111",
                "sequence_no": 2,
                "title": "First 20,000 cartons",
                "required_evidence": "Delivery note and inspection report",
                "amount": 20000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            }
        ],
        "events": [
            {
                "seq": 140528,
                "event": "deal.created",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 50000000,
                "summary": "Created deal DEAL-2026-0009: Packaging run Q4",
                "created_at": "2026-10-13T14:33:16.361Z"
            },
            {
                "seq": 140529,
                "event": "deal.updated",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": null,
                "summary": "Updated deal DEAL-2026-0009",
                "created_at": "2026-10-13T14:33:16.369Z"
            }
        ],
        "outcome": {
            "time_to_release_minutes": null,
            "approvals_by_people": 0,
            "revisions": 0
        }
    }
}

Errors ​

StatusCodeCause
400INVALID_BODYA field failed validation, or nothing to update
404NOT_FOUND, COUNTERPARTY_NOT_FOUNDNo such deal, or the counterparty is not in this workspace
409NOT_DRAFTOnly draft deals can be edited
409CONCURRENT_MODIFICATIONThe deal changed while the call ran
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below operator
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

A real NOT_DRAFT answer:

409 Conflict

json
{
    "success": false,
    "error": {
        "code": "NOT_DRAFT",
        "message": "Only draft deals can be edited."
    }
}

Add a milestone ​

POST/v1/enterprise/deals/:id/milestones

Adds one milestone to a draft deal. Returns 201 with the full deal.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 300 requests a minute per user, shared by every route.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID

Body (JSON) ​

NameTypeRequiredDescription
titlestringYes2 to 180 characters
amountintegerYes10,000 to 50,000,000,000
required_evidencestringNoAt most 300 characters
due_atstringNoISO 8601 date-time with offset

Example request ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 33333335-3333-4333-8333-333333333333" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Final 10,000 cartons",
    "amount": 10000000,
    "required_evidence": "Delivery note"
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '33333335-3333-4333-8333-333333333333',
    },
    body: JSON.stringify({
        title: "Final 10,000 cartons",
        amount: 10000000,
        required_evidence: "Delivery note"
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "33333335-3333-4333-8333-333333333333",
    },
    json={
        "title": "Final 10,000 cartons",
        "amount": 10000000,
        "required_evidence": "Delivery note",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 33333335-3333-4333-8333-333333333333',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'title' => 'Final 10,000 cartons',
        'amount' => 10000000,
        'required_evidence' => 'Delivery note',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

201 Created

json
{
    "success": true,
    "data": {
        "deal": {
            "id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
            "reference": "DEAL-2026-0009",
            "title": "Packaging run Q4",
            "description": "Printed cartons for the Q4 export order, 2 colours.",
            "external_ref": "PO-2026-1188",
            "status": "draft",
            "currency": "IDR",
            "total_amount": 60000000,
            "funded_amount": 0,
            "released_amount": 0,
            "cross_border": false,
            "owner": {
                "id": "33333333-3333-4333-8333-333333333333",
                "name": "Dimas Hidayat"
            },
            "created_at": "2026-10-13T14:33:16.361Z",
            "updated_at": "2026-10-13T14:33:16.376Z",
            "counterparty": {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd",
                "country_code": "SG",
                "kyb_status": "verified",
                "relationship": "seller"
            }
        },
        "milestones": [
            {
                "id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
                "sequence_no": 1,
                "title": "Tooling and proof approval",
                "required_evidence": "Signed proof sheet",
                "amount": 30000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            },
            {
                "id": "11111115-1111-4111-8111-111111111111",
                "sequence_no": 2,
                "title": "First 20,000 cartons",
                "required_evidence": "Delivery note and inspection report",
                "amount": 20000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            },
            {
                "id": "44444445-4444-4444-8444-444444444444",
                "sequence_no": 3,
                "title": "Final 10,000 cartons",
                "required_evidence": "Delivery note",
                "amount": 10000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            }
        ],
        "events": [
            {
                "seq": 140528,
                "event": "deal.created",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 50000000,
                "summary": "Created deal DEAL-2026-0009: Packaging run Q4",
                "created_at": "2026-10-13T14:33:16.361Z"
            },
            {
                "seq": 140529,
                "event": "deal.updated",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": null,
                "summary": "Updated deal DEAL-2026-0009",
                "created_at": "2026-10-13T14:33:16.369Z"
            },
            {
                "seq": 140530,
                "event": "milestone.added",
                "entity_type": "milestone",
                "entity_id": "44444445-4444-4444-8444-444444444444",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 10000000,
                "summary": "Added milestone Final 10,000 cartons to DEAL-2026-0009",
                "created_at": "2026-10-13T14:33:16.376Z"
            }
        ],
        "outcome": {
            "time_to_release_minutes": null,
            "approvals_by_people": 0,
            "revisions": 0
        }
    }
}

Errors ​

StatusCodeCause
400INVALID_BODYA field failed validation
404NOT_FOUNDNo such deal
409NOT_DRAFTOnly draft deals can be edited
409TOO_MANY_MILESTONESThe deal already has 20 milestones
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below operator
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Update a draft milestone ​

PATCH/v1/enterprise/deals/:id/milestones/:mid

Changes a milestone while it and its deal are drafts. Returns the full deal.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 300 requests a minute per user, shared by every route.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID
midUUIDThe milestone ID

Body (JSON) ​

NameTypeRequiredDescription
titlestringNo2 to 180 characters
amountintegerNo10,000 to 50,000,000,000
required_evidencestring | nullNoAt most 300 characters
due_atstring | nullNoISO 8601 date-time with offset

Example request ​

bash
curl -X PATCH https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/44444445-4444-4444-8444-444444444444 \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 55555555-5555-4555-8555-555555555555" \
  -H "Content-Type: application/json" \
  -d '{
    "due_at": "2026-12-15T00:00:00+07:00"
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/44444445-4444-4444-8444-444444444444', {
    method: 'PATCH',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '55555555-5555-4555-8555-555555555555',
    },
    body: JSON.stringify({
        due_at: "2026-12-15T00:00:00+07:00"
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.patch(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/44444445-4444-4444-8444-444444444444",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "55555555-5555-4555-8555-555555555555",
    },
    json={
        "due_at": "2026-12-15T00:00:00+07:00",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/44444445-4444-4444-8444-444444444444');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PATCH',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 55555555-5555-4555-8555-555555555555',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'due_at' => '2026-12-15T00:00:00+07:00',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": {
        "deal": {
            "id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
            "reference": "DEAL-2026-0009",
            "title": "Packaging run Q4",
            "description": "Printed cartons for the Q4 export order, 2 colours.",
            "external_ref": "PO-2026-1188",
            "status": "draft",
            "currency": "IDR",
            "total_amount": 60000000,
            "funded_amount": 0,
            "released_amount": 0,
            "cross_border": false,
            "owner": {
                "id": "33333333-3333-4333-8333-333333333333",
                "name": "Dimas Hidayat"
            },
            "created_at": "2026-10-13T14:33:16.361Z",
            "updated_at": "2026-10-13T14:33:16.376Z",
            "counterparty": {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd",
                "country_code": "SG",
                "kyb_status": "verified",
                "relationship": "seller"
            }
        },
        "milestones": [
            {
                "id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
                "sequence_no": 1,
                "title": "Tooling and proof approval",
                "required_evidence": "Signed proof sheet",
                "amount": 30000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            },
            {
                "id": "11111115-1111-4111-8111-111111111111",
                "sequence_no": 2,
                "title": "First 20,000 cartons",
                "required_evidence": "Delivery note and inspection report",
                "amount": 20000000,
                "status": "draft",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            },
            {
                "id": "44444445-4444-4444-8444-444444444444",
                "sequence_no": 3,
                "title": "Final 10,000 cartons",
                "required_evidence": "Delivery note",
                "amount": 10000000,
                "status": "draft",
                "due_at": "2026-12-14T17:00:00.000Z",
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            }
        ],
        "events": [
            {
                "seq": 140528,
                "event": "deal.created",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 50000000,
                "summary": "Created deal DEAL-2026-0009: Packaging run Q4",
                "created_at": "2026-10-13T14:33:16.361Z"
            },
            {
                "seq": 140529,
                "event": "deal.updated",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": null,
                "summary": "Updated deal DEAL-2026-0009",
                "created_at": "2026-10-13T14:33:16.369Z"
            },
            {
                "seq": 140530,
                "event": "milestone.added",
                "entity_type": "milestone",
                "entity_id": "44444445-4444-4444-8444-444444444444",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 10000000,
                "summary": "Added milestone Final 10,000 cartons to DEAL-2026-0009",
                "created_at": "2026-10-13T14:33:16.376Z"
            }
        ],
        "outcome": {
            "time_to_release_minutes": null,
            "approvals_by_people": 0,
            "revisions": 0
        }
    }
}

Lists are cut to the first 3 items and long text is shortened here.

Errors ​

StatusCodeCause
400INVALID_BODYA field failed validation, or nothing to update
404NOT_FOUNDNo such deal or milestone
409NOT_DRAFTOnly draft milestones can be edited
409CONCURRENT_MODIFICATIONThe milestone changed while the call ran
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below operator
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Activate a deal ​

POST/v1/enterprise/deals/:id/activate

Moves a draft deal and its milestones to awaiting_funding. The deal needs a counterparty and at least one milestone. Send {} as the body.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 300 requests a minute per user, shared by every route.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID

Example request ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/activate \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 66666665-6666-4666-8666-666666666666" \
  -H "Content-Type: application/json" \
  -d '{}'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/activate', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '66666665-6666-4666-8666-666666666666',
    },
    body: JSON.stringify({}),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/activate",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "66666665-6666-4666-8666-666666666666",
    },
    json={},
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/activate');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 66666665-6666-4666-8666-666666666666',
    ],
    CURLOPT_POSTFIELDS => json_encode(new stdClass()),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": {
        "deal": {
            "id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
            "reference": "DEAL-2026-0009",
            "title": "Packaging run Q4",
            "description": "Printed cartons for the Q4 export order, 2 colours.",
            "external_ref": "PO-2026-1188",
            "status": "awaiting_funding",
            "currency": "IDR",
            "total_amount": 60000000,
            "funded_amount": 0,
            "released_amount": 0,
            "cross_border": false,
            "owner": {
                "id": "33333333-3333-4333-8333-333333333333",
                "name": "Dimas Hidayat"
            },
            "created_at": "2026-10-13T14:33:16.361Z",
            "updated_at": "2026-10-13T14:33:16.391Z",
            "counterparty": {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd",
                "country_code": "SG",
                "kyb_status": "verified",
                "relationship": "seller"
            }
        },
        "milestones": [
            {
                "id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
                "sequence_no": 1,
                "title": "Tooling and proof approval",
                "required_evidence": "Signed proof sheet",
                "amount": 30000000,
                "status": "awaiting_funding",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            },
            {
                "id": "11111115-1111-4111-8111-111111111111",
                "sequence_no": 2,
                "title": "First 20,000 cartons",
                "required_evidence": "Delivery note and inspection report",
                "amount": 20000000,
                "status": "awaiting_funding",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            }
        ],
        "events": [
            {
                "seq": 140528,
                "event": "deal.created",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 50000000,
                "summary": "Created deal DEAL-2026-0009: Packaging run Q4",
                "created_at": "2026-10-13T14:33:16.361Z"
            },
            {
                "seq": 140529,
                "event": "deal.updated",
                "entity_type": "deal",
                "entity_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": null,
                "summary": "Updated deal DEAL-2026-0009",
                "created_at": "2026-10-13T14:33:16.369Z"
            }
        ],
        "outcome": {
            "time_to_release_minutes": null,
            "approvals_by_people": 0,
            "revisions": 0
        }
    }
}

Lists are cut to the first 2 items and long text is shortened here.

Errors ​

StatusCodeCause
404NOT_FOUNDNo such deal
409NOT_DRAFTThe deal is not a draft
409COUNTERPARTY_REQUIREDSet a counterparty first
409NO_MILESTONESAdd at least one milestone first
409CONCURRENT_MODIFICATIONThe deal changed while the call ran
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below operator
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Cancel a deal ​

POST/v1/enterprise/deals/:id/cancel

Cancels a deal while no milestone is funded. Once money is held, open a dispute instead. Send {} as the body.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 300 requests a minute per user, shared by every route.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID

Example request ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/deals/fffffff6-ffff-4fff-8fff-ffffffffffff/cancel \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 11111117-1111-4111-8111-111111111111" \
  -H "Content-Type: application/json" \
  -d '{}'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/fffffff6-ffff-4fff-8fff-ffffffffffff/cancel', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '11111117-1111-4111-8111-111111111111',
    },
    body: JSON.stringify({}),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/deals/fffffff6-ffff-4fff-8fff-ffffffffffff/cancel",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "11111117-1111-4111-8111-111111111111",
    },
    json={},
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/fffffff6-ffff-4fff-8fff-ffffffffffff/cancel');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 11111117-1111-4111-8111-111111111111',
    ],
    CURLOPT_POSTFIELDS => json_encode(new stdClass()),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": {
        "deal": {
            "id": "fffffff6-ffff-4fff-8fff-ffffffffffff",
            "reference": "DEAL-2026-0010",
            "title": "Sample shipment",
            "description": null,
            "external_ref": null,
            "status": "cancelled",
            "currency": "IDR",
            "total_amount": 2500000,
            "funded_amount": 0,
            "released_amount": 0,
            "cross_border": false,
            "owner": {
                "id": "33333333-3333-4333-8333-333333333333",
                "name": "Dimas Hidayat"
            },
            "created_at": "2026-10-13T14:33:16.555Z",
            "updated_at": "2026-10-13T14:33:16.563Z",
            "counterparty": {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd",
                "country_code": "SG",
                "kyb_status": "verified",
                "relationship": "seller"
            }
        },
        "milestones": [
            {
                "id": "22222227-2222-4222-8222-222222222222",
                "sequence_no": 1,
                "title": "Samples",
                "required_evidence": null,
                "amount": 2500000,
                "status": "cancelled",
                "due_at": null,
                "funded_at": null,
                "funding_method": null,
                "evidence_summary": null,
                "evidence_submitted_at": null,
                "approved_at": null,
                "released_at": null,
                "disputed_at": null,
                "dispute_reason": null,
                "approvals_required": 1,
                "approvals": [],
                "documents": [],
                "disbursements": []
            }
        ],
        "events": [
            {
                "seq": 140555,
                "event": "deal.created",
                "entity_type": "deal",
                "entity_id": "fffffff6-ffff-4fff-8fff-ffffffffffff",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": 2500000,
                "summary": "Created deal DEAL-2026-0010: Sample shipment",
                "created_at": "2026-10-13T14:33:16.556Z"
            },
            {
                "seq": 140556,
                "event": "deal.cancelled",
                "entity_type": "deal",
                "entity_id": "fffffff6-ffff-4fff-8fff-ffffffffffff",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "amount": null,
                "summary": "Cancelled deal DEAL-2026-0010",
                "created_at": "2026-10-13T14:33:16.564Z"
            }
        ],
        "outcome": {
            "time_to_release_minutes": null,
            "approvals_by_people": 0,
            "revisions": 0
        }
    }
}

Errors ​

StatusCodeCause
404NOT_FOUNDNo such deal
409INVALID_STATEThe deal is already cancelled
409NOT_CANCELLABLEA milestone is already funded
409CONCURRENT_MODIFICATIONThe deal changed while the call ran
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below operator
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Fund a milestone (sandbox) ​

POST/v1/enterprise/deals/:id/milestones/:mid/fund

Sandbox workspaces only: marks an awaiting_funding milestone as funded so you can test the rest of the flow. In a live workspace RekberPay confirms funding when the money arrives, and this call answers 403 LIVE_FUNDING_IS_PLATFORM_CONFIRMED.

Sandbox funding is always recorded as sandbox, whatever method you send. Deals made in the sandbox carry is_test: true. When the workspace goes live, their unfinished milestones are cancelled and they never release real money.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: finance, admin or owner.
  • Rate limit: 30 a minute per user for this route, plus the shared 300 a minute.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID
midUUIDThe milestone ID

Body (JSON) ​

NameTypeRequiredDescription
methodstringYesqris, va, ewallet, wire or sandbox
referencestringNoYour test reference, 1 to 120 characters

Example request ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/fffffff4-ffff-4fff-8fff-ffffffffffff/fund \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 77777775-7777-4777-8777-777777777777" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "sandbox",
    "reference": "SANDBOX-TOPUP-0001"
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/fffffff4-ffff-4fff-8fff-ffffffffffff/fund', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '77777775-7777-4777-8777-777777777777',
    },
    body: JSON.stringify({
        method: "sandbox",
        reference: "SANDBOX-TOPUP-0001"
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/fffffff4-ffff-4fff-8fff-ffffffffffff/fund",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "77777775-7777-4777-8777-777777777777",
    },
    json={
        "method": "sandbox",
        "reference": "SANDBOX-TOPUP-0001",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/fffffff4-ffff-4fff-8fff-ffffffffffff/fund');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 77777775-7777-4777-8777-777777777777',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'method' => 'sandbox',
        'reference' => 'SANDBOX-TOPUP-0001',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": {
        "milestone": {
            "id": "fffffff4-ffff-4fff-8fff-ffffffffffff",
            "deal_id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
            "status": "funded",
            "amount": 30000000,
            "buyer_fee": 600000,
            "funding_amount": 30600000,
            "funding_method": "sandbox"
        },
        "deal_status": "funded"
    }
}

Errors ​

StatusCodeCause
400INVALID_BODYmethod missing or not valid
403LIVE_FUNDING_IS_PLATFORM_CONFIRMEDThe workspace is live
404NOT_FOUNDNo such milestone
409CONCURRENT_MODIFICATIONThe milestone is not awaiting_funding
409LIVE_DEAL_IN_SANDBOXThe deal is a live deal (is_test: false). Sandbox test money only funds deals created in the sandbox
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below finance
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Submit evidence ​

POST/v1/enterprise/deals/:id/milestones/:mid/submit-evidence

Sends a funded milestone for approval with a short summary and the documents that prove the work. Register the files first with POST /v1/enterprise/documents. Works on funded and revision_requested milestones; each submission opens a new approval round. approvals_required is 2 when the amount is at or above the workspace's four_eyes_threshold.

The person who submits cannot decide on the same milestone, so submit with a different user or key than the one that approves.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 30 a minute per user for this route, plus the shared 300 a minute.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID
midUUIDThe milestone ID

Body (JSON) ​

NameTypeRequiredDescription
evidence_summarystringYes10 to 500 characters
document_idsUUID[]NoUp to 10 documents of this workspace, deal or milestone

Example request ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/11111115-1111-4111-8111-111111111111/submit-evidence \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 99999995-9999-4999-8999-999999999999" \
  -H "Content-Type: application/json" \
  -d '{
    "evidence_summary": "First 20,000 cartons delivered to the Cikarang warehouse.",
    "document_ids": []
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/11111115-1111-4111-8111-111111111111/submit-evidence', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '99999995-9999-4999-8999-999999999999',
    },
    body: JSON.stringify({
        evidence_summary: "First 20,000 cartons delivered to the Cikarang warehouse.",
        document_ids: []
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/11111115-1111-4111-8111-111111111111/submit-evidence",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "99999995-9999-4999-8999-999999999999",
    },
    json={
        "evidence_summary": "First 20,000 cartons delivered to the Cikarang warehouse.",
        "document_ids": [],
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/11111115-1111-4111-8111-111111111111/submit-evidence');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 99999995-9999-4999-8999-999999999999',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'evidence_summary' => 'First 20,000 cartons delivered to the Cikarang warehouse.',
        'document_ids' => [],
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": {
        "milestone_id": "11111115-1111-4111-8111-111111111111",
        "status": "evidence_submitted",
        "approvals_required": 1,
        "deal_status": "funded"
    }
}

Errors ​

StatusCodeCause
400INVALID_BODYSummary too short or too long
400INVALID_DOCUMENTSA document is not in this workspace, deal or milestone
404NOT_FOUNDNo such milestone
409INVALID_STATEThe milestone is not funded or revision_requested
409CONCURRENT_MODIFICATIONThe milestone changed while the call ran
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below operator
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Dispute a milestone ​

POST/v1/enterprise/deals/:id/milestones/:mid/dispute

Freezes a funded, evidence_submitted or approved milestone. RekberPay operations looks at it and resolves it to funded, released or cancelled; the result shows up in the event feed.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 30 a minute per user for this route, plus the shared 300 a minute.
  • Idempotency: Send an Idempotency-Key header (UUID v4). A retry with the same key and body returns the first answer with Idempotent-Replay: true.

Path parameters ​

NameTypeDescription
idUUIDThe deal ID
midUUIDThe milestone ID

Body (JSON) ​

NameTypeRequiredDescription
reasonstringYes10 to 700 characters

Example request ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/11111115-1111-4111-8111-111111111111/dispute \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 66666666-6666-4666-8666-666666666666" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Supplier has not sent the inspection report after two requests."
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/11111115-1111-4111-8111-111111111111/dispute', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '66666666-6666-4666-8666-666666666666',
    },
    body: JSON.stringify({
        reason: "Supplier has not sent the inspection report after two requests."
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/11111115-1111-4111-8111-111111111111/dispute",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "66666666-6666-4666-8666-666666666666",
    },
    json={
        "reason": "Supplier has not sent the inspection report after two requests.",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/deals/eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee/milestones/11111115-1111-4111-8111-111111111111/dispute');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 66666666-6666-4666-8666-666666666666',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'reason' => 'Supplier has not sent the inspection report after two requests.',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK

json
{
    "success": true,
    "data": {
        "milestone_id": "11111115-1111-4111-8111-111111111111",
        "status": "disputed",
        "deal_status": "disputed"
    }
}

Errors ​

StatusCodeCause
400INVALID_BODYReason too short or too long
404NOT_FOUNDNo such milestone
409INVALID_STATEThe milestone cannot be disputed in its current state
409CONCURRENT_MODIFICATIONThe milestone changed while the call ran
401UNAUTHORIZED, SESSION_EXPIRED, INVALID_TOKENNo session or key, the session expired, or the key is wrong or revoked
400INVALID_ACCOUNTX-Enterprise-Account is not a UUID
403NO_WORKSPACEYou are not an active member of that workspace, or the key belongs to another one
403FORBIDDENYour role is below operator
403SCOPE_REQUIREDThe workspace key only has the read scope
403CSRF_FAILEDSession call without the matching X-CSRF-Token header
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Escrow, payment services and B2B deals for Indonesian businesses.