Update invoice status / payment fields

PATCHhttps://rebaar.in/api/v1/invoices/{id}View as Markdown

Under the same rules as the app: an issued invoice never goes back to `Draft`; `Cancelled` is final; a `Draft` moves only to `Sent` (not while approvals are pending) or `Cancelled`. `amountPaid` (and `status: "Paid"`, which means "paid in full") RECORDS A PAYMENT for the difference — a confirmed receipt dated `paidAt` (default today, IST), visible and voidable in Rebaar, and fires `invoice.paid` when it settles the invoice. The same call twice records one payment. `amountPaid` can only go up: lowering it is 409 `amount_paid_decrease` (void the payment in Rebaar instead). Above the net total (`netTotalPaise`: the total after credit and debit notes), or with a `status` that disagrees with the amount, is 422. An invoice with an issued credit or debit note cannot be cancelled (409 `has_notes`). `Partial` cannot be set on its own — it follows the payments.

Headers

HeaderValue
AuthorizationrequiredBearer ck_live_… — your API key from Settings → API keys
Content-Typerequiredapplication/json

Parameters

NameInTypeDescription
idrequiredpathstringThe invoice id, as returned by the list endpoint.

Request body

FieldTypeDescription
statusstringone of "Draft", "Sent", "Paid", "Overdue", "Partial", "Unpaid", "Cancelled"
amountPaidintegerTotal amount received so far. Raising it records a payment for the difference; it cannot be lowered. in PAISE (rupees × 100). ₹1,500.00 = 150000.
paidAtstring (date) or nullPayment date as an ISO YYYY-MM-DD string.
dueDatestring (date) or nullDue date as an ISO YYYY-MM-DD string.

Try it

This call changes data. Send runs it in your API sandbox — a practice company with sample data — with a sandbox key, never in your real company. To change real data, run the sample from your own machine with a live key. About the sandbox

curl -X PATCH 'https://rebaar.in/api/v1/invoices/f1a8c3d5-2e6b-4c9f-a017-3b5d8e2c4f96' \
  -H 'Authorization: Bearer ck_live_xxxxxxxx_…' \
  -H 'Content-Type: application/json' \
  -d '{
  "amountPaid": 5000000,
  "paidAt": "2026-10-15"
}'
Only sandbox keys (ck_test_…) — make one in Settings → API keys. It reaches your practice company, never your real data. 30 calls a minute.

Responses

200Updated. The body is `{ "ok": true }` — GET the record for its new state.
{
  "ok": true
}
400Validation failed. `error` is the first problem found; `field` names it when it is a location, GSTIN, email or delivery-address field.
{
  "error": "no fields to update"
}
401No `Authorization: Bearer …` header was sent. Or: The key is unknown, revoked or expired — or the company cannot use it.
unauthenticated — No `Authorization: Bearer …` header was sent.
{
  "error": "unauthenticated",
  "message": "Authorization: Bearer <api_key> required"
}
invalid_token — The key is unknown, revoked or expired — or the company cannot use it.
{
  "error": "invalid_token",
  "message": "API key not recognised, revoked, or expired"
}
402The company is not on the Scale plan, which includes the API. Or: The subscription is not active (trial over, payment failed, cancelled, paused, locked or closing). `reason` says which.
plan_required — The company is not on the Scale plan, which includes the API.
{
  "error": "plan_required",
  "message": "API access requires the Scale plan. This workspace is on Growth.",
  "currentPlan": "growth",
  "requiredPlan": "scale"
}
access_expired — The subscription is not active (trial over, payment failed, cancelled, paused, locked or closing). `reason` says which.
{
  "error": "access_expired",
  "reason": "payment_failed",
  "message": "Workspace does not currently have an active Scale subscription."
}
403The request came from an IP address that is not on the key's allowlist. Or: The key does not carry the scope this method needs: `read` for GET, `write` for POST, PATCH and DELETE.
ip_not_allowed — The request came from an IP address that is not on the key's allowlist.
{
  "error": "ip_not_allowed",
  "message": "Source IP 203.0.113.7 is not on the key's allowlist."
}
insufficient_scope — The key does not carry the scope this method needs: `read` for GET, `write` for POST, PATCH and DELETE.
{
  "error": "insufficient_scope",
  "message": "This API key does not have the 'write' scope.",
  "required": "write",
  "granted": [
    "read"
  ]
}
404No such invoice in this workspace.
{
  "error": "not_found"
}
409Refused by an invoice rule — e.g. `amount_paid_decrease`, `paid_follows_payments`, `pending_exists`, `invoice_cancelled`, `invoice_not_issued`, `has_notes`, `invoice_changed`.
{
  "error": "amount_paid_decrease",
  "message": "amountPaid can only go up through the API — each increase is recorded as a payment. To reduce what INV-2026-0042 shows as paid, void that payment in Rebaar."
}
422`amount_exceeds_total` or `status_disagrees_with_amount`.
amount_exceeds_total
{
  "error": "amount_exceeds_total",
  "message": "amountPaid cannot exceed the invoice total."
}
status_disagrees_with_amount
{
  "error": "status_disagrees_with_amount",
  "message": "An amount paid of 5000000 on a total of 11800000 makes the invoice Partial, not Paid."
}
429More than 120 requests in a minute with this key (30 with a sandbox key).
rate_limited — More than 120 requests in a minute with this key (30 with a sandbox key).
{
  "error": "Too many requests. Please try again later."
}
500Something failed on our side.
internal — Something failed on our side.
{
  "error": "internal"
}

Errors

Errors every call can return
StatusCodeMeaningWhat to do
401unauthenticatedNo `Authorization: Bearer …` header was sent.Send your API key as `Authorization: Bearer ck_live_…` on every request.
401invalid_tokenThe key is unknown, revoked or expired — or the company cannot use it.Check you copied the whole key. Make a new one in Settings → API keys if it was revoked or has expired.
403ip_not_allowedThe request came from an IP address that is not on the key's allowlist.Call from an allowed address, or change the key's IP allowlist in Settings → API keys.
402plan_requiredThe company is not on the Scale plan, which includes the API.The Owner moves the company to Scale in Settings → Billing.
402access_expiredThe subscription is not active (trial over, payment failed, cancelled, paused, locked or closing). `reason` says which.The Owner pays or renews in Settings → Billing; calls work again at once.
429—More than 120 requests in a minute with this key (30 with a sandbox key).Wait the number of seconds in the `Retry-After` header. Every reply carries `RateLimit-Remaining`, so you can slow down before this happens.
403insufficient_scopeThe key does not carry the scope this method needs: `read` for GET, `write` for POST, PATCH and DELETE.Make a key with the scope you need in Settings → API keys.
500internalSomething failed on our side.Retry with exponential backoff. If it keeps happening, email [email protected] with the time of the call.