QannasAPI

Read the credit headers: audit every charge from the response

What you'll build: a thin client wrapper that logs what each call cost and what you have left, so your own logs become the billing audit trail.

SectionAPI fundamentals
Actions usedPOST /v1/data/contacts/verify-email
Credits1 (worst case)
Test-key safeYes — runs on qk_test_ for zero credits
Time to complete~5 min
PrerequisitesA key and any HTTP client that lets you read response headers.

Three headers on every data call

X-Credits-Charged is what this call cost. X-Credits-Balance is what remains afterwards. X-Price-Book identifies the price book the charge was computed against, so a quote and a charge can always be traced to the same rules.

headers.sh
curl -i -X POST https://api.qannasapi.com/v1/data/contacts/verify-email \
  -H "Authorization: Bearer $QANNAS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "jane@acme.example"}'

# < HTTP/1.1 200 OK
# < X-Credits-Charged: 1      # what this call cost
# < X-Credits-Balance: 94     # what is left afterwards
# < X-Price-Book: public    # which rules were applied

Log the charge, not the estimate

Wrap your HTTP client once and record the three headers alongside request_id. That gives you per-call cost attribution without polling a usage endpoint, and request_id is what support will ask for if a charge ever looks wrong.

metered_client.ts
export async function call(action: string, body: unknown) {
  const res = await fetch(`${API}/v1/data/${action}`, {
    method: "POST",
    headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });

  const json = await res.json();
  // Your logs become the billing audit trail.
  logger.info("qannas.call", {
    action,
    request_id: json.request_id,
    charged: Number(res.headers.get("X-Credits-Charged")),
    balance: Number(res.headers.get("X-Credits-Balance")),
  });

  return json;
}

Watch the balance, not the clock

Because the balance comes back on every call, you can throttle or alert on the response you already have. There is no separate quota endpoint to poll and no lag between spending and knowing.

throttle.ts
// The balance arrives on the call you already made —
// there is no quota endpoint to poll and no lag.
const balance = Number(res.headers.get("X-Credits-Balance"));
if (balance < LOW_WATER_MARK) {
  pauseNonUrgentJobs();
  alertOps(`credits low: ${balance}`);
}

Summary

PatternHow
What this call costX-Credits-Charged
What is leftX-Credits-Balance
Which rules appliedX-Price-Book
Trace a chargerequest_id in the response body
ThrottleAlert on X-Credits-Balance from the call you just made

Production checklist

  • Log X-Credits-Charged, X-Credits-Balance and request_id on every call.
  • Alert on the balance header rather than polling a usage endpoint.
  • Keep request_id — it is how a specific charge gets traced.
  • Expect X-Credits-Charged: 0 on a miss and do not treat it as a failure.

Next steps

Run the estimate first. It costs nothing and it is the same arithmetic the meter will apply.