Error response shape
Every error returns this structure:
{
"error": {
"code": "artifact_not_found",
"message": "Artifact art_xxx was not found.",
"status": 404
}
}
code — stable, machine-readable string. Match on this. Part of the V1 API contract.
message — human-readable. May change without notice. Do not parse.
status — HTTP status code (duplicated in the body for convenience).
For rate limit errors, an additional field is included:
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Try again in 5 seconds.",
"status": 429,
"retry_after_seconds": 5
}
}
Complete error code reference
| Code | HTTP | Meaning | Agent action |
|---|
invalid_request | 400 | Malformed body, missing fields, invalid metadata key | Abort. Fix the request. Same input always fails. |
ttl_exceeds_plan_limit | 400 | TTL exceeds plan max (Free: 90d, Pro: 365d) | Retry with shorter TTL or escalate for upgrade. |
upload_not_found | 400 | complete called but blob missing in R2 | Retry the PUT upload, then call complete again. |
unauthorized | 401 | Invalid, missing, or revoked API key | Abort immediately. Do not retry. Check or rotate key. |
quota_exceeded | 403 | Storage or request quota reached | Abort. Delete old artifacts or upgrade plan. |
artifact_not_found | 404 | No artifact with this ID for this tenant | Abort. Stale reference. Re-query to find correct artifact. |
session_not_found | 404 | No artifacts exist for this session (seal endpoint only) | Abort. Verify the session ID. |
session_sealed | 409 | Upload to a sealed session | Use a different session. No unseal operation exists. |
artifact_expired | 410 | Artifact’s TTL has passed | Abort. Re-generate from source. Cannot recover. |
artifact_already_deleted | 410 | Artifact was soft-deleted | Treat as success if intent was to delete. Otherwise, artifact is gone. |
file_too_large | 413 | Exceeds size limit | Switch method. Direct: 500 MB max. Presigned: 5 GB max. |
rate_limited | 429 | Burst limit exceeded (100 req/s sustained) | Retry after retry_after_seconds. Implement exponential backoff. |
These error codes are part of the V1 API contract. Existing codes will not be removed or renamed without a new API version. New codes may be added (non-breaking).
SDK exception mapping
The Python SDK maps each error code to a typed exception:
| Exception | API error code |
|---|
ArtifactaError | Base class for all errors |
InvalidRequestError | invalid_request |
UnauthorizedError | unauthorized |
QuotaExceededError | quota_exceeded |
ArtifactNotFoundError | artifact_not_found |
ArtifactExpiredError | artifact_expired |
SessionSealedError | session_sealed |
TTLExceedsPlanLimitError | ttl_exceeds_plan_limit |
RateLimitedError | rate_limited (includes .retry_after_seconds) |
from artifacta import Client, ArtifactNotFoundError, ArtifactExpiredError
client = Client()
try:
artifact = client.get("art_2xk9f7v3m1p0")
except ArtifactNotFoundError:
print("Artifact was never created or ID is wrong")
except ArtifactExpiredError:
print("Artifact existed but TTL passed — re-generate from source")
CLI exit codes
| Exit code | Meaning |
|---|
0 | Success |
1 | Client error (bad input, auth failure, not found) |
2 | Server error |
3 | Network error |