npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@coobird-ai/sdk

v2.0.1

Published

Official Node.js SDK for Coobird — agent usage tracking, metered billing, and wallet management for AI agents.

Readme

@coobird-ai/sdk

npm version npm downloads

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/sdk

Requirements: 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