> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.tabs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.tabs.com/_mcp/server.

# Usage-based billing quickstart

Learn how to meter usage events and generate an invoice based on consumption using the Tabs API. In this guide you'll create an event type, attach a usage-based billing term to an existing contract, send usage events, and verify the resulting invoice.

## Get your API key

You can create an API key from the [app](https://app.tabsplatform.com/merchant/developers). All requests require your key in the `Authorization` header.

## Before you begin

This guide assumes you already have a customer and a processed contract in Tabs. If you don't, follow the first two steps of the [Invoice a Customer Quickstart](/invoice-customer-quickstart) to create them.

You'll need:

* A Customer ID (for example, `cust_abc123`)
* A Contract ID (for example, `cont_xyz789`)

## Step 1: Create an event type

An event type defines the unit of consumption that Tabs meters. Event types are global to your Tabs account—create one per distinct metric you want to track (for example, API calls, active users, or GB transferred).

Create an event type using the `POST /v3/events/types` endpoint:

```bash
curl -X POST \
  https://integrators.prod.api.tabsplatform.com/v3/events/types \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API Calls"
  }'
```

Tabs returns a response like:

```json
{
  "id": "evt_type_abc123",
  "name": "API Calls"
}
```

Save the returned `id`—you'll use it in the next steps.

You can also create and manage event types in the Tabs app on the usage events settings page.

## Step 2: Create a usage-based billing term

A billing term defines the billing side of a contract — what you charge, how much it costs, and how frequently. For usage-based billing, set `billingType` to `UNIT`, `quantity` to `0`, and link the billing term to the event type you created in Step 1 using the `eventTypeId` field.

Create the billing term on the contract by calling the `POST /v3/contracts/{id}/billing-terms` endpoint:

```bash
curl -X POST \
  https://integrators.prod.api.tabsplatform.com/v3/contracts/cont_xyz789/billing-terms \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API Calls — Monthly Usage",
    "description": "Metered API call charges, billed monthly in arrears",
    "billingStartDate": "2025-02-01",
    "isRecurring": true,
    "interval": "MONTH",
    "intervalFrequency": 1,
    "duration": 11,
    "invoiceDateStrategy": "ARREARS",
    "netPaymentTerms": 30,
    "quantity": 0,
    "billingType": "UNIT",
    "pricingType": "SIMPLE",
    "eventTypeId": "evt_type_abc123",
    "itemId": "item_abc123",
    "pricing": [
      {
        "tier": 1,
        "amount": 0.01,
        "amountType": "PER_ITEM",
        "tierMinimum": 0
      }
    ]
  }'
```

When you omit `billingTermGroupId`, Tabs automatically creates a billing term group and a corresponding billing term with a 1:1 mapping.

Tabs returns a response like:

```json
{
  "payload": {
    "name": "API Calls — Monthly Usage",
    "description": "Metered API call charges, billed monthly in arrears",
    "billingStartDate": "2025-02-01",
    "isRecurring": true,
    "interval": "MONTH",
    "intervalFrequency": 1,
    "duration": 11,
    "netPaymentTerms": 30,
    "quantity": 0,
    "billingType": "UNIT",
    "pricingType": "SIMPLE",
    "eventTypeId": "evt_type_abc123",
    "itemId": "item_abc123",
    "billingTermGroupId": "btg_auto_123",
    "id": "bt_def456",
    "contractId": "cont_xyz789",
    "billingEndDate": "2025-12-31",
    "createdAt": "2025-01-15T10:00:00Z"
  },
  "success": true,
  "message": "Billing term created",
  "error": null
}
```

The `invoiceDateStrategy` field controls when Tabs generates the invoice relative to the service period. For usage-based billing, `ARREARS` is the most common choice because Tabs needs to collect all usage events before generating the invoice. For pay-as-you-go and non-prepaid commitment billing terms, Tabs generates draft invoices for each billing period. Because this billing term uses the `ARREARS` strategy, the invoice for February usage has an `issueDate` of `2025-03-01` and a `dueDate` 30 days later (`2025-03-31`), based on the `netPaymentTerms` you specified. `LAST_OF_PERIOD` is also a valid choice for usage-based billing if the invoice date were to fall within the same month as usage, which is a common pattern for revenue recognition.

For tiered pricing (for example, volume discounts), set `pricingType` to `TIERED` and provide multiple entries in the `pricing` array with ascending `tierMinimum` values.

## Step 3: Send usage events

With the event type and billing term in place, send usage events as they occur. Each event represents a single unit of consumption tied to a customer.

Submit an event using the `POST /v1/events` endpoint:

```bash
curl -X POST \
  https://usage-events.prod.api.tabsplatform.com/v1/events \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cust_abc123",
    "eventTypeId": "evt_type_abc123",
    "datetime": "2025-02-15T14:30:00Z",
    "value": 1,
    "idempotencyKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }'
```

Tabs returns a response like:

```json
{
  "success": true,
  "message": "Event created successfully",
  "data": {
    "events": {
      "customerId": "cust_abc123",
      "eventTypeId": "evt_type_abc123",
      "datetime": "2025-02-15T14:30:00Z",
      "idempotencyKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "value": 1
    }
  }
}
```

Each event requires a unique `idempotencyKey`. Tabs deduplicates events using the `(manufacturerId, idempotencyKey)` pair for 45 days.

Usage events can only be billed if a billing term exists with a service period that encompasses the event's `datetime`. Events outside of any billing term's service period are ingested but do not appear on an invoice and should be deleted.

## Step 4: Verify the invoice

Tabs recalculates usage-based invoices every hour. After sending events, wait for the next hourly recalculation, then fetch the invoice to confirm the usage is reflected.

Use the Customer ID to look up invoices with the `GET /v3/invoices` endpoint:

```bash
curl "https://integrators.prod.api.tabsplatform.com/v3/invoices?filter=customerId:eq:cust_abc123&page=1&limit=50" \
  -H "Authorization: YOUR_API_KEY"
```

Tabs returns a response like:

```json
{
  "payload": {
    "data": [
      {
        "id": "inv_ghi012",
        "customerId": "cust_abc123",
        "status": "DRAFT",
        "issueDate": "2025-03-01",
        "dueDate": "2025-03-31",
        "total": 150.00,
        "balanceRemaining": 150.00,
        "lineItems": [
          {
            "id": "li_001",
            "name": "API Calls — Monthly Usage",
            "description": "Metered API call charges, billed monthly",
            "quantity": 15000,
            "subtotal": 150.00,
            "discountTotal": 0,
            "total": 150.00,
            "salesTaxRate": "0",
            "item": {
              "id": "item_abc123",
              "name": "API Calls",
              "externalIds": []
            }
          }
        ]
      }
    ],
    "limit": 50,
    "totalItems": 1,
    "currentPage": 1
  },
  "success": true,
  "message": "string",
  "error": null
}
```

The invoice reflects 15,000 API calls at \$0.01 each for the February billing period. When you're ready to send the invoice to the customer, transition it from `DRAFT` to `SENT`:

```bash
curl -X POST \
  "https://integrators.prod.api.tabsplatform.com/v3/customers/cust_abc123/invoices/inv_ghi012/actions" \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "SEND",
    "sendToErp": true,
    "sendToCustomer": true
  }'
```

Tabs sends the invoice to the customer for payment.

Setting `sendToErp` to `true` also pushes the invoice to your connected ERP.

## Next steps

* [Collect payments](/collect-payments)
* [Set up tiered usage pricing](/bill-customers/custom)