Skip to content

Enterprise deal templates ​

A template is a named milestone plan. The dashboard applies it on the New deal form; through the API you read the plan and build the milestones of POST /v1/enterprise/deals from it. A workspace holds up to 50 templates. Auth, roles, the workspace header and the shared limits are explained in Enterprise overview.

Endpoints ​

MethodPathEndpointAuth
GET/v1/enterprise/templatesList templatesviewer
POST/v1/enterprise/templatesCreate a templateoperator
PATCH/v1/enterprise/templates/:idUpdate a templateoperator
DELETE/v1/enterprise/templates/:idDelete a templateoperator

Template milestones ​

Each plan has 1 to 20 milestones:

FieldTypeDescription
titlestring2 to 180 characters
amount_pctinteger1 to 100. Share of the deal total
amountintegerWhole rupiah, 10,000 to 50,000,000,000
required_evidencestringOptional, at most 300 characters
due_offset_daysintegerOptional, 0 to 365. Days after the deal is created

Either every milestone has amount_pct and they add up to exactly 100, or every milestone has amount. To turn percentages into amounts, round each share down to whole rupiah and add the remainder to the last milestone.


List templates ​

GET/v1/enterprise/templates

Every template in the workspace, sorted by name.

  • 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/templates \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/templates', {
    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/templates",
    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/templates');
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": "66666664-6666-4666-8666-666666666666",
            "name": "Software delivery, 3 milestones",
            "description": "Fixed-price builds paid on design sign-off, beta and go-live.",
            "milestones": [
                {
                    "title": "Design sign-off",
                    "amount": 30000000,
                    "required_evidence": "Approved design document",
                    "due_offset_days": 14
                },
                {
                    "title": "Beta release",
                    "amount": 45000000,
                    "required_evidence": "Staging link and test report",
                    "due_offset_days": 45
                }
            ],
            "created_by": "88888883-8888-4888-8888-888888888888",
            "created_at": "2026-10-01T22:33:06.162Z",
            "updated_at": "2026-10-01T22:33:06.162Z"
        },
        {
            "id": "77777774-7777-4777-8777-777777777777",
            "name": "Standard procurement, 4 milestones",
            "description": "Goods orders: deposit, production, shipment and acceptance.",
            "milestones": [
                {
                    "title": "Deposit",
                    "amount_pct": 20
                },
                {
                    "title": "Production complete",
                    "amount_pct": 30,
                    "required_evidence": "Factory photos and QC report",
                    "due_offset_days": 21
                }
            ],
            "created_by": "88888884-8888-4888-8888-888888888888",
            "created_at": "2026-10-01T02:33:06.162Z",
            "updated_at": "2026-10-01T02:33:06.162Z"
        }
    ]
}

Lists are cut to the first 2 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

Create a template ​

POST/v1/enterprise/templates
  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 60 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.

Body (JSON) ​

NameTypeRequiredDescription
namestringYes2 to 120 characters
milestonesarrayYes1 to 20 milestones, see above
descriptionstringNoAt most 500 characters

Example request ​

bash
curl -X POST https://api.rekberpay.com/v1/enterprise/templates \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: 99999994-9999-4999-8999-999999999999" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Supplier order, 30/70",
    "description": "Deposit on order, balance on delivery.",
    "milestones": [
      {
        "title": "Deposit on purchase order",
        "amount_pct": 30,
        "required_evidence": "Signed purchase order"
      },
      {
        "title": "Balance on delivery",
        "amount_pct": 70,
        "required_evidence": "Signed delivery note",
        "due_offset_days": 30
      }
    ]
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/templates', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': '99999994-9999-4999-8999-999999999999',
    },
    body: JSON.stringify({
        name: "Supplier order, 30/70",
        description: "Deposit on order, balance on delivery.",
        milestones: [
            {
                title: "Deposit on purchase order",
                amount_pct: 30,
                required_evidence: "Signed purchase order"
            },
            {
                title: "Balance on delivery",
                amount_pct: 70,
                required_evidence: "Signed delivery note",
                due_offset_days: 30
            }
        ]
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/enterprise/templates",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "99999994-9999-4999-8999-999999999999",
    },
    json={
        "name": "Supplier order, 30/70",
        "description": "Deposit on order, balance on delivery.",
        "milestones": [
            {
                "title": "Deposit on purchase order",
                "amount_pct": 30,
                "required_evidence": "Signed purchase order",
            },
            {
                "title": "Balance on delivery",
                "amount_pct": 70,
                "required_evidence": "Signed delivery note",
                "due_offset_days": 30,
            },
        ],
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/templates');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: 99999994-9999-4999-8999-999999999999',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'name' => 'Supplier order, 30/70',
        'description' => 'Deposit on order, balance on delivery.',
        'milestones' => [
            [
                'title' => 'Deposit on purchase order',
                'amount_pct' => 30,
                'required_evidence' => 'Signed purchase order',
            ],
            [
                'title' => 'Balance on delivery',
                'amount_pct' => 70,
                'required_evidence' => 'Signed delivery note',
                'due_offset_days' => 30,
            ],
        ],
    ]),
]);
$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": {
        "id": "aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
        "name": "Supplier order, 30/70",
        "description": "Deposit on order, balance on delivery.",
        "milestones": [
            {
                "title": "Deposit on purchase order",
                "amount_pct": 30,
                "required_evidence": "Signed purchase order"
            },
            {
                "title": "Balance on delivery",
                "amount_pct": 70,
                "required_evidence": "Signed delivery note",
                "due_offset_days": 30
            }
        ],
        "created_by": "33333333-3333-4333-8333-333333333333"
    }
}

Errors ​

StatusCodeCause
400INVALID_BODYA field failed validation, for example percentages that do not add up to 100
409TEMPLATE_LIMITThe workspace already has 50 templates
409TEMPLATE_BUSYAnother template is being saved. 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

A real INVALID_BODY answer:

400 Bad Request

json
{
    "success": false,
    "error": {
        "code": "INVALID_BODY",
        "message": "Invalid request.",
        "details": {
            "formErrors": [],
            "fieldErrors": {
                "milestones": [
                    "amount_pct must add up to 100 (got 60)."
                ]
            }
        }
    }
}

Update a template ​

PATCH/v1/enterprise/templates/:id

Any of name, description (null clears it) and milestones. A new milestones list replaces the whole plan.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 60 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 template ID

Example request ​

bash
curl -X PATCH https://api.rekberpay.com/v1/enterprise/templates/aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: bbbbbbb4-bbbb-4bbb-8bbb-bbbbbbbbbbbb" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Supplier order, deposit 30%"
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/templates/aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa', {
    method: 'PATCH',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': 'bbbbbbb4-bbbb-4bbb-8bbb-bbbbbbbbbbbb',
    },
    body: JSON.stringify({
        name: "Supplier order, deposit 30%"
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.patch(
    "https://api.rekberpay.com/v1/enterprise/templates/aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "bbbbbbb4-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
    },
    json={
        "name": "Supplier order, deposit 30%",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/templates/aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PATCH',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: bbbbbbb4-bbbb-4bbb-8bbb-bbbbbbbbbbbb',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'name' => 'Supplier order, deposit 30%',
    ]),
]);
$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": "aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
        "name": "Supplier order, deposit 30%",
        "description": "Deposit on order, balance on delivery.",
        "milestones": [
            {
                "title": "Deposit on purchase order",
                "amount_pct": 30,
                "required_evidence": "Signed purchase order"
            },
            {
                "title": "Balance on delivery",
                "amount_pct": 70,
                "required_evidence": "Signed delivery note",
                "due_offset_days": 30
            }
        ],
        "created_by": "33333333-3333-4333-8333-333333333333",
        "created_at": "2026-10-13T14:33:16.338Z",
        "updated_at": "2026-10-13T14:33:16.338Z"
    }
}

Errors ​

StatusCodeCause
400INVALID_BODYA field failed validation, or nothing to update
404NOT_FOUNDNo such template 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
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

Delete a template ​

DELETE/v1/enterprise/templates/:id

Deals already created from it do not change.

  • Auth: A workspace API key (Authorization: Bearer rpe_...), a personal API key or a dashboard session.
  • Role: operator, finance, admin or owner.
  • Rate limit: 60 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 template ID

Example request ​

bash
curl -X DELETE https://api.rekberpay.com/v1/enterprise/templates/aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa \
  -H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
  -H "Idempotency-Key: ccccccc4-cccc-4ccc-8ccc-cccccccccccc"
js
const res = await fetch('https://api.rekberpay.com/v1/enterprise/templates/aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa', {
    method: 'DELETE',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_WORKSPACE_KEY}`,
        'Idempotency-Key': 'ccccccc4-cccc-4ccc-8ccc-cccccccccccc',
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.delete(
    "https://api.rekberpay.com/v1/enterprise/templates/aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_WORKSPACE_KEY']}",
        "Idempotency-Key": "ccccccc4-cccc-4ccc-8ccc-cccccccccccc",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/enterprise/templates/aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_WORKSPACE_KEY'),
        'Idempotency-Key: ccccccc4-cccc-4ccc-8ccc-cccccccccccc',
    ],
]);
$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": "aaaaaaa4-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
        "deleted": true
    }
}

Errors ​

StatusCodeCause
404NOT_FOUNDNo such template 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
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.