/api/v1/cards/sub-account write:sub_account | admin Re-files cards between your own inventory and one of your sub-accounts. This changes a label and nothing else: the cards never leave their bins, handling, insurance, billing and custody are untouched, and the move itself is not charged. Pass sub_account: null (or "main") to file cards back into your own inventory. The call is all-or-nothing — if any unique_id is unknown or belongs to another account the whole request is rejected and not one card moves. A unique_id is matched across both raw cards and graded slabs: you know a card by its CARD-RIP… id and should not have to know which table we keep it in. GET /cards can now list slabs too — pass ?type=graded or ?type=all — so a sub-account you file them into is visible there as well.
All-or-nothing on purpose: a partner is never told "moved 4" and left to work out which of five failed. The destination slug is resolved before a single card row is read, and the ownership check and the update share one transaction, so a rejected call leaves your inventory exactly as it was.
This endpoint needs its own write:sub_account scope; no existing scope is accepted as a substitute. write:transfer is deliberately NOT enough: that scope only appends a row to your transfer log and never mutates a card, whereas this one UPDATEs up to 500 rows, so lending it here would have quietly widened every transfer key you already hold. Ask your account manager to add write:sub_account when your sub-accounts are set up — the same moment, so it is not a separate errand.
Nothing physical happens and nothing is billed. Moving a card between sub-accounts does not move it in the warehouse, does not re-open a holding period, and does not appear as a line on your invoice — it is a metadata change to how your inventory is presented back to you.
The "Try it" body names "docs-demo", which is a RESERVED slug no account can ever own, so pressing Run cannot re-file a real card no matter what is in the sidebar: the destination is resolved before a single card row is read, and the call comes back as a 400 that lists the slugs your account does accept. Send a real destination from your own client, not from this page.
POST /api/v1/cards/sub-account write These inputs are shared across all docs pages, so an id entered here carries over.
{
"unique_ids": [
"CARD-EXAMPLE-1"
],
"sub_account": "docs-demo"
}Not run yet. Press Run to make a live call against https://service.rip.fun (through this demo's server-side proxy; the API key never reaches the browser).
curl -X POST 'https://service.rip.fun/api/v1/cards/sub-account' \
-H 'X-API-Key: rip_…' \
-H 'Content-Type: application/json' \
-d '{"unique_ids":["CARD-EXAMPLE-1"],"sub_account":"docs-demo"}' | Field | Type | Required | Description |
|---|---|---|---|
unique_ids | string[] | yes | Cards to re-file, at most 500 per call. A singular unique_id string is accepted instead, mirroring POST /withdrawals. Duplicates and blanks are collapsed before the cap is applied |
sub_account | string | null | yes | Destination slug (matched case-insensitively), or null / "main" / "none" / "" for your own inventory — note the empty string counts, so a <select> whose default option has value="" un-files rather than erroring. The key must be PRESENT: omitting it entirely is a 400, never an implicit un-filing. "all" is rejected — meaningful as a filter, meaningless as a destination |
data)| Field | Description |
|---|---|
moved | How many distinct cards were actually re-filed, raw cards and graded slabs together. Normally this equals the distinct ids you sent, since an unknown id is rejected outright rather than partially applied; it is counted from the rows the write really changed, so a card moved out from under the call by a concurrent request is not counted as moved |
sub_account | Where they landed: { slug, name }, or null when the cards were filed back into your own inventory |
| Status | Code | When |
|---|---|---|
| 400 | sub_account is required | the sub_account key is absent from the body, or is neither a string nor null |
| 400 | unique_ids is required | unique_ids (or unique_id) missing, or empty once blanks are dropped |
| 400 | too many cards | more than 500 distinct unique_ids in one call — split the batch |
| 400 | unknown sub_account | the destination slug does not exist on your account; the message lists the valid values |
| 400 | sub-account is retired | the destination exists but has been retired — it keeps the cards already filed under it, but cannot receive more |
| 400 | invalid destination | "all" was passed as the destination |
| 403 | Tenant API key required | key is not tenant-scoped |
| 403 | Insufficient permissions | key is tenant-scoped but carries neither write:sub_account nor admin; the body names the required scopes |
| 404 | not found | any unique_id is not in your inventory — the message names up to ten of them. Nothing moved |
See Errors for the response envelope and the full code list.