Reliability and idempotency
Reliability and idempotency
The SDK retries transient failures only when repeating the request is safe. Every workflow submission carries an idempotency key so a network retry can replay the original run instead of creating another billable run.
Use a business key for recoverable submissions
When you omit idempotency_key, the SDK creates a random key. That protects retries inside one method call. It cannot connect a new process invocation to the earlier submission.
For durable application work, derive a stable key from the operation your system considers unique.
from makra import Makra
job_id = "catalog-refresh-2026-08-21-atlas-lamp"
with Makra() as client:
run = client.submit_extract(
["https://shop.example/products/atlas-lamp"],
{"price": "The current selling price"},
idempotency_key=job_id,
)
print(run.id)
Reuse the same key only with the same request body. Reusing it for different URLs, schemas, execution modes, or configuration is a conflict and is not retried.
What the SDK retries
Retryable HTTP statuses include request timeout, selected conflict and early-request statuses, rate limiting, and common server or gateway failures. The SDK also retries transport errors for methods marked safe. It honors Retry-After when present, otherwise it uses exponential backoff with jitter.
The default is two retries after the initial attempt. max_retries=0 disables them.
from makra import Makra
client = Makra(
max_retries=4,
retry_backoff=1.0,
connect_timeout=10.0,
)
Streaming reconnects are separate from workflow submission. Once a run ID exists, the SDK reconnects with a GET on the run event endpoint and resumes from the last sequence. It does not repeat the original POST.
Timeout does not mean cancellation
A client timeout means the client stopped waiting. A durable server run may still be queued or running. If a blocking or polling call times out and you have a run ID, reconcile with get_run() before submitting replacement work.
Use deferred submission when losing the inbound connection must not lose run identity.
Handle rate limiting explicitly
MakraRateLimitError carries retry_after and may carry concurrency details. The built-in retry budget can still expire while the account is at its run limit. Queue work in your application and retry at the operation level with the same idempotency key.
from makra import Makra, MakraRateLimitError
try:
with Makra(max_retries=2) as client:
client.extract(
["https://shop.example/products/atlas-lamp"],
{"price": "The current selling price"},
idempotency_key="atlas-price-refresh-17",
)
except MakraRateLimitError as error:
print(error.retry_after, error.concurrency)
raise
Do not start unbounded local retries around the SDK. Bound attempts, preserve the idempotency key, and let a queue absorb sustained capacity pressure.
Next, read Quality, validation, and drift.