Skip to main content

Usage-Based Billing

Usage-based pricing (also known as metered billing) allows you to charge customers based on their actual consumption rather than a fixed fee. This is ideal for APIs, cloud services, AI models, and any product where usage varies per customer.

How It Works

  1. You create a meter that defines what to measure and how to aggregate it
  2. You create products with usage-based pricing linked to meters
  3. You create a contract with the customer, which pre-creates invoices for each billing period
  4. Your application sends usage events to Monk via the API as customers consume resources
  5. Monk automatically matches usage events to the correct invoice based on the meter and service period
Usage events are aggregated based on the meter’s aggregation method (Sum, Count, Max, or Min) within each billing period.

Key Concepts

Meters

A meter defines what you’re measuring and how to aggregate it. Meters decouple measurement from pricing, giving you flexibility to:
  • Use the same meter across all customers
  • Have different pricing per customer without changing your integration
  • Change pricing without modifying API calls
PropertyDescriptionExample
CodeUnique identifier for API callsAPI_CALL, AI_TOKENS
Display NameHuman-readable name”API Calls”, “AI Tokens”
AggregationHow usage is combinedSum, Count, Max, Min
Think of meters as “what you measure” and pricing as “how you charge for it”.

Aggregation Types

Choose how usage is combined within a billing period:
TypeDescriptionUse Case
SumTotal of all usage valuesAPI calls, tokens, data transfer
CountNumber of usage eventsActive users, sessions
MaxHighest value in periodPeak concurrent users, max storage
MinLowest value in periodMinimum commitment tracking

Customer ID

You can identify customers using either their internal Monk UUID (customer_id) or your own external identifier (external_customer_id). Find Monk customer IDs via the List Customers endpoint or in the dashboard.

Idempotency

You can provide an idempotency_key to prevent duplicates. If you retry a failed request with the same key, Monk will reject the duplicate. If omitted, a UUID is auto-generated for each event.
Structure your idempotency keys to be unique and meaningful: {event_name}_ {customer}_{timestamp} (e.g., api_call_cust123_2026-01-15T10:30:00Z)

Setting Up Usage-Based Pricing

1. Create a Meter

In your Monk dashboard, navigate to Products → Meters and create a meter:
  • Code: Unique identifier used in API calls (e.g., API_CALL, AI_TOKENS)
  • Display Name: Human-readable name for invoices
  • Aggregation: How usage is combined (Sum, Count, Max, Min)

2. Create a Product with Usage Pricing

Create a product and select Usage-based as the pricing model:
  • Meter: Select the meter you created
  • Charge type: Per unit (flat rate) or Per tier (volume-based tiers)
  • Price: The rate per unit or tier pricing

3. Get Your API Key

Navigate to Settings → API Keys to create or copy your API key. You’ll need the usage:write scope to send usage events.

4. Send Usage Events

When a customer uses your product, send an event to Monk via the Events API:
// Example: Track API calls
const response = await fetch('https://events-api.monk.com/v1/events', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer mk_live_your_api_key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    customer_id: 'customer-uuid-here',
    event_name: 'api_call',
    properties: {
      tokens: 100,
    },
  }),
});
// Response: { "status": "accepted", "idempotency_key": "...", "request_id": "..." }
For bulk ingestion, use the Batch endpoint:
// Example: Send multiple events at once
await fetch('https://events-api.monk.com/v1/events/batch', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer mk_live_your_api_key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    events: [
      {
        customer_id: 'cust-1',
        event_name: 'api_call',
        properties: { tokens: 100 },
      },
      {
        customer_id: 'cust-2',
        event_name: 'api_call',
        properties: { tokens: 250 },
      },
    ],
  }),
});
// Response: { "status": "accepted", "count": 2, "request_id": "..." }

Via Dashboard (Single Events)

You can also add individual usage events directly from the Monk dashboard. Navigate to a customer’s usage tab and click Add Usage Event to manually record usage. This is useful for:
  • Testing your usage-based pricing setup
  • Recording one-off usage that wasn’t captured by your system
  • Making adjustments or corrections
CSV Upload: Bulk upload of usage events via CSV is coming soon. This will allow you to import historical usage data or batch upload events from external systems.

Billing Flow

  1. Contract creation: When you create a contract with usage-based pricing, Monk pre-creates invoices for each billing period
  2. During the billing period: Your app sends usage events as they occur
  3. Automatic matching: Monk matches each usage event to the correct invoice based on the meter and service period
  4. Invoice finalization: At the end of the period, the invoice is finalized with all aggregated usage and ready for payment

Best Practices

Send usage events as they happen rather than batching at the end of the period. This ensures accurate billing even if your system experiences issues.
Choose clear, uppercase codes with underscores (e.g., API_CALL, AI_TOKENS). These identify what you’re measuring.
Generate unique idempotency keys for every event. This allows safe retries without creating duplicate charges.
If the usage API returns an error, queue the event for retry. Don’t lose usage data due to transient failures.
Pass the timestamp field when the usage occurred, especially if sending events with a delay. This ensures usage is attributed to the correct billing period.

Example: AI Token Billing

Here’s a complete example for billing AI model usage:
// After each AI API call, record the token usage
const recordUsage = async (customerId, tokensUsed, requestId) => {
  try {
    const response = await fetch('https://events-api.monk.com/v1/events', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.MONK_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        customer_id: customerId,
        event_name: 'ai_tokens',
        idempotency_key: `ai_tokens_${customerId}_${requestId}`,
        properties: {
          tokens: tokensUsed,
          model: 'gpt-4',
          feature: 'chat',
        },
      }),
    });

    if (!response.ok) {
      const error = await response.json();
      if (error.retry) {
        await queueForRetry({ customerId, tokensUsed, requestId });
      } else {
        console.error('Non-retryable error:', error);
      }
    }
  } catch (error) {
    console.error('Failed to record usage:', error);
    await queueForRetry({ customerId, tokensUsed, requestId });
  }
};

Next Steps

Create Event

Send a single usage event via the Events API

Batch Create Events

Send multiple usage events in one request

List Customers

Get customer IDs for usage tracking

Legacy Usages (Deprecated)

Old endpoint — migrate to Events API