Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api-reference/accounts/auto-recharge-get.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: "Get Auto Top-Up Setting"
openapi: "/api-reference/openapi/accounts.json GET /api/accounts/{id}/auto-recharge"
---
4 changes: 4 additions & 0 deletions api-reference/accounts/auto-recharge-update.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: "Update Auto Top-Up Setting"
openapi: "/api-reference/openapi/accounts.json PATCH /api/accounts/{id}/auto-recharge"
---
206 changes: 206 additions & 0 deletions api-reference/openapi/accounts.json
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,167 @@
}
}
},
"/api/accounts/{id}/auto-recharge": {
"get": {
"description": "Retrieve whether automatic top-up is enabled for the account.",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The unique identifier (UUID) of the account. Must be the authenticated account or another accessible via organization membership.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"security": [
{
"apiKeyAuth": []
},
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Auto top-up setting returned successfully.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeResponse"
}
}
}
},
"401": {
"description": "Unauthorized - invalid or missing authentication",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeErrorResponse"
},
"example": {
"error": "Unauthorized"
}
}
}
},
"403": {
"description": "Forbidden - account not accessible to the authenticated account",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeErrorResponse"
}
}
}
},
"404": {
"description": "Account not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeErrorResponse"
}
}
}
}
}
},
"patch": {
"description": "Enable or disable automatic top-up for the account.",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The unique identifier (UUID) of the account. Must be the authenticated account or another accessible via organization membership.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"security": [
{
"apiKeyAuth": []
},
{
"bearerAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeUpdateRequest"
}
}
}
},
"responses": {
"200": {
"description": "Auto top-up setting returned successfully.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeResponse"
}
}
}
},
"400": {
"description": "Invalid request body - `enabled` must be a boolean",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeErrorResponse"
},
"example": {
"error": "enabled must be a boolean"
}
}
}
},
"401": {
"description": "Unauthorized - invalid or missing authentication",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeErrorResponse"
},
"example": {
"error": "Unauthorized"
}
}
}
},
"403": {
"description": "Forbidden - account not accessible to the authenticated account",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeErrorResponse"
}
}
}
},
"404": {
"description": "Account not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountAutoRechargeErrorResponse"
}
}
}
}
}
}
},
"/api/credits/sessions": {
"post": {
"description": "Top up credits on the authenticated account.\n\n**One credit equals one US cent (\\$0.01).** The customer is charged `credits` plus a Stripe processing fee (US card pricing: 2.9% + \\$0.30) \u2014 e.g. `credits: 10000` charges \\$103.30 total (\\$100.00 credits + \\$3.30 fee).\n\n**Two outcomes, distinguished by response shape:**\n\n- **Auto-charged** \u2014 if the account has a card on file (from a prior subscription or top-up), the card is charged immediately and the response is `{ paymentIntentId, creditsPurchased, totalCents }`. Credits land in the account's balance asynchronously via Stripe webhook (typically within seconds). No human interaction required.\n\n- **Checkout required** \u2014 if no card is on file, or the saved card requires 3-D Secure authentication, the response is `{ id, url }` with a hosted Stripe Checkout URL. Redirect to that URL; credits land on successful payment.\n\nClients should discriminate on the presence of `url` (Checkout) vs `paymentIntentId` (auto-charged). Cards entered through the Checkout fallback are saved for future top-ups, so a customer's second top-up typically auto-charges.",
Expand Down Expand Up @@ -4277,6 +4438,51 @@
}
}
},
"AccountAutoRechargeResponse": {
"type": "object",
"required": [
"account_id",
"enabled"
],
"properties": {
"account_id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the account this setting belongs to.",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
"enabled": {
"type": "boolean",
"description": "Whether automatic top-up is enabled. `false` means the account has opted out and only explicit checkout top-ups can charge it.",
"example": true
}
}
},
"AccountAutoRechargeUpdateRequest": {
"type": "object",
"required": [
"enabled"
],
"properties": {
"enabled": {
"type": "boolean",
"description": "Set `false` to opt out of automatic top-up, `true` to opt back in."
}
}
},
"AccountAutoRechargeErrorResponse": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string",
"description": "Human-readable error message.",
"example": "Unauthorized"
}
}
},
"CreateCreditsSessionRequest": {
"type": "object",
"required": [
Expand Down
26 changes: 24 additions & 2 deletions credits.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Response shape:

## Automatic top-up

Every billed API request runs a credit gate before it executes. If `remaining_credits` doesn't cover the request's cost **and** the account has a saved Stripe card, Recoup silently charges **$5 (500 credits)** off-session and lets the request proceed. Most accounts with a working card never see an "insufficient credits" failure — the top-up is invisible.
Every billed API request runs a credit gate before it executes. If `remaining_credits` doesn't cover the request's cost **and** the account has a saved card **and** the account hasn't opted out (see [Opting out](#opting-out) below), Recoup silently charges **$5 (500 credits)** off-session and lets the request proceed. Most accounts with a working card never see an "insufficient credits" failure — the top-up is invisible.

The decision tree:

Expand All @@ -125,10 +125,32 @@ The decision tree:

### When auto top-up doesn't trigger

- The account has opted out of automatic top-up → 402 with `checkoutUrl`, no `declineReason`. The saved card is never charged off-session while opted out.
- The account has no saved Stripe card → 402 with `checkoutUrl`, no `declineReason`.
- Stripe declines the saved card (insufficient funds, expired, fraud, 3-D Secure required, etc.) → 402 with `checkoutUrl` + `declineReason`.
- A single request needs more than 500 credits (rare — only `POST /api/research/deep` at 25 and oversized `extract` calls come close) → request fails even though the top-up succeeded.

### Opting out

Automatic top-up is on by default and can be disabled per account:

```bash
curl -sS -X PATCH https://api.recoupable.dev/api/accounts/$ACCOUNT_ID/auto-recharge \
-H "x-api-key: $RECOUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
```

```json
{
"account_id": "acc_…",
"enabled": false
}
```

While opted out, no off-session charge is ever attempted: billed requests that exceed the remaining balance return **HTTP 402** with a `checkoutUrl` (see below), and topping up stays an explicit action. Opting out does **not** remove the saved card — manual top-ups through checkout keep working, and re-enabling later (`{"enabled": true}`) requires no card re-entry. Read the current setting with `GET /api/accounts/$ACCOUNT_ID/auto-recharge`. Full schema at [Get Auto Top-Up Setting](/api-reference/accounts/auto-recharge-get) and [Update Auto Top-Up Setting](/api-reference/accounts/auto-recharge-update).


### Tuning

The auto top-up amount is currently a constant at **$5 / 500 credits**. Per-account thresholds are not yet exposed — reach out to support if you need a different default.
Expand Down Expand Up @@ -179,7 +201,7 @@ Current as of this revision of the page. The authoritative source is the per-end
| [`POST /api/chat`](/api-reference/chat/workflow) (streaming) | ≥1 credit per turn — variable based on model token usage |
| [`GET /api/research/*`](/api-reference/research/search) (artist & non-artist research) | 5 credits per call |
| [`POST /api/research/people`](/api-reference/research/people) | 5 credits per call |
| [`POST /api/research/web`](/api-reference/research/web) | 5 credits per call |
| [`POST /api/research/web`](/api-reference/research/web) | 1 credit per call |
| [`POST /api/research/extract`](/api-reference/research/extract) | 5 credits × number of URLs |
| [`POST /api/research/enrich`](/api-reference/research/enrich) | 5 / 10 / 25 credits (base / core / ultra processor) |
| [`POST /api/research/deep`](/api-reference/research/deep) | 25 credits per call |
Expand Down
4 changes: 3 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,9 @@
"api-reference/accounts/subscription-get",
"api-reference/credits/sessions-create",
"api-reference/accounts/credits-get",
"api-reference/accounts/payment-method-get"
"api-reference/accounts/payment-method-get",
"api-reference/accounts/auto-recharge-get",
"api-reference/accounts/auto-recharge-update"
]
},
{
Expand Down