Overview
This guide walks you through integrating the Camino Treasury API to programmatically manage wallets, track transactions, prepare deposits and withdrawals, estimate yield, and configure webhooks.
Authentication
The Camino Treasury API uses API key authentication. Include your key in the x-api-key header on every request.
API keys are scoped to a single organization. All data returned is isolated to that organization.
Base URL
All API requests should be made to:
https://api.caminotreasury.com/v1
Common Response Codes
Code Description 200Success 201Created 400Bad Request - Validation error 401Unauthorized - Missing or invalid API key 404Not Found 409Conflict - Resource already exists 429Too Many Requests - Rate limit exceeded 500Internal Server Error
Getting Started
1. Fetch Your Wallets
Start by fetching all wallets in your organization:
const response = await fetch ( 'https://api.caminotreasury.com/v1/wallets' , {
headers: { 'x-api-key' : 'your-api-key' }
});
const { data : wallets , count } = await response . json ();
2. Get Balances
Fetch token balances for a specific wallet on a chain:
const chainId = 43114 ; // Avalanche
const address = '0x742d35cc6634c0532925a3b844bc454e4438f44e' ;
const response = await fetch (
`https://api.caminotreasury.com/v1/ ${ chainId } /balances/ ${ address } ` ,
{ headers: { 'x-api-key' : 'your-api-key' } }
);
const { data : balances , count } = await response . json ();
// balances is an array of token balances:
// [
// {
// "token": "0xa0b8...49dc",
// "name": "USDC",
// "symbol": "USDC",
// "raw": "10000500000",
// "decimals": 6
// },
// {
// "token": "0xdac1...1ec7",
// "name": "USDT",
// "symbol": "USDT",
// "raw": "5000000000",
// "decimals": 6
// }
// ]
3. Submit a Transaction for Tracking
Record a transaction that was submitted on-chain:
const chainId = 43114 ;
const response = await fetch (
`https://api.caminotreasury.com/v1/ ${ chainId } /transactions` ,
{
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'x-api-key' : 'your-api-key'
},
body: JSON . stringify ({
hash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' ,
walletId: 1 ,
type: 'deposit' ,
from: '0x742d35cc6634c0532925a3b844bc454e4438f44e' ,
token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' ,
amount: '1000000000' ,
contract: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
})
}
);
const { transaction } = await response . json ();
// { hash: "0x1234...", chainId: 43114, status: "pending" }
4. Get a Transaction with Receipt
Retrieve a transaction along with its on-chain receipt:
const chainId = 43114 ;
const hash = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' ;
const response = await fetch (
`https://api.caminotreasury.com/v1/ ${ chainId } /transactions/ ${ hash } ` ,
{ headers: { 'x-api-key' : 'your-api-key' } }
);
const { transaction , receipt } = await response . json ();
// receipt is null if the transaction has not been confirmed yet
5. Prepare a Deposit
Get the transaction steps to deposit USDC into C0:
const chainId = 43114 ;
const response = await fetch (
`https://api.caminotreasury.com/v1/ ${ chainId } /deposit/prepare` ,
{
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'x-api-key' : 'your-api-key'
},
body: JSON . stringify ({
token: 'USDC' ,
amount: '1000.00' ,
from: '0x742d35cc6634c0532925a3b844bc454e4438f44e' ,
recipient: '0x742d35cc6634c0532925a3b844bc454e4438f44e'
})
}
);
const { steps , summary } = await response . json ();
// steps: [{ type: "approve", description: "...", transaction: { to, data, value } }, ...]
// summary: { tokenIn: "USDC", tokenOut: "C0", amountIn: "1000.00", amountInRaw: "1000000000" }
6. Estimate Yield
Get yield projection for a wallet’s C0 balance:
const chainId = 43114 ;
const address = '0x742d35cc6634c0532925a3b844bc454e4438f44e' ;
const response = await fetch (
`https://api.caminotreasury.com/v1/ ${ chainId } /yield/estimate?address= ${ address } ` ,
{ headers: { 'x-api-key' : 'your-api-key' } }
);
const { earning , decimals , rate , dailyYield , monthlyYield , annualYield } =
await response . json ();
// rate.apy: 0.045 (4.5% net APY)
Example: Complete Integration
Here’s a complete TypeScript client for the Camino Treasury API:
class CaminoTreasuryClient {
private baseURL = 'https://api.caminotreasury.com/v1' ;
private apiKey : string ;
constructor ( apiKey : string ) {
this . apiKey = apiKey ;
}
private headers ( json = false ) : Record < string , string > {
const h : Record < string , string > = { 'x-api-key' : this . apiKey };
if ( json ) h [ 'Content-Type' ] = 'application/json' ;
return h ;
}
// Wallets
async listWallets () : Promise <{ data : Wallet []; count : number }> {
const res = await fetch ( ` ${ this . baseURL } /wallets` , {
headers: this . headers ()
});
if ( ! res . ok ) throw new Error ( `Failed to fetch wallets: ${ res . statusText } ` );
return res . json ();
}
async createWallet ( input : { address : string ; label : string }) : Promise < Wallet > {
const res = await fetch ( ` ${ this . baseURL } /wallets` , {
method: 'POST' ,
headers: this . headers ( true ),
body: JSON . stringify ( input )
});
if ( ! res . ok ) {
const err = await res . json ();
throw new Error ( err . error || 'Failed to create wallet' );
}
const { wallet } = await res . json ();
return wallet ;
}
async deleteWallet ( address : string ) : Promise < void > {
const res = await fetch ( ` ${ this . baseURL } /wallets/ ${ address } ` , {
method: 'DELETE' ,
headers: this . headers ()
});
if ( ! res . ok ) throw new Error ( `Failed to delete wallet: ${ res . statusText } ` );
}
// Balances
async getBalances ( chainId : number , address : string ) : Promise <{ data : TokenBalance []; count : number }> {
const res = await fetch (
` ${ this . baseURL } / ${ chainId } /balances/ ${ address } ` ,
{ headers: this . headers () }
);
if ( ! res . ok ) throw new Error ( `Failed to fetch balances: ${ res . statusText } ` );
return res . json ();
}
// Transactions
async listTransactions ( chainId : number , params ?: {
status ?: 'pending' | 'confirmed' | 'failed' ;
type ?: 'deposit' | 'withdrawal' | 'yield' | 'approval' | 'other' ;
limit ?: number ;
cursor ?: string ;
}) : Promise <{ data : Transaction []; count : number ; pagination : Pagination }> {
const url = new URL ( ` ${ this . baseURL } / ${ chainId } /transactions` );
if ( params ) {
Object . entries ( params ). forEach (([ key , value ]) => {
if ( value !== undefined ) url . searchParams . set ( key , String ( value ));
});
}
const res = await fetch ( url . toString (), { headers: this . headers () });
if ( ! res . ok ) throw new Error ( `Failed to fetch transactions: ${ res . statusText } ` );
return res . json ();
}
async createTransaction ( chainId : number , input : {
hash : string ;
walletId : number ;
type : 'deposit' | 'withdrawal' | 'yield' | 'approval' | 'other' ;
from : string ;
token : string ;
amount : string ;
contract : string ;
}) : Promise <{ hash : string ; chainId : number ; status : string }> {
const res = await fetch ( ` ${ this . baseURL } / ${ chainId } /transactions` , {
method: 'POST' ,
headers: this . headers ( true ),
body: JSON . stringify ( input )
});
if ( ! res . ok ) {
const err = await res . json ();
throw new Error ( err . error || 'Failed to create transaction' );
}
const { transaction } = await res . json ();
return transaction ;
}
async getTransaction ( chainId : number , hash : string ) : Promise <{
transaction : Transaction ;
receipt : Receipt | null ;
}> {
const res = await fetch (
` ${ this . baseURL } / ${ chainId } /transactions/ ${ hash } ` ,
{ headers: this . headers () }
);
if ( ! res . ok ) throw new Error ( `Failed to fetch transaction: ${ res . statusText } ` );
return res . json ();
}
// Deposit & Withdraw
async prepareDeposit ( chainId : number , input : PrepareSwapInput ) : Promise < PrepareSwapResult > {
const res = await fetch ( ` ${ this . baseURL } / ${ chainId } /deposit/prepare` , {
method: 'POST' ,
headers: this . headers ( true ),
body: JSON . stringify ( input )
});
if ( ! res . ok ) throw new Error ( `Failed to prepare deposit: ${ res . statusText } ` );
return res . json ();
}
async prepareWithdraw ( chainId : number , input : PrepareSwapInput ) : Promise < PrepareSwapResult > {
const res = await fetch ( ` ${ this . baseURL } / ${ chainId } /withdraw/prepare` , {
method: 'POST' ,
headers: this . headers ( true ),
body: JSON . stringify ( input )
});
if ( ! res . ok ) throw new Error ( `Failed to prepare withdrawal: ${ res . statusText } ` );
return res . json ();
}
// Yield
async estimateYield ( chainId : number , address : string ) : Promise < YieldEstimate > {
const res = await fetch (
` ${ this . baseURL } / ${ chainId } /yield/estimate?address= ${ address } ` ,
{ headers: this . headers () }
);
if ( ! res . ok ) throw new Error ( `Failed to estimate yield: ${ res . statusText } ` );
return res . json ();
}
// Webhooks
async listWebhooks () : Promise <{ data : WebhookListItem []; count : number }> {
const res = await fetch ( ` ${ this . baseURL } /webhooks` , {
headers: this . headers ()
});
if ( ! res . ok ) throw new Error ( `Failed to fetch webhooks: ${ res . statusText } ` );
return res . json ();
}
async createWebhook ( input : {
url : string ;
events : ( 'transaction.confirmed' | 'transaction.failed' )[];
wallets ?: string [];
}) : Promise < Webhook > {
const res = await fetch ( ` ${ this . baseURL } /webhooks` , {
method: 'POST' ,
headers: this . headers ( true ),
body: JSON . stringify ( input )
});
if ( ! res . ok ) {
const err = await res . json ();
throw new Error ( err . error || 'Failed to create webhook' );
}
const { webhook } = await res . json ();
return webhook ;
}
async deleteWebhook ( id : number ) : Promise < void > {
const res = await fetch ( ` ${ this . baseURL } /webhooks/ ${ id } ` , {
method: 'DELETE' ,
headers: this . headers ()
});
if ( ! res . ok ) throw new Error ( `Failed to delete webhook: ${ res . statusText } ` );
}
}
// Types
interface Wallet {
id : number ;
address : string ;
label : string ;
createdAt : string ;
}
interface TokenBalance {
token : string ;
name : string ;
symbol : string ;
raw : string ;
decimals : number ;
}
interface Transaction {
hash : string ;
chainId : number ;
status : 'pending' | 'confirmed' | 'failed' ;
type : 'deposit' | 'withdrawal' | 'yield' | 'approval' | 'other' ;
from : string ;
contract : string ;
token : string ;
amount : string ;
organizationId : string ;
walletId : number ;
createdAt : string ;
updatedAt : string ;
}
interface Receipt {
chainId : number ;
hash : string ;
from : string ;
to : string | null ;
transactionIndex : number ;
blockHash : string ;
blockNumber : number ;
type : number | null ;
contractAddress : string | null ;
status : number | null ;
root : string | null ;
createdAt : string ;
updatedAt : string ;
}
interface Pagination {
hasMore : boolean ;
nextCursor : string | null ;
}
interface PrepareSwapInput {
token : 'USDC' | 'USDT' ;
amount : string ;
from : string ;
recipient : string ;
}
interface PrepareSwapResult {
steps : {
type : 'reset-approval' | 'approve' | 'swap' ;
description : string ;
transaction : { to : string ; data : string ; value : string };
}[];
summary : {
tokenIn : string ;
tokenOut : string ;
amountIn : string ;
amountInRaw : string ;
};
}
interface YieldEstimate {
earning : string ;
decimals : number ;
rate : { apy : number };
dailyYield : string ;
monthlyYield : string ;
annualYield : string ;
}
interface Webhook {
id : number ;
url : string ;
events : string [];
wallets : string [] | null ;
secret : string ;
createdAt : string ;
}
interface WebhookListItem {
id : number ;
url : string ;
events : string [];
wallets : string [] | null ;
createdAt : string ;
}
// Usage
const client = new CaminoTreasuryClient ( 'your-api-key' );
const { data : wallets } = await client . listWallets ();
const { data : balances } = await client . getBalances ( 43114 , wallets [ 0 ]. address );
const { data : transactions , pagination } = await client . listTransactions ( 43114 , {
limit: 10 ,
status: 'confirmed'
});
// Paginate
if ( pagination . hasMore && pagination . nextCursor ) {
const page2 = await client . listTransactions ( 43114 , {
cursor: pagination . nextCursor
});
}
Error Handling
Always handle errors appropriately:
try {
const response = await fetch ( 'https://api.caminotreasury.com/v1/wallets' , {
headers: { 'x-api-key' : 'your-api-key' }
});
if ( ! response . ok ) {
const error = await response . json ();
switch ( response . status ) {
case 401 :
// Invalid or expired API key
console . error ( 'Authentication failed' );
break ;
case 429 :
// Rate limited - check Retry-After header
const retryAfter = response . headers . get ( 'Retry-After' );
console . error ( `Rate limited. Retry after ${ retryAfter } s` );
break ;
default :
console . error ( 'API error:' , error );
}
return ;
}
const { data : wallets } = await response . json ();
} catch ( error ) {
console . error ( 'Network error:' , error );
}
Best Practices
Use TypeScript for Type Safety
Define interfaces for your API responses to catch errors at compile time. See the complete integration example above for the full type definitions.
The API enforces 100 requests per 60-second window. Implement retry logic with exponential backoff using the Retry-After header for production applications.
Always validate user input before sending to the API. Ethereum addresses must match the pattern 0x[a-fA-F0-9]{40} and transaction hashes must match 0x[a-fA-F0-9]{64}.
Sign Prepared Transactions in Order
When using deposit/prepare or withdraw/prepare, the returned steps must be signed and submitted in order. Each step may depend on the previous one (e.g. approval before swap).
Next Steps