Browse documentation

Messaging

Usage records

Reconcile Developer Platform activity with estimates, finalized charges, and zero-cost Test Mode records.

DevelopersAdvancedAvailable

What this guide covers

  • Join usage records to messages with public IDs.
  • Distinguish reserved, released, finalized, and reconciliation-needed usage.
  • Keep USD amounts as decimal strings until they reach a decimal-safe money type.

List usage records

GET /v1/usage requires usage:read. It returns Developer Platform usage records restricted to the key's Yanola Account, Agent Project, environment, and allowed Senders.

Usage records show what each accepted message cost in Yanola fees. A Live Mode API or SDK send is included in the Plan, so its record is finalized at 0.000000 and spends no Yanola Balance. Usage records are not the current Balance ledger or subscription entitlement state.

List finalized usage
ts
import { WhatsAppClient } from "@yanola/whatsapp"

const apiKey = process.env.YANOLA_API_KEY

if (!apiKey) {
  throw new Error("Missing YANOLA_API_KEY")
}

const yanola = new WhatsAppClient({ apiKey })

const usage = await yanola.usage.list({
  status: "finalized",
  from: "+15557654321",
  createdAfter: "2026-07-01T00:00:00.000Z",
  createdBefore: "2026-08-01T00:00:00.000Z",
  limit: 100,
})

for (const record of usage.data) {
  console.log(record.messageId, record.totalAmount)
}

Usage lifecycle

Usage status values
StatusMeaningtotalAmount
reservedAn amount is held while the final charge is unresolved. Included API and SDK sends never use this status.0.00 until finalized
releasedThe reservation was released without a finalized charge.0.00
finalizedThe record is settled. Included API and SDK sends are finalized when accepted.0.000000 on an included send
needs_reconciliationYanola could not safely determine the final charge yet.0.00 until reconciled

Amounts are decimal USD strings

All monetary values are strings so JavaScript does not introduce binary floating-point rounding. currency is always USD in the v1 contract.

Add decimal strings without Number rounding
ts
function toMicros(amount: string): bigint {
  const [whole, fraction = ""] = amount.split(".")
  return BigInt(whole) * 1_000_000n +
    BigInt(fraction.padEnd(6, "0"))
}

const totalMicros = usage.data.reduce(
  (sum, record) => sum + toMicros(record.totalAmount),
  0n
)
Usage amount fields
FieldMeaning
estimatedAmountAmount estimated or reserved when the message was accepted.
providerAmountnull on an included send: Meta bills your WhatsApp Business Account directly and Yanola charges no Meta Fee.
yanolaFeenull on an included send: API and SDK sends carry no Yanola fee.
totalAmountAmount deducted from Yanola Balance; 0.000000 on an included send, and zero for reserved, released, and needs_reconciliation records.

Correlate pricing with a message

Usage identity and pricing context
FieldMeaning
idOpaque usg_ usage record ID.
reservationIdOptional resv_ identity for the original Live Mode reservation.
messageIdRelated msg_ or msg_test_ public message ID when available.
fromE.164 Sender associated with the activity.
providerCategoryProvider message category captured in the pricing record.
marketProvider pricing market captured by the latest snapshot.
createdAt / finalizedAtCreation time and optional finalization time.

Filter and paginate

Filter by from, status, category, createdAfter, or createdBefore. REST uses created_after and created_before; the SDK maps the camel-case parameters for you.

Usage lists default to 20 and accept at most 100. Continue with pagination.nextCursor while pagination.hasMore is true. Cursors are opaque and bound to the key, environment, and filters.

Interpret usage safely

  1. Expect totalAmount 0.000000 on included API and SDK sends; they count against the Message Cap, not the Balance.
  2. Keep reserved and needs_reconciliation records visible in operational reports instead of treating them as free activity.
  3. Use messageId to join a usage record to message state; do not infer delivery from usage status.
  4. Use Balance and billing views for current funds, top-ups, invoices, and adjustments.

Usage errors

Common usage list errors
Status and codeMeaningAction
400 invalid_usage_list_queryA filter, time range, limit, or cursor is invalid.Correct the query or restart pagination.
400 environment_mismatchThe query environment differs from the key.Use the key's environment.
403 insufficient_scopeThe key lacks usage:read.Use a key with usage access.
429 rate_limit_exceededThe current read window is exhausted.Honor Retry-After and reduce overlapping scans.