> ## Documentation Index
> Fetch the complete documentation index at: https://docs.retempo.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Implement Usage-Based Billing for APIs and Agent Services

> Set up metered usage billing in Retempo for API calls, token consumption, or any quantifiable action. From subscription to settled invoice in USDC.

Usage-based billing lets you charge subscribers based on what they actually consume — no flat fees, no estimates. With Retempo, you define a unit price for each billable action (an API call, a generated token, a gigabyte processed), record usage events as subscribers interact with your service, and settle invoices in USDC at the end of each billing period. This guide walks you through the complete workflow, from configuring your plan to recording on-chain payment proof.

## Overview

The usage-based billing workflow in Retempo follows five stages:

1. **Create a service and a USAGE\_BASED plan** — define your unit price and billing interval.
2. **Subscriber checks out** — they complete a checkout session and a subscription is created.
3. **Record usage events** — your system posts an event each time the subscriber consumes a unit.
4. **Create a billing invoice** — at the end of the billing period, compute the total yourself and create an invoice with that amount.
5. **Settle the invoice** — submit a settlement to record on-chain USDC payment proof.

Each stage maps to a specific Retempo API endpoint, described in detail below.

## Workflow

<Steps>
  <Step title="Create a USAGE_BASED payment plan">
    Before subscribers can check out, you need a service with a usage-based plan attached. Create the plan by posting to `/api/v1/services/:serviceId/plans`. Set `pricingType` to `USAGE_BASED`, choose a `billingInterval`, and set `amount` to your unit price in USDC.

    In this example, the **AI Token API** charges `$0.000010` USDC per token generated:

    ```curl theme={null}
    curl --request POST \
      --url https://api.retempo.xyz/api/v1/services/svc_ai_token_api/plans \
      --header 'Authorization: Bearer <YOUR_API_KEY>' \
      --header 'Content-Type: application/json' \
      --data '{
        "pricingType": "USAGE_BASED",
        "billingInterval": "MONTH",
        "amount": "0.000010",
        "currency": "USDC",
        "name": "Pay-as-you-go",
        "description": "Billed monthly based on tokens generated"
      }'
    ```

    ```json theme={null}
    {
      "plan": {
        "id": "plan_3f9b2a1c",
        "serviceId": "svc_ai_token_api",
        "name": "Pay-as-you-go",
        "pricingType": "USAGE_BASED",
        "billingInterval": "MONTH",
        "amount": "0.000010",
        "currency": "USDC"
      }
    }
    ```

    <Tip>
      Set `amount` to the price per single unit of consumption. If you charge per 1,000 tokens, divide your price by 1,000 and store the per-token rate — this keeps your usage event quantities consistent with your plan's unit price.
    </Tip>
  </Step>

  <Step title="Subscriber checks out">
    When a subscriber is ready to activate, create a checkout session for them. On successful payment, Retempo automatically creates an **ACTIVE** subscription tied to the plan.

    ```curl theme={null}
    curl --request POST \
      --url https://api.retempo.xyz/api/v1/checkout-sessions \
      --header 'Authorization: Bearer <YOUR_API_KEY>' \
      --header 'Content-Type: application/json' \
      --data '{
        "serviceId": "svc_ai_token_api",
        "paymentPlanId": "plan_3f9b2a1c",
        "userId": "usr_b4e7f812"
      }'
    ```

    ```json theme={null}
    {
      "checkoutSession": {
        "id": "cs_8e1d4f7a",
        "url": "https://checkout.retempo.xyz/cs_8e1d4f7a",
        "status": "PENDING"
      }
    }
    ```

    Redirect your subscriber to the `url` returned in the response. Once they complete payment, Retempo creates the subscription and you receive a webhook notification. Store the resulting `subscriptionId` — you'll need it to record usage events.

    <Note>
      You can only record usage events against a subscription in `ACTIVE` status. Wait for the checkout webhook before you begin metering.
    </Note>
  </Step>

  <Step title="Record usage events">
    Each time the subscriber consumes a unit of your service, post a usage event to `/api/v1/usage-events`. Record events as they happen throughout the billing period — do not wait until billing time to report usage.

    Here's an example recording 50,000 tokens generated by subscriber `usr_b4e7f812`:

    ```curl theme={null}
    curl --request POST \
      --url https://api.retempo.xyz/api/v1/usage-events \
      --header 'Authorization: Bearer <YOUR_API_KEY>' \
      --header 'Content-Type: application/json' \
      --data '{
        "serviceId": "svc_ai_token_api",
        "subscriptionId": "sub_9f3a2c1d",
        "userId": "usr_b4e7f812",
        "eventKey": "token_generated",
        "quantity": 50000
      }'
    ```

    ```json theme={null}
    {
      "usageEvent": {
        "id": "ue_4d8c1e7b",
        "serviceId": "svc_ai_token_api",
        "subscriptionId": "sub_9f3a2c1d",
        "userId": "usr_b4e7f812",
        "invoiceId": null,
        "eventKey": "token_generated",
        "quantity": "50000",
        "occurredAt": "2025-01-15T14:32:00.000Z",
        "createdAt": "2025-01-15T14:32:01.847Z"
      }
    }
    ```

    Post as many usage events as needed across the billing period. Each event is stored independently, so you can record incremental bursts (e.g. 5,000 tokens per API response) rather than waiting for a large total to accumulate.

    <Tip>
      Use distinct `eventKey` values for each billable dimension of your service. If you bill for both tokens and API requests, record separate events with `token_generated` and `api_request` respectively. Each `subscriptionId` + `eventKey` combination must be unique.
    </Tip>
  </Step>

  <Step title="Create a billing invoice">
    At the end of the billing period, compute the total amount owed by summing the subscriber's usage events, then create an invoice with that amount.

    <Warning>
      Retempo stores the invoice amount you provide — it does **not** automatically sum usage events into an invoice amount. Compute the total from your own records or from the usage events you've posted, then pass the result as `amount`.
    </Warning>

    **Example calculation:**

    ```
    total_tokens   = 50,000 + 30,000 + 20,000  # = 100,000 tokens
    unit_price     = $0.000010 USDC per token
    invoice_amount = 100,000 × $0.000010        # = $1.00 USDC
    ```

    Post the computed amount to `/api/v1/invoices`. The `paymentPlanId` field is required and must reference the plan attached to this subscription:

    ```curl theme={null}
    curl --request POST \
      --url https://api.retempo.xyz/api/v1/invoices \
      --header 'Authorization: Bearer <YOUR_API_KEY>' \
      --header 'Content-Type: application/json' \
      --data '{
        "serviceId": "svc_ai_token_api",
        "paymentPlanId": "plan_3f9b2a1c",
        "subscriptionId": "sub_9f3a2c1d",
        "userId": "usr_b4e7f812",
        "amount": "1.00",
        "currency": "USDC"
      }'
    ```

    ```json theme={null}
    {
      "invoice": {
        "id": "inv_7c2a9e1f",
        "serviceId": "svc_ai_token_api",
        "subscriptionId": "sub_9f3a2c1d",
        "userId": "usr_b4e7f812",
        "amount": "1.00",
        "currency": "USDC",
        "status": "DRAFT"
      }
    }
    ```
  </Step>

  <Step title="Settle the invoice">
    Once the subscriber pays, submit a settlement to record the on-chain USDC payment proof against the invoice. The `referenceHash` is the bytes32 identifier for the on-chain settlement record. You must also supply wallet addresses for the payer and merchant:

    ```curl theme={null}
    curl --request POST \
      --url https://api.retempo.xyz/api/v1/settlements \
      --header 'Authorization: Bearer <YOUR_API_KEY>' \
      --header 'Content-Type: application/json' \
      --data '{
        "invoiceId": "inv_7c2a9e1f",
        "referenceHash": "0xabc123def456abc123def456abc123def456abc123def456abc123def456abcd",
        "payerAddress": "0xPayerWalletAddress",
        "merchantAddress": "0xMerchantWalletAddress",
        "amount": "1.00",
        "currency": "USDC"
      }'
    ```

    ```json theme={null}
    {
      "settlement": {
        "id": "stl_2e8f1b9c",
        "invoiceId": "inv_7c2a9e1f",
        "referenceHash": "0xabc123def456abc123def456abc123def456abc123def456abc123def456abcd",
        "transactionHash": "0x7f9e2c1a...",
        "amount": "1.00",
        "currency": "USDC",
        "status": "CONFIRMED",
        "recordedAt": "2025-02-01T09:15:33.000Z"
      },
      "chain": {
        "eventObserved": true,
        "receiptStatus": "success",
        "transactionHash": "0x7f9e2c1a..."
      }
    }
    ```

    After a successful settlement, the settlement status is `CONFIRMED` and the invoice status updates to `PAID`. The on-chain `transactionHash` is stored as an immutable record. Your subscriber's payment is now fully accounted for.
  </Step>
</Steps>

## Billing period management

Because USAGE\_BASED plans bill at the end of a period rather than at checkout time, you are responsible for tracking per-period usage and triggering invoice creation at the right moment.

A reliable approach for monthly billing:

1. **Track period boundaries.** Store the subscription's `currentPeriodStart` and `currentPeriodEnd` dates when the subscription is created (or renewed). These define the window for which you will bill.

2. **Aggregate usage within the period.** Sum the `quantity` values from all usage events recorded between `periodStart` and `periodEnd` for each `eventKey`. Keep a running total in your own database so you can query it efficiently at billing time without re-fetching all events.

3. **Create the invoice at period end.** When `currentPeriodEnd` arrives, compute the final total and post an invoice as shown in Step 4 above. Pass the correct `paymentPlanId` so the invoice is associated with the right plan.

4. **Settle immediately after payment.** Once the subscriber's USDC transfer confirms on-chain, post the settlement (Step 5). Retempo stores the `referenceHash` and `transactionHash` as immutable proof.

5. **Reset for the next period.** After settling, reset your running aggregate counters for the new period starting at `currentPeriodEnd + 1`.

<Tip>
  Store your own aggregate counts for the billing period. Use Retempo invoices to record the final billed amount at end-of-period.
</Tip>

<Info>
  If a subscriber cancels mid-period, pro-rate their invoice based on the number of days they were active, or bill for actual usage only — whichever matches your service terms. Retempo's `amount` field accepts any value you compute.
</Info>
