# Camino Treasury > Camino Treasury is a platform for managing organizational crypto wallets and automating treasury operations with yield strategies. Users deposit stablecoins (USDC or USDT) into the C0 yield-bearing token to earn U.S. Treasury yield on idle balances while keeping funds accessible. The platform provides a REST API, a dashboard, role-based access control, a unified transfer feed across on-chain and fiat rails, and merkle-based yield distribution. ## Docs - [Introduction](https://docs.caminotreasury.com): Platform overview and getting started links - [Welcome](https://docs.caminotreasury.com/get-started/welcome): What Camino Treasury is and what you can do with it - [Quickstart](https://docs.caminotreasury.com/guides/quickstart): Step-by-step guide to create an organization, connect wallets, and monitor your treasury - [US Treasury Yield](https://docs.caminotreasury.com/get-started/us-treasury-yield): How yield is generated from U.S. Treasury bills via the M^0 protocol - [Platform Overview](https://docs.caminotreasury.com/get-started/platform-overview): Organizations, wallets, bank accounts, transfers, deposits, withdrawals, and yield - [Generate API Key](https://docs.caminotreasury.com/get-started/generate-api-key): Create and use an API key from the dashboard - [Wallets](https://docs.caminotreasury.com/guides/wallets): Create and manage server-managed wallets - [Deposit and Start Earning](https://docs.caminotreasury.com/guides/deposit-and-earn): Deposit stablecoins into C0 and withdraw back to stablecoins - [Yield Tracking](https://docs.caminotreasury.com/guides/yield-tracking): Look up YieldDistributor merkle claims for a holder - [Core Concepts](https://docs.caminotreasury.com/guides/core-concepts): Organizations, wallets, bank accounts, transfers, deposits, withdrawals, yield, and permissions - [API Integration Guide](https://docs.caminotreasury.com/guides/api-integration): End-to-end integration walkthrough with code examples and a complete TypeScript client - [API Reference](https://docs.caminotreasury.com/api-reference/introduction): Full endpoint reference with OpenAPI spec - [Authentication](https://docs.caminotreasury.com/api-reference/authentication): API key authentication, key scoping, and error responses - [Rate Limiting](https://docs.caminotreasury.com/api-reference/rate-limiting): Request limits, response headers, and retry behavior - [Supported Platforms](https://docs.caminotreasury.com/api-reference/supported-platforms): Supported chains and tokens ## Supported Chains | Chain ID | Network | |----------|---------| | `1` | Ethereum Mainnet | | `11155111` | Sepolia Testnet | ## Supported Tokens All on-chain tokens use 6 decimal places. | Symbol | Name | Description | |--------|------|-------------| | USDC | USD Coin | Stablecoin — deposit input | | USDT | Tether USD | Stablecoin — deposit input | | C0 | C0 | Yield-bearing token | | M | M | Underlying protocol token | | USDB | USDB | Bridge USD (fiat-rail asset on transfers) | ## Core Concepts ### Organizations An organization is the top-level entity representing a company, DAO, or team. It contains all wallets, bank accounts, transfers, and team members. Each API key is scoped to a single organization and all data is isolated per organization. ### Wallets Server-managed on-chain wallets owned by an organization. Each wallet has a generated Ethereum `address` (used as its identifier across the API), an optional `label` (1-100 chars), and creation/update timestamps. The address is generated by the server when the wallet is created. ### Bank Accounts Linked bank accounts for the organization's fiat on/off-ramp via Bridge.xyz. Each row carries the bank metadata (bank name, routing number, last-4) plus the UUID `id` referenced from `Transfer.bankAccount.id`. ### Recipients Saved destination addresses for outbound transfers (address book). Org-scoped, with a human-readable `label` per address. `address` is unique per organization. Used to pick a known destination when initiating an outbound transfer instead of pasting a raw address. ### Transfers `GET /v1/transfers` returns all transfers initiated by the org — wallet→wallet, bank→wallet (onramp), and wallet→bank (offramp) — under one unified shape. Each row carries symmetric `from` and `to` sides; either side can be a wallet (`address`, `chainId`) or a bank account (`bankAccount` embed). Lifecycle is a single `status`: `pending | submitted | completed | failed`. Sorted by `createdAt` descending. Cursor-paginated (`limit`, `cursor`); response envelope is `{ data, nextCursor, count }`. ### Yield Yield is distributed periodically via the on-chain `YieldDistributor`. For each published period, the operator commits a merkle root; holders submit a proof to `claim()` and receive their allocation directly. `GET /v1/yield/{address}?chainId={n?}` (requires API key) returns `{ data: ClaimEntry[], count }`, where each entry carries its own `chainId` + `distributor` and a `status` of `claimed` (already pulled on-chain) or `unclaimed` (finalized and within the claim window). Unpublished, unfinalized, and expired-without-claim periods are filtered server-side. `GET /v1/yield/artifacts?periodId={n}` returns the full immutable artifact (root, every leaf, every proof, totals) for a published period — public, used for independent verification. ### Permissions & Roles Three roles with role-based access control: - **Owner**: Full access — manage billing, delete organization, add/remove members - **Admin**: Management access — manage wallets, bank accounts, and recipients; view all data - **Member**: Read-only access — view wallets, bank accounts, transfer feed, and yield claims ## Authentication All `/v1/*` endpoints (except `GET /v1/yield/artifacts`) require an API key passed in the `x-api-key` header: ``` curl https://api.caminotreasury.com/v1/wallets \ -H "x-api-key: your-api-key" ``` API keys are scoped to a single organization. Requests without a valid key receive a `401 Unauthorized` response. ## Base URL ``` https://api.caminotreasury.com/v1 ``` ## Rate Limiting All endpoints are rate-limited to 100 requests per 60-second window per API key. Response headers: - `X-RateLimit-Limit`: Maximum requests per window (100) - `X-RateLimit-Remaining`: Requests remaining in the current window - `Retry-After`: Seconds to wait before retrying (only on 429) ## API Endpoints ### Wallets - `GET /wallets` — List the organization's wallets. Sortable by `created_at` or `label`. Returns `{ data: Wallet[], count }`. - `GET /wallets/{address}` — Get a single wallet by its on-chain address. - `POST /wallets` — Create a new server-managed wallet. Body (optional): `{ label?: string }`. The Ethereum address is generated automatically. If `label` is omitted, the server assigns `Wallet N` (N = next number for the org; deleted wallets count toward the next number so labels are never reused). - `PATCH /wallets/{address}` — Update a wallet's label. Body: `{ label: string }`. ### Bank Accounts - `GET /bank-accounts` — List the organization's linked bank accounts. Requires a Bridge customer record. ### Recipients - `GET /recipients` — List saved recipients. Sortable by `created_at` or `label`. Returns `{ data: Recipient[], count }`. - `GET /recipients/{id}` — Get a single recipient by id. - `POST /recipients` — Create a recipient. Body: `{ address, label }`. 400 on duplicate (`address` already exists for the org). - `PATCH /recipients/{id}` — Update `label` and/or `address`. At least one field required. - `DELETE /recipients/{id}` — Delete a recipient. 204 on success. ### Transfers - `GET /transfers?limit={n}&cursor={opaque?}` — All transfers for the org (wallet→wallet, bank→wallet, wallet→bank) under one unified shape. Returns `{ data: Transfer[], nextCursor: string | null, count }`. ### Yield - `GET /yield/{address}?chainId={n?}` — Returns `{ data: ClaimEntry[], count }` for a holder across every configured chain (or restricted to `chainId` if passed). Each entry has `{ chainId, distributor, periodId, status, root, index, account, amount, proof }`. - `GET /yield/artifacts?periodId={n}` — Full artifact JSON (root, all leaves, all proofs, totals) for a published period. Public — no API key required. ## Response Codes - `200` — Success - `201` — Created - `400` — Bad Request (validation error) - `401` — Unauthorized (missing or invalid API key) - `404` — Not Found - `409` — Conflict (resource already exists) - `429` — Too Many Requests (rate limit exceeded) - `500` — Internal Server Error ## Data Schemas ### Wallet ```json { "address": "0x742d35cc6634c0532925a3b844bc454e4438f44e", "label": "Main Treasury", "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z" } ``` Wallets are identified by their on-chain `address` across every endpoint. ### BankAccount ```json { "id": "11111111-2222-3333-4444-555555555555", "bankName": "Acme Bank", "accountOwnerName": "Acme Corp", "businessName": "Acme Inc.", "accountType": "us", "accountOwnerType": "business", "currency": "usd", "routingNumber": "021000021", "accountNumberLast4": "1234", "checkingOrSavings": "checking", "createdAt": "2026-01-15T10:30:00.000Z", "updatedAt": "2026-01-15T10:30:00.000Z" } ``` `id` is the UUID referenced from `Transfer.bankAccount.id`. Internal fields (`organizationId`, `userId`, `bridgeExternalAccountId`, `plaidItemId`/`plaidAccountId`, `active`) are not exposed. ### Recipient ```json { "id": 42, "address": "0x742d35cc6634c0532925a3b844bc454e4438f44e", "label": "Treasury Cold Wallet", "createdAt": "2026-05-20T12:00:00.000Z", "updatedAt": "2026-05-20T12:00:00.000Z" } ``` `address` is unique per organization. `label` is human-readable (1-100 chars). The internal `organizationId` is not exposed. ### Transfer ```json { "id": "9c1a8b2e-4f3d-4a5b-8c6d-7e8f9a0b1c2d", "from": { "address": null, "bankAccount": { "id": "11111111-2222-3333-4444-555555555555", "bankName": "Acme Bank", "accountOwnerName": "Acme Corp", "accountNumberLast4": "1234" }, "chainId": null, "currency": "USD", "amount": "100.00" }, "to": { "address": "0x742d35cc6634c0532925a3b844bc454e4438f44e", "bankAccount": null, "chainId": 1, "currency": "USDC", "amount": "99.50" }, "status": "pending", "transactionHash": null, "createdAt": "2026-05-20T12:00:00.000Z", "updatedAt": "2026-05-20T12:03:42.000Z" } ``` Each side is symmetric: either `address` + `chainId` (wallet) or `bankAccount` (bank). For wallet→wallet transfers both sides are wallets; for onramps `from` is a bank; for offramps `to` is a bank. `currency` is `"USDC" | "USDT" | "USD" | "C0"`. `amount` is a human-decimal string in the side's `currency`. `status` is `pending | submitted | completed | failed`. `transactionHash` is populated once the on-chain leg (if any) has been submitted. The embedded `bankAccount` includes display fields only — for the full record (routing, currency, etc.), look up the same `id` in `GET /v1/bank-accounts`. ### ClaimEntry (yield response item) ```json { "chainId": 1, "distributor": "0x1c8F111f189EF1F03D41e85C03D5dbFfb9e8A86B", "periodId": "5", "status": "unclaimed", "root": "0xb6e5...", "index": 12, "account": "0x742d...", "amount": "1500000", "proof": ["0x14158d04", "0xc09dc2f4"] } ``` To claim, call `YieldDistributor.claim(periodId, index, account, amount, proof)` on the entry's `distributor` (on its `chainId`) with the fields from an `unclaimed` entry. ## Validation Rules - Ethereum addresses must match `^0x[a-fA-F0-9]{40}$` - Wallet labels: 1-100 characters - Supported stablecoins for deposit: `USDC`, `USDT` - Pagination (transfers): `limit` 1-200 (default 50); `cursor` opaque string from previous response's `nextCursor` (omit for the first page) ## Glossary - **EOA (Externally Owned Account)**: A blockchain account controlled by a private key - **ERC-20 Token**: Standard interface for fungible tokens on Ethereum - **C0 Token**: The yield-bearing token in Camino Treasury; deposit USDC/USDT to receive C0 - **M^0 Protocol**: Decentralized protocol that issues M tokens backed 1:1 by short-term U.S. Treasury bills - **YieldDistributor**: On-chain merkle-claim contract that distributes yield to holders each period - **APY (Annual Percentage Yield)**: Rate of return over one year, accounting for compound interest - **Gas Fee**: Transaction fee paid to execute operations on the blockchain - **DeFi (Decentralized Finance)**: Financial services built on blockchain without traditional intermediaries