Skip to main content
POST
cURL

Authorizations

x-api-key
string
header
required

Your Recoup API key. Learn more.

Body

application/json

The account to set, the balance to leave it at, and why

account_id
string<uuid>
required

UUID of the account whose balance is being set. Must be an existing account — an unknown UUID is a 404, not a silent no-op.

remaining_credits
integer
required

The balance to leave the account holding, in credits (1 credit = 1 US cent). Absolute, not a delta. Zero is allowed — it is how an account is deliberately zeroed out. Negative values are rejected with a 400, even though ordinary usage can overdraw a balance below zero on its own.

Required range: x >= 0
reason
string
required

Why the grant was made, in plain language — e.g. Trial headroom for the Aug 12 label demo. Required and non-empty (a whitespace-only string is rejected): this is the field that makes a grant distinguishable from a Stripe top-up or a monthly reset when someone asks months later. Stored verbatim and returned by the events endpoint.

Minimum string length: 1

Response

Balance set and the grant recorded

status
enum<string>
required

Status of the request

Available options:
success
grant_id
string<uuid>
required

UUID of the recorded grant row. Matches the id of the corresponding entry in the grants array of GET /api/admins/credits/events.

account_id
string<uuid>
required

UUID of the account whose balance was set (echoes the request)

remaining_credits
integer
required

The balance the account now holds — the value supplied in the request

previous_credits
integer | null
required

The balance immediately before the grant. Null when the account had no credits row at all and one was created by this request.

reason
string
required

The reason recorded with the grant (echoes the request)

granted_by
string<uuid>
required

UUID of the admin account that made the grant, resolved from the credentials on the request. Never taken from the body.

granted_at
string<date-time>
required

When the grant was recorded

expires_at
string<date-time>
required

When the monthly reset becomes eligible to overwrite this balance — one month after granted_at, clamped to the last day of the target month when that month is shorter (a grant on Jan 31 expires Feb 28, not Mar 3). The overwrite is lazy, not scheduled: it happens on the first read of the account's balance at or after this time, so the granted balance can outlive expires_at indefinitely if nothing reads it. Treat it as the point after which the balance is no longer guaranteed — it is deliberately never later than the moment the reset actually becomes eligible, so it can under-promise by up to a day but never over-promise.