@coobird-ai/sdk
v2.0.1
Published
Official Node.js SDK for Coobird — agent usage tracking, metered billing, and wallet management for AI agents.
Maintainers
Readme
@coobird-ai/sdk
Official Node.js SDK for Coobird — agent usage tracking, metered billing, and wallet management.
Track what your AI agents do, attribute costs to customers, and power your billing pipeline with a few lines of code.
Installation
npm install @coobird-ai/sdk
# or
pnpm add @coobird-ai/sdk
# or
yarn add @coobird-ai/sdkRequirements: Node.js 18+
Quick Start
import { Coomon } from '@coobird-ai/sdk'
const coomon = new Coomon('sk_live_abc123', {
host: 'https://api.coobird.ai',
})
// Track an agent task
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_xxx',
signalCode: 'api_call',
quantity: 1,
attributes: {
model: 'claude-3-5-sonnet',
input_tokens: 1200,
output_tokens: 340,
},
})
// Flush before process exit
await coomon.shutdown()Connecting to Your Deployment
The SDK needs two things: an API key and a host URL.
API Key
Create an API key from the Coobird dashboard (Settings > API Keys). The key is scoped to your tenant.
Host URL
By default, the SDK points to the dev environment at https://api.dev.coobird.ai. For production, use https://api.coobird.ai:
// Local development
const coomon = new Coomon('sk_live_abc123', {
host: 'http://localhost:4444',
})
// Dev (default)
const coomon = new Coomon('sk_live_abc123')
// → uses https://api.dev.coobird.ai
// Production
const coomon = new Coomon('sk_live_abc123', {
host: 'https://api.coobird.ai',
})The SDK appends /api/v1/ to the host internally, so just pass the base domain — no trailing slash, no path.
Event Tracking
track() — Queued (Default)
Events are queued in memory and sent in batches. This is the fastest path — track() returns immediately and never throws.
coomon.track({
customerId: 'cust_123',
agentId: 'agent_xxx',
actionType: 'task', // 'task' | 'workflow' | 'outcome'
signalCode: 'api_call', // maps to your billing signal
quantity: 1,
attributes: {
model: 'claude-3-5-sonnet',
input_tokens: 1200,
output_tokens: 340,
cost_usd: 0.0042,
},
})The queue auto-flushes when it reaches flushAt events (default: 20) or every flushInterval ms (default: 10s).
trackImmediate() — Awaited (Serverless)
In serverless environments (AWS Lambda, Vercel Edge, Cloudflare Workers), the process can die before the queue flushes. Use trackImmediate() to send the event and await the HTTP response:
// AWS Lambda handler
export async function handler(event) {
await coomon.trackImmediate({
customerId: 'cust_123',
agentId: 'agent_xxx',
actionType: 'task',
signalCode: 'api_call',
})
return { statusCode: 200 }
}Typed Wrappers
Convenience methods that set actionType for you:
// Queued (fire-and-forget)
coomon.trackTask({ customerId: 'cust_123', agentId: 'agent_xxx', signalCode: 'api_call' })
coomon.trackWorkflow({ customerId: 'cust_123', agentId: 'agent_xxx', signalCode: 'pipeline_run' })
coomon.trackOutcome({ customerId: 'cust_123', agentId: 'agent_xxx', signalCode: 'report_generated' })
// Immediate (serverless-safe)
await coomon.trackTaskImmediate({ customerId: 'cust_123', agentId: 'agent_xxx', signalCode: 'api_call' })
await coomon.trackWorkflowImmediate({ customerId: 'cust_123', agentId: 'agent_xxx', signalCode: 'pipeline_run' })
await coomon.trackOutcomeImmediate({ customerId: 'cust_123', agentId: 'agent_xxx', signalCode: 'report_generated' })Track Options
| Field | Type | Required | Description |
|---|---|---|---|
| customerId | string | Yes | The customer this event belongs to |
| agentId | string | Yes | The agent performing this action |
| actionType | 'task' \| 'workflow' \| 'outcome' | Yes | Event category (set automatically by typed wrappers) |
| signalCode | string | No | Maps to a billing signal in your plan |
| quantity | number | No | Defaults to 1 |
| attributes | Record<string, unknown> | No | Arbitrary key-value data (model, tokens, cost, etc.) |
| metadata | Record<string, unknown> | No | Additional metadata |
| eventId | string | No | Auto-generated UUID for idempotency. Pass your own to deduplicate. |
| timestamp | Date | No | Defaults to new Date() |
Global Attributes
Set attributes that are merged into every event. Event-level attributes override globals.
// Set once at startup
coomon.register({
model: 'claude-3-5-sonnet',
region: 'us-east-1',
service: 'my-agent',
})
// All subsequent events include these attributes
coomon.track({ customerId: 'cust_123', agentId: 'agent_xxx', actionType: 'task' })
// -> attributes: { model: 'claude-3-5-sonnet', region: 'us-east-1', service: 'my-agent' }
// Override per-event
coomon.track({
customerId: 'cust_123',
agentId: 'agent_xxx',
actionType: 'task',
attributes: { model: 'gpt-4o' }, // overrides global 'model'
})
// Remove a global attribute
coomon.unregister('region')Cost Tracking
Coobird supports two ways to track costs — choose the one that fits your use case.
Direct Cost (Fast Path)
If you already know the cost (e.g., from your LLM provider's response), pass cost_usd directly in attributes along with a signalCode. The enricher reads the cost as-is — no server-side lookups needed.
// OpenAI call — you know the cost from the API response
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_xxx',
signalCode: 'openai_llm_cost',
attributes: {
cost_usd: 0.0069,
provider: 'openai',
model: 'gpt-4o',
input_tokens: 1900,
output_tokens: 414,
},
})
// Anthropic call
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_xxx',
signalCode: 'anthropic_llm_cost',
attributes: {
cost_usd: 0.0042,
provider: 'anthropic',
model: 'claude-3-5-sonnet',
input_tokens: 1200,
output_tokens: 340,
},
})
// External API call with known cost
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_xxx',
signalCode: 'serp_api_cost',
attributes: {
cost_usd: 0.005,
provider: 'serpapi',
query: 'competitor analysis',
},
})When to use: You have the exact cost from the provider (LLM API responses, third-party billing APIs).
Derived Cost (Agent Lookup)
If you don't know the cost at event time, omit signalCode and let Coobird calculate it. The enricher looks up the agent's configured cost signals from the dashboard and applies fixed or variable pricing automatically.
// Simple task — cost is derived from agent config in the dashboard
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_xxx',
quantity: 1,
attributes: {
action: 'email_sent',
},
})
// Token-based pricing — enricher reads 'tokens' from attributes
// and multiplies by the configured cost_per_unit
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_xxx',
quantity: 1,
attributes: {
model: 'gpt-4o',
tokens: 2500,
},
})
// Multi-quantity — fixed cost is multiplied by quantity
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_xxx',
quantity: 5,
attributes: {
action: 'sms_sent',
recipient_count: 5,
},
})When to use: Costs are configured in the Coobird dashboard (fixed per-action pricing, variable per-unit pricing). You don't need to calculate costs in your code.
Cost Categories
Costs are categorized for reporting and margin analysis:
| Category | Use for |
|---|---|
| compute | Infrastructure, GPU, serverless invocations |
| llm | LLM API costs (OpenAI, Anthropic, etc.) |
| api | Third-party API calls (search, email, SMS) |
| storage | Data storage, file uploads |
| bandwidth | Network egress, CDN |
| other | Miscellaneous costs |
Categories are configured per signal in the Coobird dashboard — the SDK doesn't need to specify them.
How Cost Derivation Works
SDK event → API → Kafka → Enricher Worker
│
├─ signalCode provided?
│ ├─ YES → Fast path: read cost_usd from attributes
│ └─ NO → Agent lookup: find cost signals from dashboard config
│ ├─ Fixed cost: cost_per_unit × quantity
│ └─ Variable cost: attributes[value_field] × cost_per_unit
│
└─ Store enriched event → ClickHouse (analytics) + Postgres (API)Billing Quantity
The billing quantity depends on the signal's aggregation type (configured in the dashboard):
| Aggregation | Billing Quantity | Example |
|---|---|---|
| count | event.quantity (default: 1) | 3 emails sent → quantity = 3 |
| sum | attributes[quantity_field] | 1500 tokens used → quantity = 1500 |
| max | attributes[quantity_field] | Peak concurrent users |
| min | attributes[quantity_field] | Minimum threshold |
| average | attributes[quantity_field] | Average response time |
| unique_count | attributes[quantity_field] | Unique users served |
Real-World Examples
AI Agent with Multiple Cost Sources
// 1. Track the LLM cost (direct — you know the cost)
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_research',
signalCode: 'openai_llm_cost',
attributes: {
cost_usd: 0.032,
model: 'gpt-4o',
input_tokens: 5000,
output_tokens: 1200,
},
})
// 2. Track a search API call (direct — fixed price per call)
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_research',
signalCode: 'search_api_cost',
attributes: {
cost_usd: 0.01,
provider: 'tavily',
},
})
// 3. Track the overall workflow completion (derived — priced in dashboard)
coomon.trackWorkflow({
customerId: 'cust_123',
agentId: 'agent_research',
quantity: 1,
attributes: {
workflow: 'research_report',
steps_completed: 5,
duration_ms: 45000,
},
})
// 4. Track the business outcome (derived — outcome-based pricing)
coomon.trackOutcome({
customerId: 'cust_123',
agentId: 'agent_research',
attributes: {
outcome_type: 'report_generated',
quality_score: 0.92,
pages: 12,
},
})SaaS with Per-Customer Metering
// Track API calls per customer (count-based billing)
coomon.trackTask({
customerId: req.headers['x-customer-id'],
agentId: 'agent_analyzer',
signalCode: 'api_request',
quantity: 1,
attributes: {
endpoint: '/v1/analyze',
response_time_ms: 230,
},
})
// Track storage usage (sum-based billing)
coomon.trackTask({
customerId: 'cust_123',
agentId: 'agent_storage',
signalCode: 'storage_usage',
attributes: {
bytes_stored: 1_048_576, // 1 MB
file_type: 'pdf',
},
})Idempotency
Pass an eventId to prevent duplicate billing:
const eventId = crypto.randomUUID()
// Safe to retry — same eventId won't be billed twice
coomon.track({
customerId: 'cust_123',
agentId: 'agent_xxx',
actionType: 'task',
signalCode: 'api_call',
eventId,
})Customer Management
Create, retrieve, update, list, and delete customers.
// Create
const customer = await coomon.createCustomer({
name: 'Acme Corp',
type: 'company',
email: '[email protected]',
externalId: 'acme-001',
metadata: { tier: 'enterprise' },
})
// Get by ID
const fetched = await coomon.getCustomer(customer.id)
// List with filters
const { data, pagination } = await coomon.listCustomers({
status: 'active',
type: 'company',
search: 'acme',
page: 1,
limit: 25,
})
// Update
const updated = await coomon.updateCustomer(customer.id, {
name: 'Acme Corporation',
email: '[email protected]',
metadata: { tier: 'enterprise', renewed: true },
})
// Delete
await coomon.deleteCustomer(customer.id)CreateCustomerOptions
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Customer display name |
| type | 'agent' \| 'individual' \| 'company' | Yes | Customer type |
| status | 'active' \| 'inactive' \| 'suspended' | No | Defaults to 'active' |
| email | string | No | Billing email |
| phone | string | No | Phone number |
| externalId | string | No | Your system's ID for idempotent lookups |
| currency | string | No | Preferred currency (e.g. 'USD') |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
UpdateCustomerOptions
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | No | Customer display name |
| type | 'agent' \| 'individual' \| 'company' | No | Customer type |
| status | 'active' \| 'inactive' \| 'suspended' | No | Customer status |
| email | string \| null | No | Billing email (set null to clear) |
| phone | string \| null | No | Phone number (set null to clear) |
| externalId | string \| null | No | External ID (set null to clear) |
| currency | string | No | Preferred currency |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
ListCustomersQuery
| Field | Type | Description |
|---|---|---|
| status | string | Filter by status |
| type | string | Filter by customer type |
| search | string | Search by name |
| page | number | Page number |
| limit | number | Results per page |
| sort | string | Sort field |
| order | 'asc' \| 'desc' | Sort direction |
Contract Management
Contracts link a customer to a pricing plan. All pricing, agent actions, and charges are copied from the plan server-side.
// Create
const contract = await coomon.createContract({
planId: 'plan_abc',
customerId: 'cust_123',
name: 'Acme Enterprise Contract',
startDate: '2026-04-01',
billingInterval: 'monthly',
})
// Get by ID
const fetched = await coomon.getContract(contract.id)
// List with filters
const { data, pagination } = await coomon.listContracts({
status: 'active',
customerId: 'cust_123',
planId: 'plan_abc',
})
// Update
const updated = await coomon.updateContract(contract.id, {
name: 'Acme Enterprise Contract (Renewed)',
endDate: '2027-04-01',
paymentTerms: 30,
})
// Activate
const activated = await coomon.activateContract(contract.id, {
activationDate: '2026-04-01',
skipValidation: false,
})
// Suspend
const suspended = await coomon.suspendContract(contract.id, {
suspendReason: 'Payment overdue',
resumeDate: '2026-05-01',
})
// Cancel
const cancelled = await coomon.cancelContract(contract.id, {
cancellationType: 'end_of_period',
refundType: 'prorated',
reason: 'Customer churned',
})CreateContractOptions
| Field | Type | Required | Description |
|---|---|---|---|
| planId | string | Yes | The plan to replicate pricing from |
| customerId | string | Yes | The customer to attach the contract to |
| name | string | Yes | Contract name |
| startDate | string | Yes | Start date (YYYY-MM-DD) |
| description | string | No | Contract description |
| endDate | string | No | End date (YYYY-MM-DD) |
| billingInterval | 'daily' \| 'weekly' \| 'monthly' \| 'quarterly' \| 'annual' | No | Overrides plan default |
| currency | string | No | Currency code |
| collectionMethod | 'charge_automatically' \| 'send_invoice' | No | How to collect payment |
| paymentTerms | number | No | Net days for invoice payment |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
UpdateContractOptions
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | No | Contract name |
| description | string \| null | No | Description (set null to clear) |
| endDate | string \| null | No | End date (set null to clear) |
| billingInterval | 'daily' \| 'weekly' \| 'monthly' \| 'quarterly' \| 'annual' | No | Billing interval |
| currency | string | No | Currency code |
| collectionMethod | 'charge_automatically' \| 'send_invoice' | No | Collection method |
| paymentTerms | number | No | Net days for payment |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
ListContractsQuery
| Field | Type | Description |
|---|---|---|
| status | string | Filter by status |
| customerId | string | Filter by customer |
| planId | string | Filter by plan |
| page | number | Page number |
| limit | number | Results per page |
| sort | string | Sort field |
| order | 'asc' \| 'desc' | Sort direction |
ActivateContractOptions
| Field | Type | Required | Description |
|---|---|---|---|
| activationDate | string | No | Activation date (YYYY-MM-DD) |
| skipValidation | boolean | No | Skip validation checks |
SuspendContractOptions
| Field | Type | Required | Description |
|---|---|---|---|
| suspendReason | string | No | Reason for suspension |
| resumeDate | string | No | Planned resume date (YYYY-MM-DD) |
CancelContractOptions
| Field | Type | Required | Description |
|---|---|---|---|
| cancellationType | 'immediate' \| 'end_of_period' | Yes | When cancellation takes effect |
| refundType | 'none' \| 'prorated' \| 'full' | No | Refund policy |
| reason | string | No | Cancellation reason |
| cancellationDate | string | No | Specific cancellation date |
Agent Management
Agents represent the AI agents you're billing for. Each agent can have multiple actions with associated billing signals.
// Create
const agent = await coomon.createAgent({
name: 'Research Agent',
description: 'Performs web research and generates reports',
status: 'active',
tags: ['research', 'reports'],
metadata: { version: '2.0' },
})
// Get by ID
const fetched = await coomon.getAgent(agent.id)
// List with filters
const { data, pagination } = await coomon.listAgents({
status: 'active',
search: 'research',
page: 1,
limit: 25,
})
// Update
const updated = await coomon.updateAgent(agent.id, {
description: 'Updated description',
tags: ['research', 'reports', 'analysis'],
})
// Delete
await coomon.deleteAgent(agent.id)CreateAgentOptions
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Agent display name |
| description | string | No | Agent description |
| externalId | string | No | Your system's ID |
| status | 'draft' \| 'active' \| 'inactive' \| 'archived' | No | Defaults to 'draft' |
| tags | string[] | No | Tags for filtering |
| config | Record<string, unknown> | No | Agent configuration |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
UpdateAgentOptions
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | No | Agent display name |
| description | string \| null | No | Description (set null to clear) |
| externalId | string \| null | No | External ID (set null to clear) |
| status | 'draft' \| 'active' \| 'inactive' \| 'archived' | No | Agent status |
| tags | string[] | No | Tags for filtering |
| config | Record<string, unknown> | No | Agent configuration |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
ListAgentsQuery
| Field | Type | Description |
|---|---|---|
| status | string | Filter by status |
| search | string | Search by name |
| has_external_id | boolean | Filter agents with/without external ID |
| page | number | Page number |
| limit | number | Results per page |
| sort | string | Sort field |
| order | 'asc' \| 'desc' | Sort direction |
Agent Actions
Actions define the billable operations an agent can perform. Each action has a billable signal that maps to your pricing.
// Create an action for an agent
const action = await coomon.createAgentAction(agent.id, {
actionName: 'Web Search',
actionType: 'task',
description: 'Performs a web search query',
billableSignal: {
signalName: 'Web Search Query',
signalCode: 'web_search',
aggregationType: 'count',
unitLabel: 'queries',
},
costSignalIds: ['signal_cost_1'],
value: {
fteEquivalent: 0.1,
revenuePerUnit: 0.05,
defaultPriceCents: 5,
},
})
// List actions for an agent
const { data } = await coomon.listAgentActions(agent.id, {
action_type: 'task',
search: 'search',
})
// Update an action
const updated = await coomon.updateAgentAction(agent.id, action.id, {
description: 'Updated description',
billableSignal: {
unitLabel: 'searches',
},
addCostSignalIds: ['signal_cost_2'],
removeCostSignalIds: ['signal_cost_1'],
})
// Delete an action
await coomon.deleteAgentAction(agent.id, action.id)CreateAgentActionOptions
| Field | Type | Required | Description |
|---|---|---|---|
| actionName | string | Yes | Action display name |
| actionType | 'task' \| 'workflow' \| 'outcome' | Yes | Action category |
| description | string | No | Action description |
| billableSignal | object | Yes | The billing signal for this action (see below) |
| costSignalIds | string[] | No | IDs of cost signals to associate |
| value | object | No | Value metrics (see below) |
billableSignal fields:
| Field | Type | Required | Description |
|---|---|---|---|
| signalName | string | Yes | Signal display name |
| signalCode | string | Yes | Unique code used in track() calls |
| aggregationType | 'count' \| 'sum' \| 'max' \| 'min' \| 'average' \| 'unique_count' | Yes | How to aggregate usage |
| unitLabel | string | No | Display label for units (e.g. "queries") |
| valueField | string | No | Attribute key for value-based aggregation |
| description | string | No | Signal description |
value fields:
| Field | Type | Required | Description |
|---|---|---|---|
| fteEquivalent | number | No | Full-time-equivalent labor this action replaces |
| revenuePerUnit | number | No | Expected revenue per unit |
| defaultPriceCents | number | No | Default price in cents |
UpdateAgentActionOptions
| Field | Type | Required | Description |
|---|---|---|---|
| actionName | string | No | Action display name |
| actionType | 'task' \| 'workflow' \| 'outcome' | No | Action category |
| description | string \| null | No | Description (set null to clear) |
| billableSignal | object | No | Partial update to billing signal fields |
| costSignalIds | string[] | No | Replace all cost signal IDs |
| addCostSignalIds | string[] | No | Add cost signal IDs |
| removeCostSignalIds | string[] | No | Remove cost signal IDs |
| value | object | No | Value metrics (fields can be set to null) |
ListAgentActionsQuery
| Field | Type | Description |
|---|---|---|
| action_type | string | Filter by action type |
| search | string | Search by name |
| page | number | Page number |
| limit | number | Results per page |
| sort | string | Sort field |
| order | 'asc' \| 'desc' | Sort direction |
Create Agent with Actions
Create an agent and all its actions in a single request.
const agent = await coomon.createAgentWithActions({
agent: {
name: 'Customer Support Agent',
description: 'Handles customer inquiries',
status: 'active',
},
actions: [
{
actionName: 'Answer Question',
actionType: 'task',
billableSignal: {
signalName: 'Support Query',
signalCode: 'support_query',
aggregationType: 'count',
unitLabel: 'queries',
},
},
{
actionName: 'Generate Report',
actionType: 'outcome',
billableSignal: {
signalName: 'Report Generated',
signalCode: 'report_gen',
aggregationType: 'count',
unitLabel: 'reports',
},
},
],
})CreateAgentWithActionsOptions
| Field | Type | Required | Description |
|---|---|---|---|
| agent | CreateAgentOptions | Yes | Agent configuration (see CreateAgentOptions) |
| actions | CreateAgentActionOptions[] | Yes | Array of actions (see CreateAgentActionOptions) |
Plan Management
Plans define pricing structures that are applied to customers via contracts.
// Create
const plan = await coomon.createPlan({
name: 'Pro Plan',
code: 'pro-2026',
description: 'Professional tier with usage-based pricing',
planType: 'usage_based',
billingPeriod: 'monthly',
currency: 'USD',
category: 'plan',
targetAudience: 'both',
trialAvailable: true,
trialDays: 14,
})
// Get by ID
const fetched = await coomon.getPlan(plan.id)
// List with filters
const { data, pagination } = await coomon.listPlans({
status: 'active',
search: 'pro',
type: 'usage_based',
})
// Update
const updated = await coomon.updatePlan(plan.id, {
description: 'Updated pro plan description',
trialDays: 30,
})
// Delete
await coomon.deletePlan(plan.id)CreatePlanOptions
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Plan display name |
| code | string | Yes | Unique plan code |
| description | string | No | Plan description |
| targetAudience | 'both' \| 'human' \| 'agent' | No | Target audience |
| currency | string | No | Currency code (e.g. 'USD') |
| category | 'plan' \| 'addon' | No | Plan or add-on |
| planType | 'standard' \| 'enterprise' \| 'trial' \| 'freemium' \| 'usage_based' \| 'hybrid' | No | Plan type |
| billingPeriod | 'daily' \| 'weekly' \| 'monthly' \| 'quarterly' \| 'semi_annual' \| 'annual' | No | Billing period |
| trialAvailable | boolean | No | Whether trial is available |
| trialDays | number | No | Number of trial days |
| status | string | No | Plan status |
| parentPlanId | string | No | Parent plan ID (for add-ons) |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
UpdatePlanOptions
All fields from CreatePlanOptions are available but optional. Set description to null to clear it.
ListPlansQuery
| Field | Type | Description |
|---|---|---|
| status | string | Filter by status |
| search | string | Search by name |
| type | string | Filter by plan type |
| page | number | Page number |
| limit | number | Results per page |
| sort | string | Sort field |
| order | 'asc' \| 'desc' | Sort direction |
Plan Charges
Fixed or recurring charges attached to a plan (e.g. platform fees, seat licenses).
// Create
const charge = await coomon.createPlanCharge(plan.id, {
chargeName: 'Platform Fee',
chargeCode: 'platform-fee',
chargeType: 'recurring',
amount: 9900, // cents
billingFrequency: 'monthly',
description: 'Monthly platform access fee',
})
// List all charges for a plan
const charges = await coomon.listPlanCharges(plan.id)
// Update
const updated = await coomon.updatePlanCharge(plan.id, charge.id, {
amount: 14900,
description: 'Updated platform fee',
})
// Delete
await coomon.deletePlanCharge(plan.id, charge.id)CreatePlanChargeOptions
| Field | Type | Required | Description |
|---|---|---|---|
| chargeName | string | Yes | Charge display name |
| chargeCode | string | Yes | Unique charge code |
| chargeType | 'recurring' \| 'one_time' \| 'usage_based' \| 'seat_based' | Yes | Charge type |
| amount | number | Yes | Amount in cents |
| description | string \| null | No | Charge description |
| billingFrequency | string \| null | No | Billing frequency (e.g. 'monthly') |
UpdatePlanChargeOptions
All fields from CreatePlanChargeOptions are available but optional.
Plan Agent Actions
Configure pricing for specific agent actions within a plan. This is where you set per-unit pricing, tiered pricing, package pricing, etc.
// Create with per-unit pricing
const planAction = await coomon.createPlanAgentAction(plan.id, {
agentActionId: action.id,
pricingModel: 'per_unit',
unitPrice: 50, // cents per unit
includedUnits: 100,
overageAllowed: true,
})
// Create with tiered pricing
const tieredAction = await coomon.createPlanAgentAction(plan.id, {
agentActionId: action.id,
pricingModel: 'tiered',
tiers: [
{ tierOrder: 1, startUnit: 0, endUnit: 100, pricePerUnit: 10 },
{ tierOrder: 2, startUnit: 101, endUnit: 1000, pricePerUnit: 5 },
{ tierOrder: 3, startUnit: 1001, pricePerUnit: 2 },
],
})
// List all plan agent actions
const actions = await coomon.listPlanAgentActions(plan.id)
// Get a specific plan agent action
const fetched = await coomon.getPlanAgentAction(plan.id, planAction.id)
// Update
const updated = await coomon.updatePlanAgentAction(plan.id, planAction.id, {
unitPrice: 75,
includedUnits: 200,
})
// Delete
await coomon.deletePlanAgentAction(plan.id, planAction.id)CreatePlanAgentActionOptions
| Field | Type | Required | Description |
|---|---|---|---|
| agentActionId | string | Yes | The agent action to price |
| pricingModel | string | Yes | Pricing model (e.g. 'per_unit', 'tiered', 'package') |
| billableSignalId | string | No | Override billable signal |
| unitPrice | number | No | Price per unit in cents |
| packageSize | number | No | Units per package |
| packagePrice | number | No | Price per package in cents |
| includedUnits | number | No | Free units included |
| minimumCommitment | number | No | Minimum commitment amount |
| overageAllowed | boolean | No | Allow usage beyond included units |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
| tiers | array | No | Pricing tiers (see below) |
Tier fields:
| Field | Type | Required | Description |
|---|---|---|---|
| tierOrder | number | Yes | Tier sequence (1, 2, 3…) |
| startUnit | number | Yes | First unit in this tier |
| endUnit | number \| null | No | Last unit (omit for unlimited) |
| pricePerUnit | number | Yes | Price per unit in cents |
| flatFee | number | No | Flat fee for this tier |
UpdatePlanAgentActionOptions
All fields from CreatePlanAgentActionOptions are available but optional.
Pricing Tiers
Manage individual pricing tiers on plan agent actions.
// Add a tier
const tier = await coomon.createPlanAgentActionTier(plan.id, actionId, {
tierOrder: 4,
startUnit: 5001,
pricePerUnit: 1,
flatFee: 0,
})
// Update a tier
const updated = await coomon.updatePlanAgentActionTier(plan.id, actionId, tier.id, {
pricePerUnit: 0.5,
})
// Delete a tier
await coomon.deletePlanAgentActionTier(plan.id, actionId, tier.id)CreatePricingTierOptions
| Field | Type | Required | Description |
|---|---|---|---|
| tierOrder | number | Yes | Tier sequence (1, 2, 3…) |
| startUnit | number | Yes | First unit in this tier |
| endUnit | number \| null | No | Last unit (omit for unlimited) |
| pricePerUnit | number | Yes | Price per unit in cents |
| flatFee | number | No | Flat fee for this tier |
UpdatePricingTierOptions
All fields from CreatePricingTierOptions are available but optional.
Signal Management
Signals define the billable and cost metrics used across your plans and agent actions.
// Create a billable signal
const signal = await coomon.createSignal({
signalName: 'API Requests',
signalCode: 'api_requests',
signalType: 'billable',
aggregationType: 'count',
unitLabel: 'requests',
description: 'Number of API requests made',
})
// Create a cost signal
const costSignal = await coomon.createSignal({
signalName: 'LLM Token Cost',
signalCode: 'llm_token_cost',
signalType: 'cost',
aggregationType: 'sum',
unitLabel: 'tokens',
valueField: 'total_tokens',
})
// Get by ID
const fetched = await coomon.getSignal(signal.id)
// List with filters
const { data, pagination } = await coomon.listSignals({
signalType: 'billable',
status: 'active',
search: 'api',
})
// Update
const updated = await coomon.updateSignal(signal.id, {
description: 'Updated description',
unitLabel: 'calls',
})
// Delete
await coomon.deleteSignal(signal.id)CreateSignalOptions
| Field | Type | Required | Description |
|---|---|---|---|
| signalName | string | Yes | Signal display name |
| signalCode | string | Yes | Unique code (used in track() calls) |
| signalType | 'billable' \| 'cost' | Yes | Whether this signal tracks revenue or cost |
| aggregationType | 'count' \| 'sum' \| 'max' \| 'min' \| 'average' \| 'unique_count' | No | How to aggregate usage |
| unitLabel | string | No | Display label for units |
| valueField | string | No | Attribute key for value-based aggregation |
| description | string | No | Signal description |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
UpdateSignalOptions
| Field | Type | Required | Description |
|---|---|---|---|
| signalName | string | No | Signal display name |
| signalCode | string | No | Unique code |
| signalType | 'billable' \| 'cost' | No | Signal type |
| aggregationType | 'count' \| 'sum' \| 'max' \| 'min' \| 'average' \| 'unique_count' | No | Aggregation type |
| unitLabel | string | No | Unit label |
| valueField | string \| null | No | Value field (set null to clear) |
| description | string \| null | No | Description (set null to clear) |
| status | string | No | Signal status |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
ListSignalsQuery
| Field | Type | Description |
|---|---|---|
| signalType | string | Filter by signal type |
| status | string | Filter by status |
| search | string | Search by name |
| page | number | Page number |
| limit | number | Results per page |
| sort | string | Sort field |
| order | 'asc' \| 'desc' | Sort direction |
Payment Management
Record and manage payments from customers.
// Create a payment
const payment = await coomon.createPayment({
customerId: 'cust_123',
amount: 9900,
currency: 'USD',
paymentMethod: 'credit_card',
invoiceId: 'inv_abc',
paymentDate: '2026-04-01',
externalTransactionId: 'ch_stripe_123',
description: 'April invoice payment',
})
// Get by ID
const fetched = await coomon.getPayment(payment.id)
// List with filters
const { data, pagination } = await coomon.listPayments({
customerId: 'cust_123',
status: 'completed',
})
// Update
const updated = await coomon.updatePayment(payment.id, {
status: 'completed',
notes: 'Confirmed by bank',
})
// Refund (full)
const refund = await coomon.refundPayment(payment.id)
// Refund (partial)
const partialRefund = await coomon.refundPayment(payment.id, {
amount: 5000,
reason: 'Partial service credit',
externalRefundId: 're_stripe_456',
})
// Delete
await coomon.deletePayment(payment.id)CreatePaymentOptions
| Field | Type | Required | Description |
|---|---|---|---|
| customerId | string | Yes | Customer making the payment |
| amount | number | Yes | Amount in cents |
| invoiceId | string | No | Invoice this payment covers |
| currency | string | No | Currency code (e.g. 'USD') |
| paymentMethod | 'credit_card' \| 'debit_card' \| 'bank_transfer' \| 'ach' \| 'wire' \| 'check' \| 'cash' \| 'crypto' \| 'wallet' \| 'other' | No | Payment method |
| paymentDate | string | No | Payment date (YYYY-MM-DD) |
| description | string | No | Payment description |
| externalTransactionId | string | No | External payment provider ID |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
UpdatePaymentOptions
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | Payment status |
| paymentMethod | string | No | Payment method |
| externalTransactionId | string | No | External ID |
| failureReason | string | No | Failure reason |
| notes | string | No | Notes |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
RefundPaymentOptions
| Field | Type | Required | Description |
|---|---|---|---|
| amount | number | No | Refund amount in cents (omit for full refund) |
| reason | string | No | Refund reason |
| externalRefundId | string | No | External refund provider ID |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
ListPaymentsQuery
| Field | Type | Description |
|---|---|---|
| status | string | Filter by status |
| customerId | string | Filter by customer |
| contractId | string | Filter by contract |
| page | number | Page number |
| limit | number | Results per page |
| sort | string | Sort field |
| order | 'asc' \| 'desc' | Sort direction |
Invoice Management
Create, manage, and finalize invoices for customers.
// Create an invoice with line items
const invoice = await coomon.createInvoice({
customerId: 'cust_123',
contractId: 'contract_abc',
issueDate: '2026-04-01',
dueDate: '2026-04-30',
billingPeriodFrom: '2026-03-01',
billingPeriodTo: '2026-03-31',
currency: 'USD',
lineItems: [
{
description: 'API Requests (1,000 units)',
quantity: 1000,
unitPriceCents: 5,
subtotalCents: 5000,
totalCents: 5000,
pricingModel: 'per_unit',
periodFrom: '2026-03-01',
periodTo: '2026-03-31',
},
{
description: 'Platform Fee',
quantity: 1,
unitPriceCents: 9900,
subtotalCents: 9900,
totalCents: 9900,
},
],
taxRate: 0.08,
notes: 'March 2026 usage',
autoFinalize: false,
})
// Get by ID
const fetched = await coomon.getInvoice(invoice.id)
// List with filters
const { data, pagination } = await coomon.listInvoices({
customerId: 'cust_123',
status: 'draft',
})
// Update
const updated = await coomon.updateInvoice(invoice.id, {
notes: 'Updated notes',
dueDate: '2026-05-15',
})
// Finalize (lock for payment)
const finalized = await coomon.finalizeInvoice(invoice.id, {
sendEmail: true,
})
// Void (cancel a finalized invoice)
const voided = await coomon.voidInvoice(invoice.id, {
reason: 'Issued in error',
})
// Preview (calculate without creating)
const preview = await coomon.previewInvoice({
customerId: 'cust_123',
contractId: 'contract_abc',
})
console.log(preview.amount, preview.line_items)CreateInvoiceOptions
| Field | Type | Required | Description |
|---|---|---|---|
| customerId | string | Yes | Customer to invoice |
| issueDate | string | Yes | Issue date (YYYY-MM-DD) |
| lineItems | CreateInvoiceLineItemOptions[] | Yes | Line items (see below) |
| contractId | string | No | Contract this invoice covers |
| dueDate | string | No | Due date (YYYY-MM-DD) |
| billingPeriodFrom | string | No | Billing period start |
| billingPeriodTo | string | No | Billing period end |
| currency | string | No | Currency code |
| taxRate | number | No | Tax rate (e.g. 0.08 for 8%) |
| notes | string | No | Invoice notes |
| taxes | CreateInvoiceTaxOptions[] | No | Tax line items (see below) |
| autoFinalize | boolean | No | Finalize immediately after creation |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
CreateInvoiceLineItemOptions
| Field | Type | Required | Description |
|---|---|---|---|
| description | string | Yes | Line item description |
| quantity | number | Yes | Quantity |
| unitPriceCents | number | Yes | Price per unit in cents |
| subtotalCents | number | Yes | Subtotal in cents |
| totalCents | number | Yes | Total in cents |
| contractId | string | No | Source contract |
| sourceType | string | No | Source type (e.g. 'agent_action') |
| sourceId | string | No | Source ID |
| agentId | string | No | Agent ID |
| featureId | string | No | Feature ID |
| signalId | string | No | Signal ID |
| pricingModel | string | No | Pricing model used |
| periodFrom | string | No | Line item period start |
| periodTo | string | No | Line item period end |
| includedUnitsUsed | number | No | Included units consumed |
| billableUnits | number | No | Billable units beyond included |
| tierNumber | number | No | Pricing tier number |
| discountCents | number | No | Discount in cents |
| taxCents | number | No | Tax in cents |
| sortOrder | number | No | Display order |
CreateInvoiceTaxOptions
| Field | Type | Required | Description |
|---|---|---|---|
| taxName | string | Yes | Tax name (e.g. "Sales Tax") |
| taxRate | number | Yes | Tax rate |
| taxableAmount | number | Yes | Taxable amount |
| taxAmount | number | Yes | Calculated tax amount |
UpdateInvoiceOptions
| Field | Type | Required | Description |
|---|---|---|---|
| issueDate | string | No | Issue date |
| dueDate | string | No | Due date |
| billingPeriodFrom | string | No | Billing period start |
| billingPeriodTo | string | No | Billing period end |
| currency | string | No | Currency code |
| taxRate | number | No | Tax rate |
| notes | string | No | Invoice notes |
| lineItems | CreateInvoiceLineItemOptions[] | No | Replace line items |
| taxes | CreateInvoiceTaxOptions[] | No | Replace tax items |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
FinalizeInvoiceOptions
| Field | Type | Required | Description |
|---|---|---|---|
| sendEmail | boolean | No | Send invoice email to customer |
VoidInvoiceOptions
| Field | Type | Required | Description |
|---|---|---|---|
| reason | string | Yes | Reason for voiding |
PreviewInvoiceOptions
| Field | Type | Required | Description |
|---|---|---|---|
| customerId | string | Yes | Customer to preview for |
| contractId | string | No | Contract to preview |
Wallet Management
Prepaid credit wallets for your customers.
// Create wallet
const wallet = await coomon.createWallet({
customerId: 'cust_123',
name: 'Main Credits',
currency: 'USD',
})
// Add credits
const topUp = await coomon.topUpWallet(wallet.id, {
amount: 100,
creditType: 'purchased',
idempotencyKey: 'topup-001', // prevents double-charging
})
// Check balance
const balance = await coomon.getWalletBalance(wallet.id)
console.log(balance.credits_balance) // 100
// Deduct credits
const deduction = await coomon.deductWallet(wallet.id, {
amount: 30,
description: 'Agent API usage',
idempotencyKey: 'debit-001',
})
// Get wallet details
const details = await coomon.getWallet(wallet.id)CreateWalletOptions
| Field | Type | Required | Description |
|---|---|---|---|
| customerId | string | Yes | Owner customer ID |
| name | string | Yes | Wallet display name |
| description | string | No | Wallet description |
| currency | string | No | Currency code (e.g. 'USD') |
| conversionRate | number | No | 1 monetary unit = N credits |
| initialCredits | number | No | Seed balance on creation |
| autoRechargeEnabled | boolean | No | Enable auto top-up |
| autoRechargeThreshold | number | No | Top up when balance drops below this |
| autoRechargeAmount | number | No | Credits to add on each recharge |
| allowNegativeBalance | boolean | No | Allow balance to go negative |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
TopUpWalletOptions
| Field | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | Amount to credit |
| creditAmount | number | No | Override credit amount (if different from amount) |
| creditType | 'free' \| 'purchased' \| 'promotional' \| 'bonus' | No | Type of credit |
| description | string | No | Transaction description |
| idempotencyKey | string | No | Prevents duplicate transactions |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
DeductWalletOptions
| Field | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | Amount to debit |
| description | string | No | Transaction description |
| idempotencyKey | string | No | Prevents duplicate transactions |
| metadata | Record<string, unknown> | No | Arbitrary key-value data |
Configuration
const coomon = new Coomon('sk_live_abc123', {
host: 'https://api.coobird.ai',
flushAt: 20,
flushInterval: 10_000,
maxRetries: 3,
maxBatchSize: 100,
maxQueueSize: 1000,
requestTimeout: 10_000,
shutdownTimeoutMs: 30_000,
debug: false,
disabled: false,
onError: (err) => console.error('Coobird SDK error:', err),
})| Option | Type | Default | Description |
|---|---|---|---|
| host | string | 'https://api.dev.coobird.ai' | API host URL. Use https://api.coobird.ai for production. |
| flushAt | number | 20 | Auto-flush when queue reaches this many events |
| flushInterval | number | 10000 | Auto-flush every N ms. Set 0 to disable timer. |
| maxRetries | number | 3 | Retry attempts on retriable failures (5xx, 429, network errors) |
| maxBatchSize | number | 100 | Max events per HTTP request |
| maxQueueSize | number | 1000 | Max events in memory. Oldest dropped when exceeded. |
| requestTimeout | number | 10000 | Per-request timeout in ms. Uses AbortController. |
| shutdownTimeoutMs | number | 30000 | Max time to wait during shutdown() |
| debug | boolean | false | Enable verbose [coomon] logging to console |
| disabled | boolean | false | Disable all tracking (useful in tests/CI) |
| onError | (err) => void | console.error | Called on unrecoverable send errors |
Environments
Long-Running Servers (Express, Fastify, NestJS)
Use the queued track() methods for best performance. Call shutdown() on process exit:
import { Coomon } from '@coobird-ai/sdk'
const coomon = new Coomon(process.env.COOBIRD_API_KEY, {
host: 'https://api.coobird.ai',
})
// In your route handler
app.post('/run-agent', async (req, res) => {
const result = await runAgent(req.body)
coomon.trackTask({
customerId: req.body.customerId,
agentId: 'agent_xxx',
signalCode: 'agent_run',
attributes: { model: result.model, tokens: result.tokens },
})
res.json(result)
})
// Graceful shutdown
process.on('SIGTERM', async () => {
await coomon.shutdown()
process.exit(0)
})Serverless (AWS Lambda, Vercel, Cloudflare Workers)
Use trackImmediate() to ensure events are sent before the function returns:
import { Coomon } from '@coobird-ai/sdk'
const coomon = new Coomon(process.env.COOBIRD_API_KEY, {
host: 'https://api.coobird.ai',
flushInterval: 0, // disable background timer (not useful in serverless)
})
export async function handler(event) {
const result = await runAgent(event.body)
await coomon.trackTaskImmediate({
customerId: event.body.customerId,
agentId: 'agent_xxx',
signalCode: 'agent_run',
attributes: { model: result.model },
})
return { statusCode: 200, body: JSON.stringify(result) }
}Tests & CI
Disable the SDK to avoid sending real events:
const coomon = new Coomon('sk_test_key', { disabled: true })
coomon.track({ ... }) // no-op
await coomon.trackImmediate({ ... }) // returns { accepted: 0, ... }
await coomon.createCustomer({ ... }) // throws '[coomon] SDK is disabled'Retry Behavior
The SDK retries intelligently based on error type:
| Error | Retried? | Why | |---|---|---| | Network error | Yes | Transient connectivity issue | | 429 Too Many Requests | Yes | Rate limited, back off and retry | | 500, 502, 503, 504 | Yes | Server error, likely transient | | 400 Bad Request | No | Client error, won't succeed on retry | | 401 Unauthorized | No | Invalid API key | | 403 Forbidden | No | Permission denied | | 404 Not Found | No | Resource doesn't exist |
Retries use exponential backoff: 1s, 2s, 4s, etc.
For queued events (track()), errors are reported via onError and the event is dropped. For direct calls (createCustomer(), trackImmediate()), errors are thrown to the caller.
TypeScript
Full TypeScript support with all types exported:
import type {
// Configuration
CoomonOptions,
// Event tracking
TrackOptions,
TrackTaskOptions,
TrackWorkflowOptions,
TrackOutcomeOptions,
BatchTrackResponse,
TrackEventResponse,
// Common
PaginatedResponse,
ListQuery,
// Customers
CreateCustomerOptions,
UpdateCustomerOptions,
CustomerResponse,
ListCustomersQuery,
// Contracts
CreateContractOptions,
UpdateContractOptions,
ActivateContractOptions,
SuspendContractOptions,
CancelContractOptions,
ContractResponse,
ListContractsQuery,
// Agents
CreateAgentOptions,
UpdateAgentOptions,
AgentResponse,
ListAgentsQuery,
CreateAgentWithActionsOptions,
// Agent Actions
CreateAgentActionOptions,
UpdateAgentActionOptions,
AgentActionResponse,
ListAgentActionsQuery,
// Plans
CreatePlanOptions,
UpdatePlanOptions,
PlanResponse,
ListPlansQuery,
// Plan Charges
CreatePlanChargeOptions,
UpdatePlanChargeOptions,
PlanChargeResponse,
// Plan Agent Actions
CreatePlanAgentActionOptions,
UpdatePlanAgentActionOptions,
PlanAgentActionResponse,
// Pricing Tiers
CreatePricingTierOptions,
UpdatePricingTierOptions,
PricingTierResponse,
// Signals
CreateSignalOptions,
UpdateSignalOptions,
SignalResponse,
ListSignalsQuery,
// Payments
CreatePaymentOptions,
UpdatePaymentOptions,
RefundPaymentOptions,
PaymentResponse,
PaymentListResponse,
RefundResponse,
ListPaymentsQuery,
// Invoices
CreateInvoiceOptions,
CreateInvoiceLineItemOptions,
CreateInvoiceTaxOptions,
UpdateInvoiceOptions,
FinalizeInvoiceOptions,
VoidInvoiceOptions,
PreviewInvoiceOptions,
InvoiceResponse,
InvoiceActionResponse,
InvoicePreviewResponse,
ListInvoicesQuery,
// Wallets
CreateWalletOptions,
WalletResponse,
WalletBalanceResponse,
TopUpWalletOptions,
DeductWalletOptions,
WalletTransactionResponse,
} from '@coobird-ai/sdk'API Reference
Constructor
new Coomon(apiKey: string, options?: CoomonOptions)Throws if apiKey is empty or missing.
Event Tracking
| Method | Returns | Description |
|---|---|---|
| track(options) | void | Queue event for batch delivery |
| trackTask(options) | void | Queue task event |
| trackWorkflow(options) | void | Queue workflow event |
| trackOutcome(options) | void | Queue outcome event |
| trackImmediate(options) | Promise<BatchTrackResponse> | Send event immediately |
| trackTaskImmediate(options) | Promise<BatchTrackResponse> | Send task event immediately |
| trackWorkflowImmediate(options) | Promise<BatchTrackResponse> | Send workflow event immediately |
| trackOutcomeImmediate(options) | Promise<BatchTrackResponse> | Send outcome event immediately |
Global Attributes
| Method | Returns | Description |
|---|---|---|
| register(attributes) | void | Set attributes merged into every event |
| unregister(key) | void | Remove a global attribute |
Customers
| Method | Returns | Description |
|---|---|---|
| createCustomer(options) | Promise<CustomerResponse> | Create a customer |
| getCustomer(id) | Promise<CustomerResponse> | Get customer by ID |
| listCustomers(query?) | Promise<PaginatedResponse<CustomerResponse>> | List customers |
| updateCustomer(id, options) | Promise<CustomerResponse> | Update a customer |
| deleteCustomer(id) | Promise<void> | Delete a customer |
Contracts
| Method | Returns | Description |
|---|---|---|
| createContract(options) | Promise<ContractResponse> | Create a contract |
| getContract(id) | Promise<ContractResponse> | Get contract by ID |
| listContracts(query?) | Promise<PaginatedResponse<ContractResponse>> | List contracts |
| updateContract(id, options) | Promise<ContractResponse> | Update a contract |
| activateContract(id, options?) | Promise<ContractResponse> | Activate a draft contract |
| suspendContract(id, options?) | Promise<ContractResponse> | Suspend an active contract |
| cancelContract(id, options) | Promise<ContractResponse> | Cancel a contract |
Agents
| Method | Returns | Description |
|---|---|---|
| createAgent(options) | Promise<AgentResponse> | Create an agent |
| getAgent(id) | Promise<AgentResponse> | Get agent by ID |
| listAgents(query?) | Promise<PaginatedResponse<AgentResponse>> | List agents |
| updateAgent(id, options) | Promise<AgentResponse> | Update an agent |
| deleteAgent(id) | Promise<void> | Delete an agent |
| createAgentWithActions(options) | Promise<AgentResponse> | Create agent with actions in one call |
Agent Actions
| Method | Returns | Description |
|---|---|---|
| createAgentAction(agentId, options) | Promise<AgentActionResponse> | Create an agent action |
| listAgentActions(agentId, query?) | Promise<PaginatedResponse<AgentActionResponse>> | List agent actions |
| updateAgentAction(agentId, actionId, options) | Promise<AgentActionResponse> | Update an agent action |
| deleteAgentAction(agentId, actionId) | Promise<void> | Delete an agent action |
Plans
| Method | Returns | Description |
|---|---|---|
| createPlan(options) | Promise<PlanResponse> | Create a plan |
| getPlan(id) | Promise<PlanResponse> | Get plan by ID |
| listPlans(query?) | Promise<PaginatedResponse<PlanResponse>> | List plans |
| updatePlan(id, options) | Promise<PlanResponse> | Update a plan |
| deletePlan(id) | Promise<void> | Delete a plan |
Plan Charges
| Method | Returns | Description |
|---|---|---|
| createPlanCharge(planId, options) | Promise<PlanChargeResponse> | Create a plan charge |
| listPlanCharges(planId) | Promise<PlanChargeResponse[]> | List plan charges |
| updatePlanCharge(planId, chargeId, options) | Promise<PlanChargeResponse> | Update a plan charge |
| deletePlanCharge(planId, chargeId) | Promise<void> | Delete a plan charge |
Plan Agent Actions
| Method | Returns | Description |
|---|---|---|
| createPlanAgentAction(planId, options) | Promise<PlanAgentActionResponse> | Create a plan agent action |
| listPlanAgentActions(planId) | Promise<PlanAgentActionResponse[]> | List plan agent actions |
| getPlanAgentAction(planId, actionId) | Promise<PlanAgentActionResponse> | Get a plan agent action |
| updatePlanAgentAction(planId, actionId, options) | Promise<PlanAgentActionResponse> | Update a plan agent action |
| deletePlanAgentAction(planId, actionId) | Promise<void> | Delete a plan agent action |
Pricing Tiers (Plan Agent Actions)
| Method | Returns | Description |
|---|---|---|
| createPlanAgentActionTier(planId, actionId, options) | Promise<PricingTierResponse> | Add a pricing tier |
| updatePlanAgentActionTier(planId, actionId, tierId, options) | Promise<PricingTierResponse> | Update a pricing tier |
| deletePlanAgentActionTier(planId, actionId, tierId) | Promise<void> | Delete a pricing tier |
Signals
| Method | Returns | Description |
|---|---|---|
| createSignal(options) | Promise<SignalResponse> | Create a signal |
| getSignal(id) | Promise<SignalResponse> | Get signal by ID |
| listSignals(query?) | Promise<PaginatedResponse<SignalResponse>> | List signals |
| updateSignal(id, options) | Promise<SignalResponse> | Update a signal |
| deleteSignal(id) | Promise<void> | Delete a signal |
Payments
| Method | Returns | Description |
|---|---|---|
| createPayment(options) | Promise<PaymentResponse> | Create a payment |
| getPayment(id) | Promise<PaymentResponse> | Get payment by ID |
| listPayments(query?) | Promise<PaginatedResponse<PaymentResponse>> | List payments |
| updatePayment(id, options) | Promise<PaymentResponse> | Update a payment |
| refundPayment(id, options?) | Promise<RefundResponse> | Refund a payment |
| deletePayment(id) | Promise<void> | Delete a payment |
Invoices
| Method | Returns | Description |
|---|---|---|
| createInvoice(options) | Promise<InvoiceResponse> | Create an invoice |
| getInvoice(id) | Promise<InvoiceResponse> | Get invoice by ID |
| listInvoices(query?) | Promise<PaginatedResponse<InvoiceResponse>> | List invoices |
| updateInvoice(id, options) | Promise<InvoiceResponse> | Update an invoice |
| finalizeInvoice(id, options?) | Promise<InvoiceActionResponse> | Finalize an invoice |
| voidInvoice(id, options) | Promise<InvoiceActionResponse> | Void an invoice |
| previewInvoice(options) | Promise<InvoicePreviewResponse> | Preview invoice calculation |
Wallets
| Method | Returns | Description |
|---|---|---|
| createWallet(options) | Promise<WalletResponse> | Create a prepaid wallet |
| getWallet(walletId) | Promise<WalletResponse> | Get wallet details |
| getWalletBalance(walletId) | Promise<WalletBalanceResponse> | Get current balance |
| topUpWallet(walletId, options) | Promise<WalletTransactionResponse> | Add credits |
| deductWallet(walletId, options) | Promise<WalletTransactionResponse> | Deduct credits |
Lifecycle
| Method | Returns | Description |
|---|---|---|
| flush() | Promise<BatchTrackResponse \| null> | Drain the queue manually |
| shutdown() | Promise<void> | Flush + stop timer. Call before process exit. |
License
MIT
