ClocknextHelp
DocumentationAPI ReferenceMCP Tools
Dashboard

Get started

OverviewQuickstart

Good to know

Response formatHandling errorsPaginating resultsSending data reliablyYour own customer idsWebhooks

API reference

Record credit POSTRecord outcome POSTComplete outcome POSTRecord wallet POSTRecord unit POSTComplete composite POST
List customers GETCreate a customer POSTGet a customer GETUpdate a customer PATCHDelete a customer DELETEGet a customer's balances GETGet a customer's wallet ledger GETSet a customer's low-balance alert PUTGet a customer's current plan GETChange a recurring grant PUTList Customer Usage Log GETLook Up Usage Logs by ID GET
Manage a customer's credit balance POSTManage a customer's outcome balance POSTManage a customer's unit balance POSTManage a customer's composite balance POSTManage a customer's wallet balance POST
List a customer's members GETAdd a member POSTUpdate a member PATCHRemove a member DELETE
PlansCreditsOutcomesUnitsComposites
List taxes GETCreate a tax POSTGet a tax GETUpdate a tax PATCH
List purchases GETCreate a purchase POSTGet a purchase GETUpdate a purchase's auto-payment setting PATCHCancel a purchase POST
List invoices GETGet an invoice GETMint a hosted pay link GET
List payments GETGet a payment GET
wallet.balance.update POSTwallet.balance.drop POST
Mint a customer-portal access token POST

API Reference

Quickstart

Create a customer, package a Plan, and record your first usage signal — start to finish.

This guide takes you from an API key to a priced usage signal in seven steps — two of them in the dashboard, since entitlements and Plans aren't available over the API yet. Every other step shows both cURL and Node.js.

You'll need

An API key (cnk_…) from Settings → API Keys. Keep it in an environment variable — the samples below read $CLOCKNEXT_API_KEY. The Node.js tabs use the official @clocknext/sdk client (cnk); install it with npm install @clocknext/sdk.

Set your key

Export your key so every request can read it. Never hard-code it in source you commit.

export CLOCKNEXT_API_KEY="cnk_your_key_here"

Create a customer

A customer is who you bill. Only name and email are required — everything else is an optional profile field you can also fill in later. Here we send the full profile so invoices render complete from day one.

curl https://payments.clocknext.com/api/v1/customers \
  -H "Authorization: Bearer $CLOCKNEXT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Inc",
    "email": "ops@acme.com",
    "description": "AI meeting-notes startup — growth tier",
    "website": "https://acme.com",
    "phone": "+1 415 555 0100",
    "legalName": "Acme Incorporated",
    "addressLine1": "500 Market Street",
    "city": "San Francisco",
    "state": "CA",
    "country": "United States",
    "pincode": "94105",
    "taxId": "US-EIN 12-3456789",
    "currencyCode": "USD"
  }'
import { ClockNext } from "@clocknext/sdk";

const cnk = new ClockNext({ apiKey: process.env.CLOCKNEXT_API_KEY! });

const customer = await cnk.customers.create({
  name: "Acme Inc",
  email: "ops@acme.com",
  description: "AI meeting-notes startup — growth tier",
  website: "https://acme.com",
  phone: "+1 415 555 0100",
  legalName: "Acme Incorporated",
  addressLine1: "500 Market Street",
  city: "San Francisco",
  state: "CA",
  country: "United States",
  pincode: "94105",
  taxId: "US-EIN 12-3456789",
  currencyCode: "USD",
});
const customerId = customer.id; // e.g. "cus_abc123"

Grab the new customer's id — you'll reference it as customerId everywhere else. The SDK returns it directly; the raw response wraps it in the envelope's result.

Create an entitlement

Define what the customer is allowed to consume. Entitlements aren't available over the API yet — create at least one in the dashboard:

  • Credits for token-tracked features
  • Outcomes for work billed by result, step by step
  • Units for simple counted items
  • Composite to combine entitlements into one meter
  • Or skip this and bill straight against the customer's Wallet

Every type has a stable agentKey except Wallet. If you create a Credit, Outcome, Unit, or Composite, note its agentKey — you'll pass it on your usage signal. See Decide what they can consume for the full walkthrough.

Package it into a Plan

Bundle the entitlement(s) from the previous step into a Plan — the thing you actually sell — in Plans → New Plan. For each component, choose whether it's billed in advance or in arrears. Note the Plan's id (e.g. plan_growth) for the next step. See Package it as a Plan for the full walkthrough.

Purchase the plan for the customer

Put the customer on the Plan you just created. Only customerId and planId are required. The Plan itself must be active — purchasing an inactive one returns 400.

curl https://payments.clocknext.com/api/v1/purchases \
  -H "Authorization: Bearer $CLOCKNEXT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cus_abc123",
    "planId": "plan_growth"
  }'
const purchase = await cnk.purchases.create({
  customerId: "cus_abc123",
  planId: "plan_growth",
});

This starts the customer's billing cycle and charges any up-front components immediately. The customer now has an active Plan — the last prerequisite before a signal can be recorded. See Create a purchase for the full parameter list.

Record a usage signal

Meter one LLM request against that customer, now that it's on an active Plan. Each meter type has its own route under /signal/* — pick the one that matches the entitlement you created. The route decides the meter, so there is no type field in the body. customerId is always required; everything else depends on the type.

Debits the customer's USD wallet at the model's provider cost — no agentKey needed.

curl -X POST https://payments.clocknext.com/api/v1/signal/wallet \
  -H "Authorization: Bearer $CLOCKNEXT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cus_abc123",
    "member": "dana@acme.com",
    "usage": {
      "model": "gpt-4o",
      "inputTokens": 1200,
      "outputTokens": 350,
      "cacheTokens": 200,
      "cacheWriteTokens": 0
    },
    "custom": { "feature": "chat", "region": "eu" }
  }'
await cnk.signals.wallet({
  customerId: "cus_abc123",
  model: "gpt-4o",
  tokens: { input: 1200, output: 350, cache: 200, cacheWrite: 0 },
  member: "dana@acme.com",
  custom: { feature: "chat", region: "eu" },
});

Draws down a named Credit's balance, addressed by its stable agentKey.

curl -X POST https://payments.clocknext.com/api/v1/signal/credit \
  -H "Authorization: Bearer $CLOCKNEXT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cus_abc123",
    "agentKey": "deep-research",
    "member": "dana@acme.com",
    "usage": {
      "model": "gpt-4o",
      "inputTokens": 1200,
      "outputTokens": 350,
      "cacheTokens": 200,
      "cacheWriteTokens": 0
    }
  }'
await cnk.signals.credit({
  customerId: "cus_abc123",
  model: "gpt-4o",
  agentKey: "deep-research", // the Credit's agent key
  member: "dana@acme.com",
  tokens: { input: 1200, output: 350, cache: 200, cacheWrite: 0 },
});

Bills per run, not per step. Every signal of one run shares a runId. Recording a step never bills — closing the run is its own separate call, and that call is what bills it. See Complete outcome.

# Record a step. Every step of one run shares the same runId.
curl -X POST https://payments.clocknext.com/api/v1/signal/outcome \
  -H "Authorization: Bearer $CLOCKNEXT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cus_abc123",
    "agentKey": "resolved_ticket.resolve",
    "runId": "ticket_9021",
    "usage": { "model": "gpt-4o", "inputTokens": 500, "outputTokens": 200 }
  }'

# Close and bill the run — a separate request.
curl -X POST https://payments.clocknext.com/api/v1/signal/outcome/complete \
  -H "Authorization: Bearer $CLOCKNEXT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "customerId": "cus_abc123", "runId": "ticket_9021" }'
await cnk.signals.outcome({
  customerId: "cus_abc123",
  model: "gpt-4o",
  agentKey: "resolved_ticket.resolve", // the OutcomeStep's key
  runId: "ticket_9021",
  tokens: { input: 500, output: 200 },
});

// Closing the run is a separate, dedicated call — never a flag on a step.
await cnk.signals.completeOutcome({
  customerId: "cus_abc123",
  runId: "ticket_9021",
});

Units are fixed-price meters with no model and no tokens, so there is no usage block and a caller can never post a price. quantity defaults to 1.

curl -X POST https://payments.clocknext.com/api/v1/signal/unit \
  -H "Authorization: Bearer $CLOCKNEXT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cus_abc123",
    "agentKey": "seats",
    "member": "dana@acme.com"
  }'
await cnk.signals.unit({
  customerId: "cus_abc123",
  agentKey: "seats", // the unit's agent key
  member: "dana@acme.com",
});

The platform prices the request server-side from the model's (or unit's) live rates. Every signal is first written to a durable inbox, so the response is usually 202 with a rawId and the price is worked out a moment later. See Reliability for what that means for your code.

Read it back

Confirm the signal landed on the Signals page in the dashboard — or read the customer's balances back over the API/SDK:

curl https://payments.clocknext.com/api/v1/customers/cus_abc123/balances \
  -H "Authorization: Bearer $CLOCKNEXT_API_KEY"
const balances = await cnk.customers.balances("cus_abc123");

balances returns the customer's wallet, credit, outcome, and unit balances under their current Plan. See Get a customer's balances for the full shape.

What just happened

You authenticated with a bearer key, created a billing identity, gave it something to consume and a Plan to buy it on, purchased that Plan, metered one request against it, and read the result back — all through the same base URL and the same response envelope.

Next steps

Meter by credit or outcome

Bill against a named credit balance or an outcome step instead of the wallet.

How Plans and entitlements work

The full conceptual walkthrough — entitlements, Plans, Purchases, and Signals.

Embed the customer portal

Mint a short-lived token so customers can see their own balances.

Overview

The Clocknext Payments API and Node.js SDK — meter LLM usage, manage customers and plans.

Response format

Every endpoint — success or error — returns the same predictable envelope. Here's the contract.

On this page

Set your keyCreate a customerCreate an entitlementPackage it into a PlanPurchase the plan for the customerRecord a usage signalRead it backWhat just happenedNext steps