check sits in front of every metered action in your product. If Ledger can’t answer it, the SDKs fail open: the check is allowed and the usage is queued for later, so an outage on our side never stops your customers. Business answers, such as an insufficient balance or an unknown customer, are never failed open.
Fail open is on by default in the TypeScript and Python SDKs, for checkCredits / check_credits and trackUsage / track_usage only. Every other method throws as usual. Calling the API directly, for example with cURL, does none of this.
When it fails open
These are still thrown, exactly as without fail open:
400 invalid_request,401 unauthorized,404 customer_not_foundand404 feature_not_found.- Track’s
409 insufficient_credits,409 overage_cap_reachedand409 request_id_conflict. - A
429after a401, so a wrong API key is never hidden. - Your own aborted request.
allowed: false stays allowed: false.
What you get back
Every result from these two methods hasfailedOpen. When it is true, the result also has a reason, and the numbers Ledger would have sent are null because they are unknown.
Usage is replayed, not lost
A track that fails open is kept in memory and sent again in the background with the samerequest_id, so it is charged once however many times it is sent (Record usage). Retries start after a second and back off to every 30 seconds while Ledger stays down.
Replayed usage is charged at the balance when it lands. It is dropped, and reported to your callback, when:
- Ledger answers it with a business error, such as
409 insufficient_creditsbecause the balance ran out meanwhile (rejected); - it is still queued an hour later (
expired); - the client already holds 1,000 queued usages (
queue_full).
Logging fail-open events
By default the SDKs write a short warning, at most every 10 seconds for each kind of event:console.warn in TypeScript, the integrateledger logger in Python. Pass a callback to send events to your own logging or alerting:
Events carry the customer, feature and request IDs, the
reason or cause, and the SDK error. A callback that throws is ignored.
Settings
failOpen: false (Python fail_open=False) turns it off: both methods throw on an outage, as before.