Wallet & Payments
Section titled “Wallet & Payments”Manage account balances, saved payment methods, invoices, transactions, transfers between balance buckets, and top-up payment flows. Use these endpoints to render a wallet UI, check what providers can top up the user right now, generate invoices for transactions, and reconcile Stripe and crypto payment intents.
Authentication is via a Hoody token passed as Bearer <token> in the Authorization header on every request. The control-plane base URL is https://api.hoody.com.
Balances
Section titled “Balances”GET /api/v1/wallet/balances
Section titled “GET /api/v1/wallet/balances”Aggregate the user’s general balance and AI credit balance (limit, live usage, remaining). ai_usage_status is live when ai_usage and ai_remaining reflect a real provider reading; when it is unavailable, treat ai_remaining as unknown, not spendable.
This endpoint takes no parameters.
curl https://api.hoody.com/api/v1/wallet/balances \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getAggregateBalances();{ "statusCode": 200, "message": "Balances retrieved successfully", "data": { "general_balance": "125.50", "ai_limit": "50.00", "ai_usage": "23.45", "ai_remaining": "26.55", "ai_usage_status": "live" }}GET /api/v1/wallet/balances/ai
Section titled “GET /api/v1/wallet/balances/ai”AI credit balance only — limit, current usage, and remaining.
This endpoint takes no parameters.
curl https://api.hoody.com/api/v1/wallet/balances/ai \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getAiBalance();{ "statusCode": 200, "message": "AI balance retrieved successfully", "data": { "ai_limit": "50.00", "ai_usage": "23.45", "ai_remaining": "26.55" }}GET /api/v1/wallet/balances/general
Section titled “GET /api/v1/wallet/balances/general”General cash balance only.
This endpoint takes no parameters.
curl https://api.hoody.com/api/v1/wallet/balances/general \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getGeneralBalance();{ "statusCode": 200, "message": "General balance retrieved successfully", "data": { "id": "507f1f77bcf86cd799439100", "user_id": "507f1f77bcf86cd799439011", "general_balance": "125.50", "created_at": "2025-01-10T08:30:00.000Z", "updated_at": "2025-01-21T20:00:00.000Z" }}GET /api/v1/wallet/ai-fee-history
Section titled “GET /api/v1/wallet/ai-fee-history”Paginated history of platform fees charged on AI credit transfers and admin credits. Each fee is paired with the transaction it was charged against.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | number | No | Page number. Default: 1. |
limit | query | number | No | Results per page. Default: 20. |
sort_by | query | string | No | Sort field. One of created_at, amount, transaction_id. Default: created_at. |
sort_order | query | string | No | asc or desc. Default: desc. |
curl "https://api.hoody.com/api/v1/wallet/ai-fee-history?page=1&limit=20&sort_by=created_at&sort_order=desc" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
for await (const page of client.api.wallet.listAiFeeHistoryIterator({ page: 1, limit: 20 })) { console.log(page);}{ "statusCode": 200, "message": "AI fee history retrieved", "data": { "fees": [ { "id": "507f1f77bcf86cd799439201", "transaction_id": "507f1f77bcf86cd799439110", "amount": "1.25", "created_at": "2025-01-20T15:30:00.000Z", "transaction": { "id": "507f1f77bcf86cd799439110", "reason": "ai_credit_topup", "amount": "25.00" } } ], "pagination": { "total": 1, "page": 1, "limit": 20, "totalPages": 1 } }}GitHub Connection Bonus
Section titled “GitHub Connection Bonus”GET /api/v1/wallet/github-bonus
Section titled “GET /api/v1/wallet/github-bonus”Status of the one-time GitHub connection bonus for the authenticated user. Reads local state only — it never contacts GitHub. When the offer is disabled, the response carries only { enabled: false } (plus the caller’s historical claim, if any).
This endpoint takes no parameters.
curl https://api.hoody.com/api/v1/wallet/github-bonus \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getGithubBonus();{ "statusCode": 200, "message": "GitHub bonus status retrieved", "data": { "enabled": true, "repo": "HoodyNetwork/hoody-sdk", "amount_usd": "5.00", "github_linked": true, "github_username": "hoodydev", "claimed": false, "identity_claimed_elsewhere": false, "claim": null }}{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}POST /api/v1/wallet/github-bonus/claim
Section titled “POST /api/v1/wallet/github-bonus/claim”Grants the one-time GitHub connection bonus to the authenticated user when eligible. Idempotent: a second call returns already_claimed and credits nothing. The endpoint always returns 200 — the outcome is in data.result.
data.result may be one of:
granted: credited now.already_claimed: this account already received it.identity_claimed_elsewhere: another account already claimed with this GitHub identity.not_linked: no GitHub identity on this account.offer_ended: offer inactive.retry: transient write conflict, safe to retry.error: unexpected.
This endpoint takes no parameters.
curl -X POST https://api.hoody.com/api/v1/wallet/github-bonus/claim \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.claimGithubBonus();{ "statusCode": 200, "message": "GitHub bonus claimed", "data": { "result": "granted", "amount_usd": "5.00", "transaction_id": "507f1f77bcf86cd799439301", "claim": { "amount_usd": "5.00", "at": "2025-01-21T20:30:00.000Z", "transaction_id": "507f1f77bcf86cd799439301" } }}{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}{ "statusCode": 429, "error": "Too Many Requests", "message": "Bonus claim rate limit exceeded; retry shortly"}Payment Methods
Section titled “Payment Methods”Saved payment methods (cards and other instruments) for the authenticated user. Use the CRUD endpoints to list, create, update, set as default, or delete a method.
GET /api/v1/wallet/payment-methods/
Section titled “GET /api/v1/wallet/payment-methods/”List all payment methods for the current user.
This endpoint takes no parameters.
curl https://api.hoody.com/api/v1/wallet/payment-methods/ \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
for await (const method of client.api.wallet.listPaymentMethodsIterator()) { console.log(method);}{ "statusCode": 200, "message": "Payment methods retrieved successfully", "data": [ { "id": "507f1f77bcf86cd799439130", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Visa ending in 4242", "status": "active", "details": { "last4": "4242", "brand": "visa", "exp_month": 12, "exp_year": 2026 }, "is_default": true, "created_at": "2025-01-15T10:00:00.000Z", "updated_at": "2025-01-15T10:00:00.000Z" } ]}GET /api/v1/wallet/payment-methods/{id}
Section titled “GET /api/v1/wallet/payment-methods/{id}”Get a single payment method by id.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment method id. |
curl https://api.hoody.com/api/v1/wallet/payment-methods/507f1f77bcf86cd799439130 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getPaymentMethod('507f1f77bcf86cd799439130');{ "statusCode": 200, "message": "Payment method retrieved successfully", "data": { "id": "507f1f77bcf86cd799439130", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Visa ending in 4242", "status": "active", "details": { "last4": "4242", "brand": "visa", "exp_month": 12, "exp_year": 2026 }, "is_default": true, "created_at": "2025-01-15T10:00:00.000Z", "updated_at": "2025-01-15T10:00:00.000Z" }}{ "statusCode": 404, "error": "Not Found", "message": "Payment method not found"}POST /api/v1/wallet/payment-methods/
Section titled “POST /api/v1/wallet/payment-methods/”Add a new payment method.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Payment method type (for example credit_card). |
name | string | Yes | Display name (for example Mastercard ending in 5555). |
details | object | No | Free-form provider-specific details. |
is_default | boolean | No | Mark this method as the user’s default. |
curl -X POST https://api.hoody.com/api/v1/wallet/payment-methods/ \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "type": "credit_card", "name": "Mastercard ending in 5555", "details": { "last4": "5555", "brand": "mastercard", "exp_month": 8, "exp_year": 2027 }, "is_default": false }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.addPaymentMethod({ type: 'credit_card', name: 'Mastercard ending in 5555', details: { last4: '5555', brand: 'mastercard', exp_month: 8, exp_year: 2027 }, is_default: false,});{ "statusCode": 201, "message": "Payment method added successfully", "data": { "id": "507f1f77bcf86cd799439131", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Mastercard ending in 5555", "status": "active", "details": { "last4": "5555", "brand": "mastercard", "exp_month": 8, "exp_year": 2027 }, "is_default": false, "created_at": "2025-01-21T20:30:00.000Z", "updated_at": "2025-01-21T20:30:00.000Z" }}{ "statusCode": 400, "error": "Bad Request", "message": "Missing required field: name"}PUT /api/v1/wallet/payment-methods/{id}
Section titled “PUT /api/v1/wallet/payment-methods/{id}”Update an existing payment method (name, status, default flag, details).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment method id. |
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
details | object | No | Free-form provider-specific details. |
status | string | No | One of active, inactive. |
is_default | boolean | No | Promote this method to the user’s default. |
curl -X PUT https://api.hoody.com/api/v1/wallet/payment-methods/507f1f77bcf86cd799439131 \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "is_default": true, "status": "active" }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.updatePaymentMethod('507f1f77bcf86cd799439131', { is_default: true, status: 'active',});{ "statusCode": 200, "message": "Payment method updated successfully", "data": { "id": "507f1f77bcf86cd799439131", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Mastercard (primary)", "status": "active", "details": { "last4": "5555", "brand": "mastercard", "exp_month": 10, "exp_year": 2027 }, "is_default": true, "created_at": "2025-01-21T20:30:00.000Z", "updated_at": "2025-01-21T20:45:00.000Z" }}{ "statusCode": 404, "error": "Not Found", "message": "Payment method not found"}PUT /api/v1/wallet/payment-methods/{id}/default
Section titled “PUT /api/v1/wallet/payment-methods/{id}/default”Promote an existing payment method to the user’s default.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment method id. |
curl -X PUT https://api.hoody.com/api/v1/wallet/payment-methods/507f1f77bcf86cd799439131/default \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.setDefaultPaymentMethod('507f1f77bcf86cd799439131');{ "statusCode": 200, "message": "Default payment method set successfully", "data": { "id": "507f1f77bcf86cd799439131", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Mastercard (primary)", "status": "active", "details": { "last4": "5555", "brand": "mastercard", "exp_month": 10, "exp_year": 2027 }, "is_default": true, "created_at": "2025-01-21T20:30:00.000Z", "updated_at": "2025-01-21T21:00:00.000Z" }}{ "statusCode": 404, "error": "Not Found", "message": "Payment method not found"}DELETE /api/v1/wallet/payment-methods/{id}
Section titled “DELETE /api/v1/wallet/payment-methods/{id}”Delete an existing payment method.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment method id. |
curl -X DELETE https://api.hoody.com/api/v1/wallet/payment-methods/507f1f77bcf86cd799439131 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.deletePaymentMethod('507f1f77bcf86cd799439131');{ "statusCode": 200, "message": "Payment method deleted successfully"}{ "statusCode": 404, "error": "Not Found", "message": "Payment method not found"}Invoices
Section titled “Invoices”Generate, retrieve, list, and download PDF invoices for completed transactions.
GET /api/v1/wallet/invoices/
Section titled “GET /api/v1/wallet/invoices/”List all invoices for the current user. Supports pagination, sorting, and structured filtering.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | No | Page number, starting from 1. Default: 1. |
limit | query | integer | No | Results per page; max 100. Default: 20. |
sort_by | query | string | No | One of id, invoice_number, status, amount, currency, issue_date, due_date, paid_date, created_at, updated_at, user_id, transaction_id. Unrecognised values fall back to created_at. Default: created_at. |
sort_order | query | string | No | asc or desc. Default: desc. |
filter | query | string | No | JSON object string filtering by the sortable fields, e.g. {"status":"paid"} or {"amount":{"gte":10}}. Operators: eq, ne, gt, gte, lt, lte, like, in. Unknown fields or operators are rejected with 400. |
curl "https://api.hoody.com/api/v1/wallet/invoices/?page=1&limit=10&sort_by=created_at&sort_order=desc" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
for await (const invoice of client.api.wallet.listInvoicesIterator({ page: 1, limit: 10, filter: '{"status":"paid"}' })) { console.log(invoice);}{ "statusCode": 200, "message": "Invoices retrieved successfully", "data": { "invoices": [ { "id": "507f1f77bcf86cd799439120", "user_id": "507f1f77bcf86cd799439011", "transaction_id": "507f1f77bcf86cd799439110", "invoice_number": "INV-1785439290709-4e2a8002866b32d1f473ffe0", "status": "paid", "amount": 50, "currency": "USD", "issue_date": "2025-01-20T15:30:00.000Z", "due_date": "2025-02-20T15:30:00.000Z", "paid_date": "2025-01-20T15:30:00.000Z", "created_at": "2025-01-20T15:30:00.000Z", "updated_at": "2025-01-20T15:30:00.000Z", "transaction": { "id": "507f1f77bcf86cd799439110", "transaction_type": "payment", "status": "completed", "amount": 50, "currency": "USD", "created_at": "2025-01-20T15:30:00.000Z" } } ], "pagination": { "total": 23, "page": 1, "limit": 10, "totalPages": 3 } }}GET /api/v1/wallet/invoices/{id}
Section titled “GET /api/v1/wallet/invoices/{id}”Get a single invoice, including line items, billing details (when applicable), and the source transaction.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Invoice id. |
curl https://api.hoody.com/api/v1/wallet/invoices/507f1f77bcf86cd799439120 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getInvoice('507f1f77bcf86cd799439120');{ "statusCode": 200, "message": "Invoice retrieved successfully", "data": { "id": "507f1f77bcf86cd799439120", "user_id": "507f1f77bcf86cd799439011", "transaction_id": "507f1f77bcf86cd799439110", "invoice_number": "INV-1785439290709-4e2a8002866b32d1f473ffe0", "status": "paid", "amount": 50, "currency": "USD", "billing_details": { "payment_method": "Card (Stripe Checkout)", "payment_method_type": "card" }, "items": [ { "type": "general", "description": "Credits", "amount": 50 } ], "issue_date": "2025-01-20T15:30:00.000Z", "due_date": "2025-02-20T15:30:00.000Z", "paid_date": "2025-01-20T15:30:00.000Z", "created_at": "2025-01-20T15:30:00.000Z", "updated_at": "2025-01-20T15:30:00.000Z", "transaction": { "id": "507f1f77bcf86cd799439110", "transaction_type": "payment", "status": "completed", "amount": 50, "currency": "USD", "created_at": "2025-01-20T15:30:00.000Z" } }}{ "statusCode": 404, "error": "Not Found", "message": "Invoice not found"}GET /api/v1/wallet/invoices/{id}/pdf
Section titled “GET /api/v1/wallet/invoices/{id}/pdf”Download an invoice as a PDF file (Content-Type: application/pdf).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Invoice id. |
curl -L https://api.hoody.com/api/v1/wallet/invoices/507f1f77bcf86cd799439120/pdf \ -H "Authorization: Bearer <token>" \ -o invoice.pdfimport { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const pdf = await client.api.wallet.downloadInvoicePdf('507f1f77bcf86cd799439120');The response body is a binary PDF file (Content-Type: application/pdf).
%PDF-1.4... invoice contents ...{ "statusCode": 404, "error": "Not Found", "message": "Invoice not found"}POST /api/v1/wallet/invoices/generate/{id}
Section titled “POST /api/v1/wallet/invoices/generate/{id}”Generate (or regenerate) an invoice for a specific transaction. If an invoice already exists for the transaction, the existing invoice id is returned with a 200; otherwise a new one is created and returned with 201.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Transaction id. |
curl -X POST https://api.hoody.com/api/v1/wallet/invoices/generate/507f1f77bcf86cd799439110 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.generateInvoice('507f1f77bcf86cd799439110');{ "statusCode": 200, "message": "Invoice already exists", "data": { "invoice_id": "507f1f77bcf86cd799439120", "invoice_number": "INV-1785439290709-4e2a8002866b32d1f473ffe0" }}{ "statusCode": 201, "message": "Invoice generated successfully", "data": { "invoice_id": "507f1f77bcf86cd799439121", "invoice_number": "INV-1785439290812-9c6a2b1f4d0e88a37bb51c02" }}{ "statusCode": 404, "error": "Not Found", "message": "Transaction not found"}Transactions & Top-up Availability
Section titled “Transactions & Top-up Availability”GET /api/v1/wallet/transactions
Section titled “GET /api/v1/wallet/transactions”List wallet transactions. Use to reconcile debits and credits on the user’s balance.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | number | No | Results per page. Default: 20. |
sort_by | query | string | No | One of id, transaction_type, status, amount, created_at, updated_at. Default: created_at. |
sort_order | query | string | No | asc or desc. Default: desc. |
curl "https://api.hoody.com/api/v1/wallet/transactions?limit=20&sort_by=created_at&sort_order=desc" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
for await (const tx of client.api.wallet.listTransactionsIterator({ limit: 20 })) { console.log(tx);}{ "statusCode": 200, "message": "Transactions retrieved successfully", "data": []}GET /api/v1/wallet/transactions/{id}
Section titled “GET /api/v1/wallet/transactions/{id}”Get a single transaction by id.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Transaction id. |
curl https://api.hoody.com/api/v1/wallet/transactions/507f1f77bcf86cd799439110 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getTransaction('507f1f77bcf86cd799439110');{ "statusCode": 200, "message": "Transaction retrieved successfully"}GET /api/v1/wallet/payment-availability
Section titled “GET /api/v1/wallet/payment-availability”Inspect which top-up providers are usable right now (enabled and configured), the per-provider USD bounds, and the AI-credit transfer fee in basis points. Use this in the wallet UI to render the correct top-up affordances. No secrets are returned.
This endpoint takes no parameters.
curl https://api.hoody.com/api/v1/wallet/payment-availability \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getPaymentAvailability();{ "statusCode": 200, "message": "Payment availability retrieved successfully", "data": { "stripe": { "enabled": true, "min_usd": 5, "max_usd": 10000 }, "nowpayments": { "enabled": false, "min_usd": 5, "max_usd": 10000 }, "ai_credit_fee_bps": 0 }}Transfers
Section titled “Transfers”POST /api/v1/wallet/transfers
Section titled “POST /api/v1/wallet/transfers”One-way transfer from general balance to AI credit balance. The amount is debited in full from the general balance, and the net amount (after the platform fee) is credited to the AI credit limit. Pass expected_fee_bps so the server can reject the transfer if the fee you displayed at confirmation no longer matches — this guarantees no irreversible transfer is charged a fee the user was not shown.
If you pass an idempotency_key, retrying with the same key and the same amount returns the original receipt without moving funds again (the response sets replayed: true); reusing the same key with a different amount returns 409 TRANSFER_IDEMPOTENCY_KEY_REUSED.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | USD amount as a strict decimal string with up to 2 decimals (for example "10.00"). No exponent, no negatives. |
idempotency_key | string | No | Caller idempotency key, 1–128 chars, must contain a non-whitespace character. Retries with the same key and same amount replay the receipt; same key with a different amount is rejected. |
expected_fee_bps | integer | No | The platform fee in basis points the client displayed at confirmation (0–9999). If it does not match the current server fee, the transfer is rejected with 409 TRANSFER_FEE_CHANGED so the user re-confirms. |
curl -X POST https://api.hoody.com/api/v1/wallet/transfers \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "amount": "25.00", "idempotency_key": "transfer-2025-01-21-001", "expected_fee_bps": 500 }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.transferToAi({ amount: '25.00', idempotency_key: 'transfer-2025-01-21-001', expected_fee_bps: 500,});{ "statusCode": 200, "message": "Transfer completed and AI credit limit synced", "data": { "gross_transferred": "25.00", "net_ai_credit": "23.75", "fee": "1.25", "general_balance": "100.50", "ai_balance": "75.00", "key_created": false, "limit_sync_pending": false, "replayed": false }}Payments — Crypto (NOWPayments)
Section titled “Payments — Crypto (NOWPayments)”Top up the wallet using a hosted crypto invoice. The endpoint creates a payment intent and a hosted invoice URL; the user pays there and the wallet is credited only after NOWPayments confirms settlement via IPN.
POST /api/v1/wallet/payments/crypto/invoice
Section titled “POST /api/v1/wallet/payments/crypto/invoice”Create a crypto payment intent and return the hosted invoice URL. Send the user to the invoice_url to complete payment. Pass idempotency_key so retries with the same key return the original intent.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | USD amount as a strict decimal string (for example "25" or "25.00"). |
idempotency_key | string | No | Caller idempotency key, 1–128 chars, must contain a non-whitespace character. Repeats return the original intent. |
curl -X POST https://api.hoody.com/api/v1/wallet/payments/crypto/invoice \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "amount": "25.00", "idempotency_key": "topup-2026-06-10-002" }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.createCryptoInvoice({ amount: '25.00', idempotency_key: 'topup-2026-06-10-002',});{ "statusCode": 201, "message": "Crypto payment invoice created", "data": { "intent": { "id": "665f1f77bcf86cd799439012", "provider": "nowpayments", "status": "pending", "amount": 25, "currency": "USD", "redirect_url": "https://nowpayments.io/payment/?iid=4522625843", "credited_at": null, "expires_at": null, "created_at": "2026-06-10T12:00:00.000Z", "updated_at": "2026-06-10T12:00:00.000Z" }, "invoice_url": "https://nowpayments.io/payment/?iid=4522625843" }}GET /api/v1/wallet/payments/crypto/intents
Section titled “GET /api/v1/wallet/payments/crypto/intents”List the authenticated user’s crypto payment intents, newest first.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | No | Max intents to return. Default: 20. |
offset | query | integer | No | Offset for pagination. Default: 0. |
curl "https://api.hoody.com/api/v1/wallet/payments/crypto/intents?limit=20&offset=0" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.listCryptoPaymentIntents({ limit: 20, offset: 0 });{ "statusCode": 200, "message": "Payment intents retrieved successfully", "data": { "intents": [ { "id": "665f1f77bcf86cd799439012", "provider": "nowpayments", "status": "pending", "amount": 25, "currency": "USD", "redirect_url": "https://nowpayments.io/payment/?iid=4522625843", "credited_at": null, "expires_at": null, "created_at": "2026-06-10T12:00:00.000Z", "updated_at": "2026-06-10T12:00:00.000Z" } ], "total": 1 }}GET /api/v1/wallet/payments/crypto/intents/{id}
Section titled “GET /api/v1/wallet/payments/crypto/intents/{id}”Get one of the authenticated user’s crypto payment intents by id. Poll this after redirecting the user to the hosted invoice URL until status is completed, failed, or expired.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment intent id. |
curl https://api.hoody.com/api/v1/wallet/payments/crypto/intents/665f1f77bcf86cd799439012 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getCryptoPaymentIntent('665f1f77bcf86cd799439012');{ "statusCode": 200, "message": "Payment intent retrieved successfully", "data": { "id": "665f1f77bcf86cd799439012", "provider": "nowpayments", "status": "pending", "amount": 25, "currency": "USD", "redirect_url": "https://nowpayments.io/payment/?iid=4522625843", "credited_at": null, "expires_at": null, "created_at": "2026-06-10T12:00:00.000Z", "updated_at": "2026-06-10T12:00:00.000Z" }}Payments — Stripe Checkout (Cards)
Section titled “Payments — Stripe Checkout (Cards)”Top up the wallet using a hosted Stripe Checkout session. The endpoint creates a payment intent and a hosted checkout URL; the user pays there and the wallet is credited only after Stripe confirms settlement via webhook.
POST /api/v1/wallet/payments/stripe/checkout
Section titled “POST /api/v1/wallet/payments/stripe/checkout”Create a card payment intent and a Stripe Checkout session. Send the user to the checkout_url to complete payment. Pass idempotency_key so retries with the same key return the original intent.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | USD amount as a strict decimal string (for example "25" or "25.00"). |
idempotency_key | string | No | Caller idempotency key, 1–128 chars, must contain a non-whitespace character. Repeats return the original intent. |
curl -X POST https://api.hoody.com/api/v1/wallet/payments/stripe/checkout \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "amount": "25.00", "idempotency_key": "topup-2026-06-10-001" }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.createStripeCheckout({ amount: '25.00', idempotency_key: 'topup-2026-06-10-001',});{ "statusCode": 201, "message": "Checkout session created", "data": { "intent": { "id": "665f1f77bcf86cd799439011", "provider": "stripe", "status": "pending", "amount": 25, "currency": "USD", "redirect_url": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3", "credited_at": null, "expires_at": "2026-06-11T12:00:00.000Z", "created_at": "2026-06-10T12:00:00.000Z", "updated_at": "2026-06-10T12:00:00.000Z" }, "checkout_url": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3" }}GET /api/v1/wallet/payments/stripe/intents
Section titled “GET /api/v1/wallet/payments/stripe/intents”List the authenticated user’s Stripe payment intents, newest first.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | No | Max intents to return. Default: 20. |
offset | query | integer | No | Offset for pagination. Default: 0. |
curl "https://api.hoody.com/api/v1/wallet/payments/stripe/intents?limit=20&offset=0" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.listStripePaymentIntents({ limit: 20, offset: 0 });{ "statusCode": 200, "message": "Payment intents retrieved successfully", "data": { "intents": [ { "id": "665f1f77bcf86cd799439011", "provider": "stripe", "status": "pending", "amount": 25, "currency": "USD", "redirect_url": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3", "credited_at": null, "expires_at": "2026-06-11T12:00:00.000Z", "created_at": "2026-06-10T12:00:00.000Z", "updated_at": "2026-06-10T12:00:00.000Z" } ], "total": 1 }}GET /api/v1/wallet/payments/stripe/intents/{id}
Section titled “GET /api/v1/wallet/payments/stripe/intents/{id}”Get one of the authenticated user’s Stripe payment intents by id. Poll this after redirecting the user to the Stripe Checkout URL until status is completed, failed, or expired.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment intent id. |
curl https://api.hoody.com/api/v1/wallet/payments/stripe/intents/665f1f77bcf86cd799439011 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.wallet.getStripePaymentIntent('665f1f77bcf86cd799439011');{ "statusCode": 200, "message": "Payment intent retrieved successfully", "data": { "id": "665f1f77bcf86cd799439011", "provider": "stripe", "status": "pending", "amount": 25, "currency": "USD", "redirect_url": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3", "credited_at": null, "expires_at": "2026-06-11T12:00:00.000Z", "created_at": "2026-06-10T12:00:00.000Z", "updated_at": "2026-06-10T12:00:00.000Z" }}