---
title: "Charge the saved card to top up prepaid balance"
method: POST
path: "/v1/orgs/{orgId}/billing/deposit"
tags: ["Billing"]
---

# Charge the saved card to top up prepaid balance

`POST /v1/orgs/{orgId}/billing/deposit`

Charges the org's default saved card off-session. The balance credit is applied by the payment_intent.succeeded webhook (the authoritative money signal), not this response: poll the balance after success.

## Path parameters

- `orgId` string, required

## Request body

- DepositRequest
  - `amountCents` integer, required — Amount to charge the saved card, in cents. The flat floor is $25 and the default per-deposit cap is $500 (raised to an approved monthly spend limit). While the org has usage running the endpoint requires at least one hour of the current burn; read the exact figure from Balance.minDepositCents rather than re-deriving it.
  - `captchaAction` string — Optional reCAPTCHA action the score was measured for (see DeviceSignals).
  - `captchaBand` string — Optional score band, pass|step_up|step_up_strict (see DeviceSignals). The band's step-up was already satisfied at the dashboard before this request was sent.
  - `captchaScore` number — Optional reCAPTCHA v3 score, 0 to 1 (see DeviceSignals). Recorded on the org and copied onto the dispute-evidence record; it never gates the deposit.
  - `deviceEventId` string — Optional Fingerprint event id (see DeviceSignals).
  - `deviceFingerprint` string — Optional Fingerprint visitor id (see DeviceSignals). Recorded and clustered. A device that puts the account on a verification hold gets 403 ACCOUNT_PENDING_VERIFICATION, or 403 VERIFICATION_UNAVAILABLE when the hold could not be recorded; every other verdict is observe-only.
  - `idempotencyKey` string — Client-generated id for this logical deposit; reused verbatim on retry so a network/client retry can't double-charge. Optional: the server generates one if absent (then retries won't dedupe).

## Response `200`

Charge outcome (status drives the dashboard's next step)

- DepositResult
  - `clientSecret` string — Set only when status is requires_action (on-session SCA).
  - `paymentIntentId` string, required
  - `publishableKey` string — Set with clientSecret: the Stripe publishable key Stripe.js needs to confirm the PaymentIntent on-session.
  - `status` string, required — Stripe PaymentIntent status. "succeeded" → credit lands via webhook; "requires_action" → complete SCA on-session with clientSecret; "requires_payment_method" → the card was declined.

## Other responses

- `400` — The request is invalid
- `401` — Missing or invalid API key
- `403` — API key lacks the required scope
- `503` — A required integration (e.g. payments) is not configured

## Changes

- **2026-09-23** `eccb596a4949` — 1 info
  - added the optional property `publishableKey` to the response with the `200` status
- **2026-09-12** `57633a329e9c` — 1 warning
  - the `amountCents` request property's min was set to `2500.00`
- **2026-09-05** `383d5864ac75` — 3 info
  - added the new optional request property `captchaAction`
  - added the new optional request property `captchaBand`
  - added the new optional request property `captchaScore`
- **2026-09-04** `cca00bd5b0b5` — 2 info
  - added the new optional request property `deviceEventId`
  - added the new optional request property `deviceFingerprint`
- **2026-09-04** `4a338e447d39` — 1 warning
  - removed the request property `promoCode`

[Change history](https://skmtc.dev/openrelay/apis/openrelay-api/changes/v1/orgs/:orgId/billing/deposit/post.md)

---

[API](https://skmtc.dev/openrelay/apis/openrelay-api.md) · [All operations](https://skmtc.dev/openrelay/apis/openrelay-api/llms.txt) · [OpenAPI document](https://skmtc.dev/openrelay/apis/openrelay-api/revisions/24a11ebdab5e?raw)
