Costs and credits
Understand prediction costs and read the available balance.
What is billed
Only predictions and forecasts consume credits. Training, evaluation, backtesting, reported outcomes, model refreshes, archiving, restoring and reads are free.
| Operation | Cost |
|---|---|
POST /v1/models, training | 0 credits |
POST /v1/datasets/evaluate | 0 credits |
POST /v1/models/{id}/predict | Scored rows × the model engine's credits per row |
POST /v1/forecast | horizon × the serving engine's credits, per call, all series included |
POST /v1/forecast/backtest | 0 credits |
POST /v1/models/{id}/outcomes | 0 credits |
POST /v1/models/{id}/refresh | 0 credits |
| Reads | 0 credits |
For forecasting, horizon is the number of future steps requested for each
series. On an engine charging one credit, one series with 56 historical
observations and a horizon of 7 costs 7 credits. Five series with that horizon in one call also cost 7 credits,
while producing 35 forecast values. Five separate calls at horizon 7 cost
35 credits in total. Historical input rows and returned quantiles do not
multiply the charge.
Use item_id to identify separate series (itemId in JavaScript).
For model predictions, read GET /v1/engines for the credits per row of the
engine serving your model. A prediction does not necessarily cost one credit.
Read the available balance
GET /v1/usage returns predictions_remaining: the remaining monthly allowance
plus the credit balance, counted in credits. The monthly allowance is used
first, followed by the credit balance. The Free plan uses signup credits and
has no monthly allowance.
Despite its name, this number counts credits, not rows: on an engine charging two credits per row, it scores half as many rows.
usage = spavik.usage()
print(usage["predictions_remaining"])Billable responses can include X-Spavik-Predictions-Remaining, the same
number after the call. The SDKs expose it as result.predictions_remaining in
Python and result.predictionsRemaining in JavaScript. The header can be
absent, including on a cached idempotent replay, so None or null means
unknown, never unlimited. The API does not return the amount charged: the SDK's
result.cost is 0 for a free operation and None or null for a billed one.
Balance responses are snapshots, and usage reports may be cached. Other calls can consume credits between reading a balance and submitting your next request.
When usage returns null
In a successful GET /v1/usage response, unlimited_usage: true and an
explicit predictions_remaining: null denote an account without an enforced
prediction credit limit. The current API applies this behavior to Enterprise accounts.
It does not remove model, input-size or other technical limits.
This meaning is specific to that field and response. A missing field or header
means availability is unknown. included_units_per_month: null does not imply
unlimited usage: the Free plan also has no monthly allowance and spends its
finite credit balance.
When the balance runs out
If available credits cannot cover an operation, the API returns
402 CREDITS_EXHAUSTED. These examples make a billable prediction and handle insufficient credits.
Use model and rows from your application, or set MODEL_ID and prepare
rows.json for REST. Inspect the error code and human-readable detail;
the current API does not provide separate numeric balance and required
fields in this error.
from spavik import SpavikCreditsExhausted
try:
model.predict(rows)
except SpavikCreditsExhausted as exc:
print(exc.code, exc.detail, exc.request_id)Retry with idempotency
Send a unique Idempotency-Key on the original billable request and reuse it
with the same endpoint and payload for retries. A stored successful response
is replayed without another computation or charge while its record is retained.
The default retention is 24 hours from the original request. After expiration,
the same key can execute and charge again.
The SDKs generate a key per call and keep it during their automatic retries.
Calling predict or forecast again creates a new logical request with a new
key. It is not a replay of the previous SDK call.
| Response | What to do |
|---|---|
REQUEST_IN_PROGRESS | Wait as directed by Retry-After; retain the original key and payload. |
IDEMPOTENCY_KEY_REUSED | The key was used with different input. Check the original request. |
REQUEST_INTERRUPTED | The outcome is uncertain. Stop automatic retries and inspect the request log or contact support. |
IDEMPOTENCY_RESPONSE_UNAVAILABLE | The operation may have completed but its response could not be saved. Contact support with X-Spavik-Request-Id. |
Do not create a new key to force execution after an uncertain outcome. An error or lost response does not prove that no charge occurred. Idempotency is protection for retries under these conditions, not a permanent guarantee against duplicate charges. See API conventions.
How is this guide?
Last updated on