v1

latestOpenAPI 3.1.02026-08-042453938.9 KB
Usage

Record usage and charge

Record a billable usage event and immediately charge the customer.

Requires a secret key (sk_*) with at least the OPERATOR role.

This endpoint waits for on-chain confirmation before returning, ensuring the charge is settled. For faster responses, use POST /v1/usage/async.

x402 Payment Flow: If the customer has insufficient balance, returns 402 with payment headers. The client can sign a payment with their session key and retry with X-Payment-* headers to complete the charge.

Idempotency: Include an idempotencyKey to safely retry requests without duplicate charges.

post/v1/usage

Request body

customerIdstring

Drip customer ID (cus_*). One of customerId, externalCustomerId, or stripeCustomerId is required.

externalCustomerIdstring

Your own database's customer ID. If no Drip customer exists yet for (business, externalCustomerId), one is auto-provisioned as an internal customer on first use.

stripeCustomerIdstring

Stripe customer ID (cus_…) from your connected Stripe account. If no Drip customer exists yet for (business, stripeCustomerId), one is auto-provisioned and usage is forwarded to Stripe's Billing Meter Events. Intended for merchants who just finished Stripe OAuth, so you can start sending usage against Stripe IDs immediately without waiting for the background customer import.

usageTypestring

Usage type matching a pricing plan (defaults to "generic" if omitted)

quantitynumber

Quantity of usage (defaults to 1 if omitted)

unitsstring

Human-readable unit label for display (e.g., "tokens", "API calls", "seconds")

descriptionstring

Human-readable description for support/finance teams (e.g., "Chat completion for Customer XYZ")

idempotencyKeystring required

Unique key to prevent duplicate charges. Required. Use a stable identifier like {customerId}_{action}_{timestamp} so retries produce the same key.

metadataobject

Optional metadata

workflowIdstring

Link this usage to a workflow

runIdstring

Link this usage to an agent run

eventType'USAGE' | 'INFERENCE' | 'TOOL_CALL' | 'DELEGATION' | 'RETRIEVAL' | 'CUSTOM'

Classify the type of usage event

actionNamestring

Name of the action performed (e.g., "chat_completion", "image_generation")

outcome'SUCCEEDED' | 'FAILED' | 'PENDING' | 'SKIPPED' | 'CANCELLED'

Outcome of the action

explanationstring

Human-readable explanation of what happened

parentEventIdstring

ID of the parent event (for building causality trees)

retryOfEventIdstring

ID of the event this is retrying (for retry chain tracking)

attemptNumberinteger

Attempt number (1 = first try, 2 = first retry, etc.)

inputHashstring

SHA-256 hash of the input for verification

outputHashstring

SHA-256 hash of the output for verification

inputobject

Raw input data (will be hashed for verification)

outputobject

Raw output data (will be hashed for verification)

Example request

{
  "customerId": "cus_abc123def456",
  "externalCustomerId": "user_42",
  "stripeCustomerId": "cus_NffrFeUfNV2Hib",
  "usageType": "api_call",
  "quantity": 100,
  "units": "API calls",
  "description": "Eligibility check for Pharmacy ABC (workflow: insurance_verify)",
  "idempotencyKey": "req_20240115_abc123",
  "metadata": {
    "endpoint": "/v1/chat",
    "model": "gpt-4"
  }
}

Response

Usage recorded. Either an on-chain charge was created (charge object populated) or the customer has no on-chain address and the request was auto-promoted to internal/visibility mode (charge=null, mode=internal).

successboolean
usageEventIdstring

Usage event ID

isDuplicateboolean

True if this was a duplicate request matched by idempotencyKey

mode'internal' nullable

Present when the request was recorded as internal/visibility usage.

autoPromotedboolean nullable

True when /usage auto-promoted to /usage/internal because the customer has no on-chain address. Explicit internal customers get mode=internal with autoPromoted=false.

reasonstring nullable

Human-readable explanation of why the request was routed to the internal path.

Example response

{
  "success": true
}