How credits work
Usage of Kardinal’s Route Optimization API is billed in credits. Every new account starts with 1,000 free credits. Three requests can consume credits:POST /plans (creating a plan), PUT /plans/{planId} (updating one), and PUT /plans/{planId}/running with the body true (restarting its optimization). The billed metric is the number of unique stops optimized per plan, at a 1:1 ratio — one unique stop optimized costs one credit. Plans submitted with a sandbox token don’t consume any credits, so run your smoke, schema, and modeling tests in the sandbox — but routes there are always computed crow-fly and optimization is capped at 5 seconds, so judge optimization quality on a real plan in production (see Moving from sandbox to production).
A restart is billed like an update, by the same 24-hour rule (see below). It also counts as one optimization against your agency’s daily and monthly optimization quota (see Limits and quotas).
A stop counts as the same unique stop across requests as long as it stays in the same plan, keeps the same id, and moves by no more than about 11 metres (its latitude and longitude, rounded to 4 decimals, don’t change). Changing its id, moving it further, or submitting it in another plan (a new POST /plans) makes it a new unique stop, billed again.
Everything else can change freely without consuming credits, as long as stops stay unchanged in that sense: resources, constraints, time windows, capacities, objectives, and so on. Re-optimizing a plan after a delay, a breakdown, or a new constraint therefore costs nothing extra. A PUT whose body is identical to the stored plan consumes nothing at all: the plan isn’t re-optimized and its version doesn’t change. The exception is an archived plan updated with ?force=true: it always creates a new version and re-optimizes the plan, even if its content is identical, so every stop is billed again, as for any update or restart made more than 24 hours after the plan’s creation. A forced restart of an archived plan bills every stop again too. See Limits and quotas.
Unique stops are counted per 24-hour period, starting from the plan’s creation. Within one period, an unchanged stop is billed once, however many times the plan is updated or restarted. Once 24 hours have passed since the plan was created, the next update (PUT /plans/{planId}) or restart (PUT /plans/{planId}/running) bills every stop in the plan again, then again at 48 hours, and so on.
Buying credits
Additional credit packs are available directly from the Console — no sales conversation required. Credits never expire and are never refunded once purchased.Buy credits in the Console
Buy credit packs and set an automatic repurchase rule.
Insufficient credits
When aPOST /plans, a PUT /plans/{planId}, or a restart with PUT /plans/{planId}/running is submitted, the API checks that your balance covers the credits it would consume. If the balance would drop below zero, the whole request is rejected with a 403 and code: NOT_ALLOWED: the plan isn’t created, updated, or restarted, and nothing is optimized. The error’s properties.details reads Insufficient credits, and properties.remaining gives your current balance:
GET and DELETE requests, and an update or a restart that keeps the plan’s unique stops unchanged within the current 24-hour period.
This only concerns production, since the sandbox doesn’t consume credits. To avoid it, set up the automatic repurchase rule described earlier. See Limits and quotas for the other causes of a 403.
See also
- Limits and quotas — rate limits and other usage caps, a separate mechanism from credit consumption.
- Authentication and API keys — obtaining your API token.

