/api/v1/sends sends:create You hold prize inventory with CardOS — a specific card set aside for first place, a shelf of pre-opened prizes for everyone who paid to enter. A send delivers one of those to a wallet. The prize is HELD, never fulfilled for you: the token lands in the winner's wallet and stops there, and redeeming it for the physical item is their decision, later. Returns 202 — delivery is one or more on-chain transactions and is asynchronous; take send.fulfilled / send.failed or poll GET /sends/:send_id. Whether an item is minted to the winner or transferred from the CardOS server wallet is decided per item, not requested.
A sealed product (CONTAINER) is TRANSFER-only. Minting a container needs a registered on-chain product type and a warehouse serial, which is an intake operation — a container that is not already minted comes back in skipped[] as container_not_minted rather than being silently minted.
buyback_eligible is not a database flag. The sell-back contract allows a sale only when the on-chain window names the seller, and a transferred prize's window still names whoever the card was first distributed to — so CardOS re-opens the window on chain. A sealed product records unsupported_asset_type (containers have no sell-back window), and a card with no price group records no_oracle_group. If buyback_registered_at is null, that item cannot be sold back.
If EVERY item is skipped the call is 409 no_sendable_items and your Idempotency-Key is NOT burned — fix the list and retry with the same key.
POST /api/v1/sends money These inputs are shared across all docs pages, so an id entered here carries over.
{
"wallet_address": "0x0000000000000000000000000000000000000000",
"items": [
{
"unique_id": "CARD-EXAMPLE-1"
}
],
"reference": "docs-example"
}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/sends' \
-H 'X-API-Key: rip_…' \
-H 'Idempotency-Key: 0fd76539-86ba-41ab-9658-458a417f042f' \
-H 'Content-Type: application/json' \
-d '{"wallet_address":"0x0000000000000000000000000000000000000000","items":[{"unique_id":"CARD-EXAMPLE-1"}],"reference":"docs-example"}' | Field | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | header | yes | Your unique id for this prize — replays return the original send instead of sending it twice |
wallet_address | string | yes | The winner's wallet. The prize is minted or transferred to it and stays there |
items | array | yes | One to fifty assets, each by ONE id: { "unique_id": "CARD-…" | "GRADED-…" | "SEALED-…" } or { "container_token_id": "777" } for a sealed product named by its on-chain id. A bare string is treated as a unique_id |
reference | string | — | Your own handle for the send (a tournament id, a placement), ≤255 chars, echoed back on reads and in the webhooks |
metadata | object | — | Opaque to CardOS; returned unchanged |
buyback_eligible | boolean | — | Re-open the on-chain sell-back window in the WINNER's name once each item lands. Without it a transferred prize cannot be sold back — see the notes |
data)| Field | Description |
|---|---|
send_id / status | The send, and in_progress → complete | complete_with_errors |
items[] | Per item: unique_id, asset_type (CARD | GRADED | CONTAINER), action (MINT | TRANSFER — decided, not requested), status (PENDING → SENDING → SENT | FAILED), token_id, contract_address, tx_hash, error |
items[].buyback_registered_at / buyback_error | Whether the sell-back window was re-opened in the winner's name, or why not |
skipped[] | Assets refused at the door with the reason (burned, listed, already_queued, not_held_by_server_wallet, container_not_minted) — never a silent drop |
sent_count / failed_count / item_count | Totals, filled in as the send lands |
| Status | Code | When |
|---|---|---|
| 400 | missing_idempotency_key | no Idempotency-Key header (or idempotency_key body field) |
| 400 | invalid_wallet_address | wallet_address missing or not an address |
| 400 | no_items / too_many_items | items empty, or more than 50 |
| 400 | invalid_item | an item carrying both ids, neither id, or a non-numeric container_token_id |
| 404 | item_not_found | a unique_id or container_token_id that is not a CardOS asset |
| 409 | ambiguous_item | a unique_id that matches more than one asset table |
| 409 | idempotency_mismatch | the key was already used for a different wallet_address |
| 409 | no_sendable_items | every item was skipped — the reasons are in the message; the key is not burned |
See Errors for the response envelope and the full code list.