Record Signals
Records exactly one Signal — a single metered request against a wallet, credit or outcome meter.
Authorization
apiKey Per-organisation API key from Settings → API Keys, sent as Authorization: Bearer cnk_…. Missing, unknown or expired keys return 401.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Pricing-metric tag ( credit / outcome / unit ). A pricing metric is addressed by its refId as a property name on this body — send { "voice_ai": "call_5f3a" } to tag the voice_ai metric with your correlation value. Reporting only: it never changes what is billed, never fails the signal, and is ignored on wallet signals or when the name matches no live metric.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/usage" \ -H "Content-Type: application/json" \ -d '{ "customerId": "cus_abc123", "type": "credit", "agentKey": "credit.research", "member": "dana@acme.com", "model": "openai/gpt-4o", "inputTokens": 1200, "outputTokens": 350, "cacheTokens": 200, "custom": { "feature": "chat", "region": "eu" } }'{ "statusCode": 200, "statusDetail": { "status": "SUCCESS", "message": "OK" }, "result": { "usageLog": { "id": "log_8m3n5p", "customerId": "cus_abc123", "modelName": "gpt-4o", "creditName": "Deep Research", "member": "dana@acme.com", "inputTokens": 1200, "outputTokens": 350, "cacheTokens": 200, "credit": 2, "providedCost": 0.0087, "customerCost": 0.012, "status": "SUCCESS", "appliedRules": [ { "ruleId": "rule_7q2w4e", "ruleName": "EU region uplift", "creditsApplied": 2 } ], "outcome": null, "balance": { "dimension": "credit", "remaining": 18, "name": "Deep Research" }, "createdAt": "2026-07-21T14:03:22.000Z" } }}{ "statusCode": 200, "statusDetail": { "status": "SUCCESS", "message": "OK" }, "result": { "queued": true, "messageId": "msg_2f4a1b8c" }}{ "statusCode": 400, "statusDetail": { "status": "ERROR", "message": "Request body must be valid JSON." }, "result": {}}{ "statusCode": 401, "statusDetail": { "status": "ERROR", "message": "Invalid API key." }, "result": {}}{ "statusCode": 404, "statusDetail": { "status": "ERROR", "message": "No customer with id \"cus_abc123\"." }, "result": {}}{ "statusCode": 422, "statusDetail": { "status": "ERROR", "message": "No credit with agent key \"summarize\" exists in this workspace." }, "result": {}}{ "statusCode": 500, "statusDetail": { "status": "ERROR", "message": "Could not complete the request." }, "result": {}}Async, flushing & reliability
How the SDK sends signals — buffered by default, with retries, idempotency, and the flush() you must call before a serverless function exits.
Record usage logs POST
Records one usage log against a catalogue unit, addressed by its stable `agentKey`. Units are fixed-price meters with no tokens — the price comes from the unit's catalogue configuration, so a caller can never post a price.