Klarety

Errors

What an error looks like, how the SDK raises it, and when to retry.

For devs

Every failed API call returns the same JSON shape and a standard HTTP status. The turns each into a Python exception, so your code handles a meaning, not a number.

The error body

Errors follow RFC 9457 and are sent as application/problem+json:

{
  "type": "https://klarety.ai/problems/too-many-requests",
  "title": "Too many requests",
  "status": 429,
  "detail": "slow down and retry in 12s",
  "instance": "/v1/sql"
}
FieldMeaning
typeA stable address for this kind of problem. Safe to branch on.
titleA short summary.
statusThe HTTP status.
detailWhat happened, in words you can show or log.
instanceThe path that was called.
creditsWhen present: what the refused action would cost, so a person can agree to the price and ask again.
limitWhen present: the plan limit that refused it, so a person can ask for it to be raised.

Status codes

StatusMeaningRetry?
401Sign-in failed: no token, a wrong or expired token, or a rejected key. The body is the same for every cause.No. Fix the key or get a new token.
402The cannot pay for this work.After adding credits.
403You are signed in, but this is out of scope for your key or role.No.
404Not found, or not yours to see.No.
409It changed since you read it, or is changing.Read again, then retry.
413The request body is too large (over 1 MiB).No. Send less, or upload a file.
422The request is not one you may make, or is invalid.No. Fix the request.
429Too many requests, or every slot is busy. Nothing ran.Yes, after Retry-After seconds.
500Something failed on our side. The body carries no detail.Yes, a little later.
503Temporarily unavailable, for example while Nexus starts.Yes, after Retry-After when present.

How the SDK raises them

All SDK exceptions inherit from KlaretyError, and you import them from klarety.

ExceptionRaised for
AuthError401, and a key rejected at Nexus.connect().
RefusedError403 and 422.
TableRuleErrorA change that breaks a rule of the table (a kind of RefusedError). Never resend it unchanged.
NotFoundError404.
ConflictError409.
InsufficientCreditsError402.
OverBudgetError413, 429, and a query that would read more than your plan allows.
RateLimitedErrorMore calls per minute than your plan allows (a kind of OverBudgetError).
ServiceError500, 503 and anything else on our side.
AnswerNotReadyErrorNo answer in the time allowed, often while Nexus starts (a kind of ServiceError).
SparkStartingError is starting for your workspace (a kind of AnswerNotReadyError).
WaitingForOwnerErrorA change is held for the owner's OK. Carries job_id. Never resend it.

A careful handler

from klarety import (
    AuthError,
    ConflictError,
    InsufficientCreditsError,
    KlaretyError,
    Nexus,
    OverBudgetError,
    RefusedError,
    ServiceError,
)

try:
    with Nexus.connect() as nexus:
        result = nexus.sql("SELECT COUNT(*) AS n FROM orders")
        print(result.rows)
except AuthError:
    print("Sign-in failed: check or replace the API key.")
except InsufficientCreditsError:
    print("Out of credits.")
except OverBudgetError as over:
    print(f"Over a plan limit or rate: {over}")
except RefusedError as refused:
    print(f"Not allowed: {refused}")
except ConflictError:
    print("Changed since read: read again, then retry.")
except ServiceError as failed:
    print(f"Klarety could not answer, try later: {failed}")
except KlaretyError as other:
    print(f"Klarety error: {other}")

Order matters: catch the more specific exceptions first.

What the SDK retries for you

You rarely need your own retry loop.

  • Reads (GET) are retried up to three times on 502, 503 and 504, with a short backoff.
  • Busy and rate-limited answers are waited out on any call, honouring Retry-After, for up to five minutes. Nothing ran, so this is safe.
  • SQL statements carry an ID, so a resent statement runs once.
  • Other writes (POST, PUT, PATCH, DELETE) are never retried, because replaying one could spend credits twice.

Retrying with raw HTTP

If you call the API directly:

  1. Retry only on 429, 503 and 500.
  2. Wait the Retry-After header's seconds when it is present; otherwise back off with random jitter.
  3. Retry a write only if it is safe to run twice, or carries its own ID (statement_id on /v1/sql, write_id on row edits).

Next steps

On this page