The Wallet & Payments API lets you read account balances, transfer funds into AI credits, browse transactions and invoices, manage saved payment methods, and start or inspect top-up payments through Stripe (card) and NOWPayments (crypto). It also exposes the one-time GitHub connection bonus and fee history.
All endpoints below are authenticated against the control-plane API and use the hoody-sdk pattern client.api.wallet.*.
Balances
Section titled “Balances”Read-only views over the user’s general USD balance, AI credit balance (limit/usage/remaining), or both at once.
GET /api/v1/wallet/balances
Section titled “GET /api/v1/wallet/balances”Returns the general balance together with AI limit, usage, remaining, and a freshness flag (ai_usage_status).
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Response
Section titled “Response”{ "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" }}const balances = await client.api.wallet.getAggregateBalances();GET /api/v1/wallet/balances/general
Section titled “GET /api/v1/wallet/balances/general”Returns only the general USD balance plus row bookkeeping fields.
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Response
Section titled “Response”{ "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" }}const balance = await client.api.wallet.getGeneralBalance();GET /api/v1/wallet/balances/ai
Section titled “GET /api/v1/wallet/balances/ai”Returns only the AI balance triplet (limit, usage, remaining).
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Response
Section titled “Response”{ "statusCode": 200, "message": "AI balance retrieved successfully", "data": { "ai_limit": "50.00", "ai_usage": "23.45", "ai_remaining": "26.55" }}const ai = await client.api.wallet.getAiBalance();AI Transfers & Fee History
Section titled “AI Transfers & Fee History”One-way transfers from the general balance to AI credit, plus the historical record of platform fees charged on those transfers (and on admin credits).
POST /api/v1/wallet/transfers
Section titled “POST /api/v1/wallet/transfers”Debits amount USD from the general balance and credits AI credits after the platform fee. The fee is returned separately as a basis-points-aware value; send expected_fee_bps so the server rejects the transfer (rather than silently charging a different fee) if the displayed fee has changed.
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | USD amount as a string with up to 2 decimals, e.g. "10.00". No exponent, no negatives. Pattern: `^(0 |
idempotency_key | string | No | Optional caller idempotency key (1–128 chars, must contain a non-whitespace character). Retrying with the same key and same amount returns the original receipt without moving funds; the same key with a different amount is rejected (409 TRANSFER_IDEMPOTENCY_KEY_REUSED). |
expected_fee_bps | integer | No | Optional. The platform fee in basis points the client displayed at confirmation. Range 0–9999. If it no longer matches the current server fee the transfer is rejected (409 TRANSFER_FEE_CHANGED) so an irreversible transfer is never charged a fee the user was not shown. |
Response
Section titled “Response”{ "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 }}const result = await client.api.wallet.transferToAi({ amount: "25.00", idempotency_key: "transfer-2026-06-10-001", expected_fee_bps: 500,});GET /api/v1/wallet/ai-fee-history
Section titled “GET /api/v1/wallet/ai-fee-history”Paginated list of fees charged on AI credit transfers and on admin credits.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | number | No | Page number (default 1). |
limit | query | number | No | Page size (default 20). |
sort_by | query | string | No | One of created_at, amount, transaction_id (default created_at). |
sort_order | query | string | No | asc or desc (default desc). |
Response
Section titled “Response”{ "statusCode": 200, "message": "AI fee history retrieved successfully", "data": { "fees": [ { "id": "507f1f77bcf86cd799439200", "transaction_id": "507f1f77bcf86cd799439110", "amount": "1.25", "created_at": "2025-01-21T20:00:00.000Z", "transaction": { "id": "507f1f77bcf86cd799439110", "reason": "transfer_to_ai", "amount": "25.00" } } ], "pagination": { "total": 14, "page": 1, "limit": 20, "totalPages": 1 } }}// One page:const page = await client.api.wallet.listAiFeeHistoryIterator({ page: 1, limit: 20 });// Stream across all pages:for await (const fee of client.api.wallet.listAiFeeHistoryIterator({ limit: 50 })) { // ...}Transactions
Section titled “Transactions”Inspect the user’s wallet transactions. Transactions are immutable ledger entries produced by transfers, top-ups, fees, and refunds.
GET /api/v1/wallet/transactions
Section titled “GET /api/v1/wallet/transactions”Lists wallet transactions, newest first by default.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | number | No | Maximum number of transactions to return (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). |
Response
Section titled “Response”{ "statusCode": 200, "message": "Transactions retrieved successfully"}// One page:const txs = await client.api.wallet.listTransactionsIterator({ limit: 20 });// Stream:for await (const tx of client.api.wallet.listTransactionsIterator({ sort_order: "desc" })) { // ...}GET /api/v1/wallet/transactions/{id}
Section titled “GET /api/v1/wallet/transactions/{id}”Returns a single wallet transaction by ID.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Transaction ID. |
Response
Section titled “Response”{ "statusCode": 200, "message": "Transaction retrieved successfully"}const tx = await client.api.wallet.getTransaction("507f1f77bcf86cd799439110");Invoices
Section titled “Invoices”Browse, fetch, and generate invoices for transactions that warrant a receipt (typically completed payments). PDFs are produced on demand.
GET /api/v1/wallet/invoices/
Section titled “GET /api/v1/wallet/invoices/”Lists all invoices belonging to the authenticated user, newest first.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | No | Page number for pagination — starts from 1 (default 1). |
limit | query | integer | No | Number of invoices to return per page — maximum 100 (default 20). |
sort_by | query | string | No | Field to sort by. 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. |
Response
Section titled “Response”{ "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 } }}// One page, e.g. only paid invoices with amount ≥ 10:const result = await client.api.wallet.listInvoicesIterator({ limit: 10, sort_by: "created_at", sort_order: "desc", filter: JSON.stringify({ status: "paid", amount: { gte: 10 } }),});// Stream all pages:for await (const inv of client.api.wallet.listInvoicesIterator({ limit: 50 })) { // ...}GET /api/v1/wallet/invoices/{id}
Section titled “GET /api/v1/wallet/invoices/{id}”Returns a single invoice (including billing_details, line items, and the underlying transaction).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Invoice ID. |
Response
Section titled “Response”{ "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"}const inv = await client.api.wallet.getInvoice("507f1f77bcf86cd799439120");GET /api/v1/wallet/invoices/{id}/pdf
Section titled “GET /api/v1/wallet/invoices/{id}/pdf”Downloads the invoice as a PDF file (application/pdf, binary).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Invoice ID. |
Response
Section titled “Response”The response body is the raw PDF binary (Content-Type: application/pdf). Browser/SDK clients should stream it to disk or trigger a download.
%PDF-1.4% binary PDF content...{ "statusCode": 404, "error": "Not Found", "message": "Invoice not found"}const pdf = await client.api.wallet.downloadInvoicePdf("507f1f77bcf86cd799439120");POST /api/v1/wallet/invoices/generate/{id}
Section titled “POST /api/v1/wallet/invoices/generate/{id}”Generates an invoice for a specific transaction. Idempotent: if an invoice already exists for the transaction, the existing one is returned with statusCode 200 and a “Invoice already exists” message.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Transaction ID. |
Request Body
Section titled “Request Body”This endpoint takes no body.
Response
Section titled “Response”{ "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"}const invoice = await client.api.wallet.generateInvoice("507f1f77bcf86cd799439110");Payment Methods
Section titled “Payment Methods”Saved payment instruments on file for the authenticated user. Note: real cards added through Stripe Checkout or other tokenized providers are typically saved automatically by the provider integration — this resource primarily exposes saved metadata (e.g., labels, statuses, default flags) for the wallet UI.
GET /api/v1/wallet/payment-methods/
Section titled “GET /api/v1/wallet/payment-methods/”Lists the user’s payment methods.
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Response
Section titled “Response”{ "statusCode": 200, "message": "Payment methods retrieved successfully", "data": [ { "id": "507f1f77bcf86cd799439130", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Visa ending in 4242", "status": "active", "details": {}, "is_default": true, "created_at": "2025-01-15T10:00:00.000Z", "updated_at": "2025-01-15T10:00:00.000Z" } ]}for await (const pm of client.api.wallet.listPaymentMethodsIterator()) { // ...}GET /api/v1/wallet/payment-methods/{id}
Section titled “GET /api/v1/wallet/payment-methods/{id}”Returns a single payment method by ID.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment method ID. |
Response
Section titled “Response”{ "statusCode": 200, "message": "Payment method retrieved successfully", "data": { "id": "507f1f77bcf86cd799439130", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Visa ending in 4242", "status": "active", "details": {}, "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"}const pm = await client.api.wallet.getPaymentMethod("507f1f77bcf86cd799439130");POST /api/v1/wallet/payment-methods/
Section titled “POST /api/v1/wallet/payment-methods/”Adds a new payment method for the user.
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Provider-specific type identifier (e.g. credit_card). |
name | string | Yes | Display name for the method. |
details | object | No | Free-form provider metadata (e.g. last4, brand, exp_month, exp_year). |
is_default | boolean | No | Whether this method should be the user’s default. Defaults to false. |
Response
Section titled “Response”{ "statusCode": 201, "message": "Payment method added successfully", "data": { "id": "507f1f77bcf86cd799439131", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Mastercard ending in 5555", "status": "active", "details": {}, "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": "Invalid payment method payload"}const pm = await client.api.wallet.addPaymentMethod({ type: "credit_card", name: "Mastercard ending in 5555", is_default: false,});PUT /api/v1/wallet/payment-methods/{id}
Section titled “PUT /api/v1/wallet/payment-methods/{id}”Updates one or more fields of an existing payment method.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment method ID. |
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
details | object | No | Replaces the free-form provider metadata. |
status | string | No | One of active, inactive. |
is_default | boolean | No | Whether this method should be the user’s default. |
Response
Section titled “Response”{ "statusCode": 200, "message": "Payment method updated successfully", "data": { "id": "507f1f77bcf86cd799439131", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Mastercard (primary)", "status": "active", "details": {}, "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"}const pm = await client.api.wallet.updatePaymentMethod("507f1f77bcf86cd799439131", { is_default: true, status: "active",});PUT /api/v1/wallet/payment-methods/{id}/default
Section titled “PUT /api/v1/wallet/payment-methods/{id}/default”Marks an existing payment method as the user’s default. Equivalent to PUT /{id} with is_default: true, exposed as a dedicated convenience endpoint.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment method ID. |
Response
Section titled “Response”{ "statusCode": 200, "message": "Default payment method set successfully", "data": { "id": "507f1f77bcf86cd799439131", "user_id": "507f1f77bcf86cd799439011", "type": "credit_card", "name": "Mastercard (primary)", "status": "active", "details": {}, "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"}const pm = await client.api.wallet.setDefaultPaymentMethod("507f1f77bcf86cd799439131");DELETE /api/v1/wallet/payment-methods/{id}
Section titled “DELETE /api/v1/wallet/payment-methods/{id}”Removes a payment method from the user’s saved methods.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Payment method ID. |
Response
Section titled “Response”{ "statusCode": 200, "message": "Payment method deleted successfully"}{ "statusCode": 404, "error": "Not Found", "message": "Payment method not found"}await client.api.wallet.deletePaymentMethod("507f1f77bcf86cd799439131");Payment Availability
Section titled “Payment Availability”Returns which top-up providers are usable right now (enabled and fully configured), the per-provider min/max USD per top-up, and the current AI credit transfer fee in basis points. The wallet UI typically calls this before rendering a top-up affordance. No secrets are exposed.
GET /api/v1/wallet/payment-availability
Section titled “GET /api/v1/wallet/payment-availability”Parameters
Section titled “Parameters”This endpoint takes no parameters.
Response
Section titled “Response”{ "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 }}const availability = await client.api.wallet.getPaymentAvailability();Crypto Payments (NOWPayments)
Section titled “Crypto Payments (NOWPayments)”Create a hosted crypto invoice and poll its status. The wallet is credited only after the provider confirms settlement via IPN, so status will move from pending to completed asynchronously.
POST /api/v1/wallet/payments/crypto/invoice
Section titled “POST /api/v1/wallet/payments/crypto/invoice”Creates a payment intent and a hosted crypto payment invoice. Redirect the user to invoice_url; the wallet is credited after the payment provider confirms settlement.
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | USD amount as a strict decimal string (e.g. "25" or "25.00"). Pattern: `^(0 |
idempotency_key | string | No | Optional caller idempotency key (1–128 chars, must contain a non-whitespace character). Repeats return the original intent. |
Response
Section titled “Response”{ "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" }}const { intent, invoice_url } = await client.api.wallet.createCryptoInvoice({ amount: "25.00", idempotency_key: "topup-2026-06-10-002",});// Redirect the user to invoice_url...GET /api/v1/wallet/payments/crypto/intents
Section titled “GET /api/v1/wallet/payments/crypto/intents”Lists the authenticated user’s crypto payment intents, newest first.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | No | Maximum number of intents to return (default 20). |
offset | query | integer | No | Number of intents to skip (default 0). |
Response
Section titled “Response”{ "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 }}const intents = await client.api.wallet.listCryptoPaymentIntents({ limit: 20 });GET /api/v1/wallet/payments/crypto/intents/{id}
Section titled “GET /api/v1/wallet/payments/crypto/intents/{id}”Returns one of the authenticated user’s crypto payment intents. Poll this endpoint after the user returns from the hosted invoice to learn whether the payment settled.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Crypto payment intent ID. |
Response
Section titled “Response”{ "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" }}const intent = await client.api.wallet.getCryptoPaymentIntent("665f1f77bcf86cd799439012");Stripe (Card) Payments
Section titled “Stripe (Card) Payments”Create a hosted Stripe Checkout session and poll its status. The wallet is credited only after Stripe confirms settlement via webhook, so status moves from pending to completed asynchronously.
POST /api/v1/wallet/payments/stripe/checkout
Section titled “POST /api/v1/wallet/payments/stripe/checkout”Creates a payment intent and a hosted Stripe Checkout session. Redirect the user to checkout_url; the wallet is credited after Stripe confirms settlement.
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | USD amount as a strict decimal string (e.g. "25" or "25.00"). Pattern: `^(0 |
idempotency_key | string | No | Optional caller idempotency key (1–128 chars, must contain a non-whitespace character). Repeats return the original intent. |
Response
Section titled “Response”{ "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" }}const { intent, checkout_url } = await client.api.wallet.createStripeCheckout({ amount: "25.00", idempotency_key: "topup-2026-06-10-001",});// Redirect the user to checkout_url...GET /api/v1/wallet/payments/stripe/intents
Section titled “GET /api/v1/wallet/payments/stripe/intents”Lists the authenticated user’s Stripe payment intents, newest first.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | No | Maximum number of intents to return (default 20). |
offset | query | integer | No | Number of intents to skip (default 0). |
Response
Section titled “Response”{ "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 }}const intents = await client.api.wallet.listStripePaymentIntents({ limit: 20 });GET /api/v1/wallet/payments/stripe/intents/{id}
Section titled “GET /api/v1/wallet/payments/stripe/intents/{id}”Returns one of the authenticated user’s Stripe payment intents. Poll this endpoint after the user returns from checkout to learn whether the payment settled.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Stripe payment intent ID. |
Response
Section titled “Response”{ "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" }}const intent = await client.api.wallet.getStripePaymentIntent("665f1f77bcf86cd799439011");GitHub Bonus
Section titled “GitHub Bonus”The one-time grant credited when an authenticated user has a linked GitHub identity. Read local state only — GET never contacts GitHub. When the offer is disabled, the response carries only { enabled: false } (plus the caller’s own historical claim, if any).
GET /api/v1/wallet/github-bonus
Section titled “GET /api/v1/wallet/github-bonus”Returns the bonus status, including whether it’s enabled, the offered amount, the linked GitHub identity, whether the caller has already claimed it, and the historical receipt (if any).
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Response
Section titled “Response”{ "statusCode": 200, "message": "GitHub bonus status retrieved successfully", "data": { "enabled": true, "repo": "HoodyNetwork/hoody-sdk", "amount_usd": "5.00", "github_linked": true, "github_username": "octocat", "claimed": false, "identity_claimed_elsewhere": false, "claim": null }}{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}const status = await client.api.wallet.getGithubBonus();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 result: "already_claimed" and credits nothing. The HTTP status is always 200 — the outcome is encoded in data.result.
Parameters
Section titled “Parameters”This endpoint takes no parameters.
Response
Section titled “Response”{ "statusCode": 200, "message": "GitHub bonus granted", "data": { "result": "granted", "amount_usd": "5.00", "transaction_id": "507f1f77bcf86cd799439110", "claim": { "amount_usd": "5.00", "at": "2025-01-21T20:00:00.000Z", "transaction_id": "507f1f77bcf86cd799439110" } }}{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}{ "statusCode": 429, "error": "Too Many Requests", "message": "GitHub bonus claim rate limit exceeded"}Possible data.result values:
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 is inactive.retry— transient write conflict, safe to retry.error— unexpected.
const outcome = await client.api.wallet.claimGithubBonus();if (outcome.data.result === "granted") { // The bonus has been credited to the general balance.}