Skip to content

Enterprise events and audit ​

Every change in a workspace is written to an append-only event feed. Each event has a seq number that only goes up, so you can poll the feed from the last seq you processed (see Polling events), or receive the same events as webhooks. Auth, roles, the workspace header and the shared limits are explained in Enterprise overview.

Endpoints ​

MethodPathEndpointAuth
GET/v1/enterprise/overviewGet the overviewviewer
GET/v1/enterprise/eventsList eventsviewer
GET/v1/enterprise/audit/export.csvExport the audit logfinance
GET/v1/enterprise/reconciliationCheck the booksviewer

Get the overview ​

GET/v1/enterprise/overview

The dashboard home in one call: headline numbers, a 24-hour series, 7-day trends, 90-day outcomes, counterparty performance, the approvals waiting for you, live alerts and the 8 newest events. It is cached for 15 seconds per workspace and user; your own writes clear the cache at once.

  • 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: 60 a minute per user for this route, plus the shared 300 a minute.
  • Idempotency: Not needed. Reading has no side effects.

Example request ​

bash
curl https://api.rekberpay.com/v1/enterprise/overview \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/overview', {
    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/overview",
    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/overview');
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": {
        "greeting_name": "Dimas",
        "generated_at": "2026-10-13T14:33:16.656Z",
        "stats": {
            "active_deal_value": 772500000,
            "deals_active": 6,
            "transactions_secured": 8,
            "released_24h": 641300000,
            "need_you": 1,
            "median_approval_hours": 4,
            "avg_settlement_minutes": 31.8
        },
        "series_24h": [
            {
                "hour": "2026-10-12T15:00:00.000Z",
                "funded": 1,
                "approved": 0,
                "released": 0,
                "disputed": 1
            },
            {
                "hour": "2026-10-12T16:00:00.000Z",
                "funded": 1,
                "approved": 1,
                "released": 1,
                "disputed": 0
            }
        ],
        "trends_7d": {
            "days": [
                "2026-10-07",
                "2026-10-08"
            ],
            "automation_pct": [
                100,
                100
            ],
            "revisions": [
                0,
                0
            ]
        },
        "outcomes_90d": {
            "released": 8,
            "open": 12,
            "disputed": 2,
            "cancelled": 1,
            "revision_rate_pct": 13.3,
            "automation_rate_pct": 86.7
        },
        "counterparty_performance": [
            {
                "id": "eeeeeee3-eeee-4eee-8eee-eeeeeeeeeeee",
                "name": "Harbourline Components Pte Ltd",
                "deals": 4,
                "on_time_pct": 100,
                "dispute_pct": 12.5,
                "spark": [
                    0,
                    0
                ]
            },
            {
                "id": "22222228-2222-4222-8222-222222222222",
                "name": "PT Sinar Logistik Nusantara",
                "deals": 2,
                "on_time_pct": 100,
                "dispute_pct": 0,
                "spark": [
                    0,
                    0
                ]
            }
        ],
        "needs_you": [
            {
                "milestone_id": "ccccccc5-cccc-4ccc-8ccc-cccccccccccc",
                "deal_id": "ddddddd5-dddd-4ddd-8ddd-dddddddddddd",
                "deal_reference": "DEAL-2026-0004",
                "deal_title": "Cold-chain logistics, Jakarta to Surabaya",
                "milestone_title": "QA inspection passed",
                "status": "evidence_submitted",
                "amount": 18500000,
                "currency": "IDR",
                "counterparty_name": "PT Sinar Logistik Nusantara",
                "risk_tier": "standard",
                "evidence_summary": "Temperature log for the full route, never warmer than -19C.",
                "evidence_submitted_at": "2026-10-13T12:33:06.162Z",
                "due_at": "2026-10-16T02:33:06.162Z",
                "approvals_required": 1,
                "approvals_done": 0,
                "my_decision": null,
                "submitted_by": {
                    "id": "88888884-8888-4888-8888-888888888888",
                    "name": "Sari Wibowo"
                }
            }
        ],
        "alerts": [
            {
                "kind": "overdue_milestone",
                "severity": "medium",
                "title": "Milestone overdue",
                "detail": "DEAL-2026-0005 / PO signed and registered was due 2026-10-10.",
                "deal_id": "55555558-5555-4555-8555-555555555555",
                "milestone_id": "66666668-6666-4666-8666-666666666666"
            },
            {
                "kind": "kyb_gap",
                "severity": "medium",
                "title": "Counterparty KYB incomplete",
                "detail": "DEAL-2026-0005 / PO signed and registered: PT Mitra Retail Jaya is pending.",
                "deal_id": "55555558-5555-4555-8555-555555555555",
                "milestone_id": "66666668-6666-4666-8666-666666666666"
            }
        ],
        "recent": [
            {
                "seq": 140566,
                "id": "ddddddd7-dddd-4ddd-8ddd-dddddddddddd",
                "event": "disbursement.queued",
                "entity_type": "disbursement",
                "entity_id": "ccccccc7-cccc-4ccc-8ccc-cccccccccccc",
                "deal_id": "44444447-4444-4444-8444-444444444444",
                "deal_reference": "DEAL-2026-0011",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "actor_label": null,
                "amount": 150000000,
                "summary": "Payout queued for DEAL-2026-0011 / Moulds delivered and inspected",
                "created_at": "2026-10-13T14:33:16.635Z",
                "livemode": false
            },
            {
                "seq": 140565,
                "id": "eeeeeee7-eeee-4eee-8eee-eeeeeeeeeeee",
                "event": "milestone.released",
                "entity_type": "milestone",
                "entity_id": "55555557-5555-4555-8555-555555555555",
                "deal_id": "44444447-4444-4444-8444-444444444444",
                "deal_reference": "DEAL-2026-0011",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "actor_label": null,
                "amount": 150000000,
                "summary": "Released DEAL-2026-0011 / Moulds delivered and inspected in 1 payout",
                "created_at": "2026-10-13T14:33:16.634Z",
                "livemode": false
            }
        ]
    }
}

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

FieldTypeDescription
statsobjectactive_deal_value, deals_active, transactions_secured, released_24h, need_you, median_approval_hours, avg_settlement_minutes
series_24harray24 hourly buckets of funded, approved, released and disputed counts
trends_7dobjectSeven UTC days of automation_pct and revisions
outcomes_90dobjectCounts and rates over 90 days
needs_youarrayMilestones waiting for your decision
alertsarraydispute_sla, overdue_milestone, high_value_pending, payout_velocity, watchlist_hit and kyb_gap alerts
recentarrayThe 8 newest events

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

List events ​

GET/v1/enterprise/events

Oldest first after after (the default), for polling. With order=desc it returns the newest events first below before, plus next_before for the next older page. Both forms return next_after: send it as after on your next poll. When nothing is new, next_after echoes your after. Event items never carry IP addresses. Each item has livemode, the same flag as the webhook payload: fixed when the event happens, true only for real money in a live workspace, false for sandbox and test data.

  • 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
afterintegerNoEvents with seq above this. Default 0
orderstringNoasc (default) or desc
beforeintegerNoWith order=desc, events with seq below this
limitintegerNo1 to 100. Default 50
deal_idUUIDNoOnly this deal
eventstringNoOnly this event name, for example milestone.released

Example request ​

bash
curl "https://api.rekberpay.com/v1/enterprise/events?after=140563&limit=3" \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/events?after=140563&limit=3', {
    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/events?after=140563&limit=3",
    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/events?after=140563&limit=3');
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": {
        "items": [
            {
                "seq": 140564,
                "id": "fffffff7-ffff-4fff-8fff-ffffffffffff",
                "event": "milestone.approved",
                "entity_type": "milestone",
                "entity_id": "55555557-5555-4555-8555-555555555555",
                "deal_id": "44444447-4444-4444-8444-444444444444",
                "deal_reference": "DEAL-2026-0011",
                "actor": {
                    "id": "77777776-7777-4777-8777-777777777777",
                    "name": "Maya Santoso"
                },
                "actor_label": null,
                "amount": 150000000,
                "summary": "Approved DEAL-2026-0011 / Moulds delivered and inspected for release",
                "created_at": "2026-10-13T14:33:16.626Z",
                "livemode": false
            },
            {
                "seq": 140565,
                "id": "eeeeeee7-eeee-4eee-8eee-eeeeeeeeeeee",
                "event": "milestone.released",
                "entity_type": "milestone",
                "entity_id": "55555557-5555-4555-8555-555555555555",
                "deal_id": "44444447-4444-4444-8444-444444444444",
                "deal_reference": "DEAL-2026-0011",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "actor_label": null,
                "amount": 150000000,
                "summary": "Released DEAL-2026-0011 / Moulds delivered and inspected in 1 payout",
                "created_at": "2026-10-13T14:33:16.634Z",
                "livemode": false
            },
            {
                "seq": 140566,
                "id": "ddddddd7-dddd-4ddd-8ddd-dddddddddddd",
                "event": "disbursement.queued",
                "entity_type": "disbursement",
                "entity_id": "ccccccc7-cccc-4ccc-8ccc-cccccccccccc",
                "deal_id": "44444447-4444-4444-8444-444444444444",
                "deal_reference": "DEAL-2026-0011",
                "actor": {
                    "id": "33333333-3333-4333-8333-333333333333",
                    "name": "Dimas Hidayat"
                },
                "actor_label": null,
                "amount": 150000000,
                "summary": "Payout queued for DEAL-2026-0011 / Moulds delivered and inspected",
                "created_at": "2026-10-13T14:33:16.635Z",
                "livemode": false
            }
        ],
        "next_after": 140566
    }
}
FieldTypeDescription
seqintegerFeed position. Store the highest one you processed
eventstringEvent name. The list is in Webhooks
actorobject | nullThe member who acted
actor_labelstring | nullSet when the actor is not a member, for example RekberPay ops
amountnumber | nullRupiah moved by the event, when there is one

Errors ​

StatusCodeCause
400INVALID_QUERYorder is not asc or desc, deal_id is not a UUID, or event is not a valid name
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

A real INVALID_QUERY answer:

400 Bad Request

json
{
    "success": false,
    "error": {
        "code": "INVALID_QUERY",
        "message": "order must be asc or desc."
    }
}

Export the audit log ​

GET/v1/enterprise/audit/export.csv

The event log as CSV, for auditors. Columns: seq, created_at, event, actor, ip, deal, amount, summary, previous_state, new_state. The ip column is only there for admins and owners; a finance member gets the same file without it. One export holds at most 10,000 rows; when there were more, the answer has X-Export-Truncated: true and you should export a shorter range. Cells a spreadsheet would read as a formula start with '.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: finance, admin or owner.
  • Rate limit: 5 a minute per user for this route, plus the shared 300 a minute.
  • Idempotency: Not needed. Reading has no side effects.

Query parameters ​

NameTypeRequiredDescription
fromstringNoFirst day, YYYY-MM-DD. Default 90 days ago
tostringNoLast day, YYYY-MM-DD. Default today

Example request ​

bash
curl "https://api.rekberpay.com/v1/enterprise/audit/export.csv?from=2026-10-13&to=2026-10-13" \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -o export.csv
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/audit/export.csv?from=2026-10-13&to=2026-10-13', {
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
    },
});
const csv = await res.text();
python
import os

import requests

resp = requests.get(
    "https://api.rekberpay.com/v1/enterprise/audit/export.csv?from=2026-10-13&to=2026-10-13",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
    },
    timeout=30,
)
open("export.csv", "wb").write(resp.content)
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/audit/export.csv?from=2026-10-13&to=2026-10-13');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
    ],
]);
file_put_contents('export.csv', curl_exec($ch));
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Example response ​

200 OK with Content-Disposition: attachment; filename="rekberpay-enterprise-audit-fffffff2-ffff-4fff-8fff-ffffffffffff-2026-10-13.csv"

csv
seq,created_at,event,actor,ip,deal,amount,summary,previous_state,new_state
140451,2026-10-13T01:16:03.709Z,milestone.funded,Sandbox API key,,,21000000.00,Sandbox run SBX-408: funded test milestone via sandbox,,"{""status"":""funded"",""funding_method"":""sandbox""}"
140452,2026-10-13T01:29:41.428Z,milestone.approved,Sandbox API key,,,21000000.00,Sandbox run SBX-408: approved test milestone for release,,"{""status"":""approved""}"
140453,2026-10-13T01:36:48.405Z,milestone.released,Sandbox API key,,,21000000.00,Sandbox run SBX-408: released test milestone in 1 payout,,"{""status"":""released""}"

The header row and the first 3 rows of the file.

Errors ​

StatusCodeCause
400INVALID_QUERYA date is not YYYY-MM-DD, or from is after to
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
429RATE_LIMITEDOver the rate limit. Wait for Retry-After seconds

Check the books ​

GET/v1/enterprise/reconciliation

Compares every deal's stored funded and released totals with the sum of its milestones. balanced_all is null when the workspace has more than 1,000 deals and only the newest 1,000 were checked (truncated: true).

  • 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.

Example request ​

bash
curl https://api.rekberpay.com/v1/enterprise/reconciliation \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/reconciliation', {
    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/reconciliation",
    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/reconciliation');
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": {
        "deals": [
            {
                "id": "44444447-4444-4444-8444-444444444444",
                "reference": "DEAL-2026-0011",
                "stored_funded": 150000000,
                "computed_funded": 150000000,
                "stored_released": 150000000,
                "computed_released": 150000000,
                "balanced": true
            },
            {
                "id": "fffffff6-ffff-4fff-8fff-ffffffffffff",
                "reference": "DEAL-2026-0010",
                "stored_funded": 0,
                "computed_funded": 0,
                "stored_released": 0,
                "computed_released": 0,
                "balanced": true
            },
            {
                "id": "eeeeeee4-eeee-4eee-8eee-eeeeeeeeeeee",
                "reference": "DEAL-2026-0009",
                "stored_funded": 50000000,
                "computed_funded": 50000000,
                "stored_released": 30000000,
                "computed_released": 30000000,
                "balanced": true
            }
        ],
        "balanced_all": true,
        "truncated": false,
        "checked_at": "2026-10-13T14:33:16.674Z"
    }
}

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

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

Escrow, payment services and B2B deals for Indonesian businesses.