Best practices
Combine webhooks with scheduled Pull API syncs, upsert by transaction id, and re-query recent ranges to detect voided transactions.
The most reliable integration uses webhooks for speed and a scheduled Pull API sync for completeness, with everything keyed on the transaction id. The sections below cover the details that catch people out.
Combine webhooks and the Pull API
Use webhooks for near-real-time updates and the Pull API for reconciliation. Neither channel alone covers every case:
| Need | Channel |
|---|---|
| Know about a new transaction within seconds | Webhook |
| Backfill history, or the period before the webhook URL was set | Pull API |
| Recover after your endpoint was down or the webhook was disabled | Pull API |
| Detect transactions voided or canceled after delivery | Pull API |
| Monthly statement reconciliation | Pull API |
A common design: process webhooks as they arrive, and run a scheduled Pull sync (for example every 15 minutes over the last 2 hours, and nightly over the last 7 days) that upserts by transaction id.
How do I detect voids and cancellations?
Neither the Pull API nor webhooks report VOID or CANCELED transactions. A transaction that is voided after you received it disappears from Pull API results for its date range.
To detect this, periodically re-query recent ranges and compare with what you have stored:
- Fetch all transactions for the last N days (7 is a reasonable default; extend it if your disputes take longer to resolve).
- Any transaction you hold with
created_atin that range that is absent from the response has been voided or canceled. Mark it accordingly. - Refunds for duplicates, variances and disputes arrive as new
CONFIRMEDtransactions withcorrection_reference_idset. Link them to the original.
Upsert by transaction id
Treat id as the primary key of a transaction on your side. Both channels return the same record for the same id, so an upsert lets you receive an event first and the Pull result later (or the reverse) without conflicts.
Store amounts precisely
- Store
fees.total_amountwith 6 decimal places. It matches your balance deduction exactly and is the figure to reconcile against Octane statements. - Store other amounts with at least 2 decimal places. Use a decimal type, not a floating-point one.
Handle images promptly
Image URLs expire after 1 hour (Pull) or 24 hours (webhooks). If you need the photos, download them when you receive the record and store them yourself. Never persist the URL.
Be tolerant of new fields
New fields may be added to the transaction object and the webhook envelope at any time. Ignore fields you do not recognise, and do not fail on them.
Respect the rate limit
- Page with
limit=100. - Back off on
429usingRetry-After. - Run one sync worker per key.
Secure your credentials
- Keep the API key and webhook secret in a secrets manager. Never commit them.
- Send requests only from the IPs on your allow-list; tell Octane before your egress IPs change.
- Verify every webhook signature and reject stale timestamps.
- If you suspect a key or secret is compromised, contact Octane immediately. The key will be switched off and a new one issued.
Plan for access expiry
Watch the X-Access-Expires-At response header. Renew your charging profile with Octane before that date to avoid 403 NO_ACTIVE_CHARGING_PROFILE and a pause in webhook deliveries.
Support
When contacting Octane support, include:
- Your key prefix (never the full key)
- The
request_idfrom the error response, if present - The delivery
idfor webhook issues - Timestamps in UTC


