Skip to content

Preflight And Usage Logging

Preflight checks decide whether a provider call should proceed. Usage logging records what happened after the provider call.

Example: Preflight Then Log

curl "$SPENDWARE_BASE_URL/api/v1/usage/preflight-with-key" \
  -H "Content-Type: application/json" \
  -d '{"key":"SPENDWARE_CUSTOMER_KEY","service_provider_name":"openai","service_name":"gpt-4o","input_tokens":120,"output_tokens":45,"cached_tokens":30}'

curl "$SPENDWARE_BASE_URL/api/v1/usage/log-with-key" \
  -H "Content-Type: application/json" \
  -d '{"key":"SPENDWARE_CUSTOMER_KEY","service_provider_name":"openai","service_name":"gpt-4o","number_requests":1,"input_tokens":120,"output_tokens":45,"cached_tokens":30}'
from spendware_provider_sdk.management import SpendwareManagementClient

client = SpendwareManagementClient(base_url="SPENDWARE_BASE_URL", api_key="SPENDWARE_CUSTOMER_KEY")
client.usage.preflight_with_key({
    "key": "SPENDWARE_CUSTOMER_KEY",
    "service_provider_name": "openai",
    "service_name": "gpt-4o",
    "input_tokens": 120,
    "output_tokens": 45,
    "cached_tokens": 30,
})
client.usage.log_with_key({
    "key": "SPENDWARE_CUSTOMER_KEY",
    "service_provider_name": "openai",
    "service_name": "gpt-4o",
    "number_requests": 1,
    "input_tokens": 120,
    "output_tokens": 45,
    "cached_tokens": 30,
})
client.close()
import { SpendwareManagementClient } from "@spendware/provider-adapters-sdk/management";

const client = new SpendwareManagementClient({ baseUrl: "SPENDWARE_BASE_URL", apiKey: "SPENDWARE_CUSTOMER_KEY" });
await client.usage.preflightWithKey({
  key: "SPENDWARE_CUSTOMER_KEY",
  service_provider_name: "openai",
  service_name: "gpt-4o",
  input_tokens: 120,
  output_tokens: 45,
  cached_tokens: 30,
});
await client.usage.logWithKey({
  key: "SPENDWARE_CUSTOMER_KEY",
  service_provider_name: "openai",
  service_name: "gpt-4o",
  number_requests: 1,
  input_tokens: 120,
  output_tokens: 45,
  cached_tokens: 30,
});

Modes

  • Strict mode should block provider calls when policy checks fail.
  • Best-effort mode should favor provider availability when Spendware is temporarily unavailable.
  • Disabled and dry-run modes are useful during local development.

Partial Logging

Use partial usage logging when a user-key import must accept usage before the project, customer, or provider record exists. Customer-key runtime logging should continue to use log-with-key because the customer key already carries runtime customer context.

Common Errors

  • Write-side counts must be raw, not scaled presentation values.
  • cached_tokens is required and must be provided alongside input_tokens and output_tokens. total_tokens is input_tokens + output_tokens + cached_tokens.
  • Customer keys need preflight:read and usage:write for both calls.
  • Reused idempotency keys should use the same payload.