Developer docs

Ship studio vehicle photos with a few lines of code.

AutoStudio AI is API-first. POST raw lot photos, and get back consistent, catalog-ready renditions through a REST API built for fleets at scale.

Overview

What the API does

Send raw vehicle photos and AutoStudio classifies each shot, replaces the backdrop with a clean studio sweep, enhances lighting, blurs plates and faces, then QA's every frame — returning signed URLs for each rendition. Everything happens through HTTP, so your inventory system can drive the whole pipeline without a UI.

REST + JSON

Standard HTTP, a { data, error } envelope, and bearer auth.

Bulk jobs

POST one image or thousands; each item is processed and QA'd.

Async delivery

Poll the job or receive a signed job.completed webhook.

Get started

Get an API key

Create a key from the dashboard under API Keys. Choose an environment when you create it — the prefix tells you which pipeline it runs, exactly like Stripe.

sk_test_…Test

Runs a free mock pipeline — instant, $0, no real AI. Responses have the same shape as live, so you can build and test your integration end-to-end for free.

sk_live_…Live

Runs the real pipeline: backdrop replacement, enhancement, plate/face blur, and QA. Billed per processed image.

Security

Authentication

Authenticate every request with your secret key in the Authorization header. Keep keys server-side — never ship them to a browser or mobile app.

header
Authorization: Bearer sk_live_...
A missing or invalid key returns 401 with error.code = "unauthorized".

Concepts

Job lifecycle

Jobs are asynchronous. You submit images, the pipeline processes each item, and you collect results by polling or via webhook.

  1. 1. Submit

    POST /v1/jobs with base64 images. You get 202 and a job with status queued.

  2. 2. Poll or webhook

    Poll GET /v1/jobs/{id}, or register a webhook to receive job.completed.

  3. 3. Fetch results

    Read each item's renditions map — signed URLs that expire. Re-fetch the job for fresh URLs.

Terminal statuses are completed, completed_with_fallbacks (some frames failed QA and fell back to the original), and failed.

Reference

Endpoint reference

Base URL https://api.autostudio.ai. All responses use the { data, error } envelope.

POST/v1/jobs

Create a job

Submit one or more base64-encoded images. Returns 202 with a queued job you can poll or receive via webhook.

Request

curl
curl -X POST https://api.autostudio.ai/v1/jobs \
-H "Authorization: Bearer $AUTOSTUDIO_KEY" \
-H "Content-Type: application/json" \
-d '{
"preset_id": "default",
"webhook_url": "https://yourapp.com/hooks/autostudio",
"images": [
{ "filename": "front.jpg", "content_base64": "<base64>", "shot_type_hint": "front_3q" }
]
}'

Response

response.json
{
"data": {
"id": "job_9f2c71a4",
"status": "queued",
"total_items": 1,
"completed_items": 0,
"failed_items": 0,
"created_at": "2026-07-16T22:00:00Z"
},
"error": null
}
GET/v1/jobs

List jobs

Return all jobs for the authenticated account, newest first.

Request

curl
curl -X GET https://api.autostudio.ai/v1/jobs \
-H "Authorization: Bearer $AUTOSTUDIO_KEY"

Response

response.json
{
"data": [
{ "id": "job_9f2c71a4", "status": "completed", "total_items": 1,
"completed_items": 1, "failed_items": 0, "created_at": "2026-07-16T22:00:00Z" }
],
"error": null
}
GET/v1/jobs/{id}

Get a job

Fetch a single job including its per-image items, QA status, and signed rendition URLs.

Request

curl
curl -X GET https://api.autostudio.ai/v1/jobs/{id} \
-H "Authorization: Bearer $AUTOSTUDIO_KEY"

Response

response.json
{
"data": {
"id": "job_9f2c71a4",
"status": "completed",
"total_items": 1,
"completed_items": 1,
"failed_items": 0,
"created_at": "2026-07-16T22:00:00Z",
"items": [
{
"id": "item_01",
"image_id": "img_01",
"status": "completed",
"shot_type": "front_3q",
"qa_pass": true,
"fell_back": false,
"renditions": {
"hero_2048": "https://cdn.autostudio.ai/signed/...",
"thumb_512": "https://cdn.autostudio.ai/signed/..."
},
"original_url": "https://cdn.autostudio.ai/signed/..."
}
]
},
"error": null
}
GET/v1/usage

Get usage

Return processed image counts, fallbacks, and cost for the current period.

Request

curl
curl -X GET https://api.autostudio.ai/v1/usage \
-H "Authorization: Bearer $AUTOSTUDIO_KEY"

Response

response.json
{
"data": {
"images_processed": 1420,
"fallbacks": 11,
"total_cost_usd": 42.6,
"period": "2026-07"
},
"error": null
}
GET/v1/presets

List presets

Return your brand presets (backdrop, plate handling, aspect ratio, enhancement intensity, rendition sizes).

Request

curl
curl -X GET https://api.autostudio.ai/v1/presets \
-H "Authorization: Bearer $AUTOSTUDIO_KEY"

Response

response.json
{
"data": [
{ "id": "default", "name": "Storefront", "is_default": true,
"backdrop": "studio_white", "plate_handling": "blur",
"output_aspect": "4:3", "enhancement_intensity": "medium",
"watermark": false, "rendition_sizes": ["hero_2048", "thumb_512"] }
],
"error": null
}
PATCH/v1/presets/{id}

Update a preset

Update any preset field. Send only the keys you want to change.

Request

curl
curl -X PATCH https://api.autostudio.ai/v1/presets/{id} \
-H "Authorization: Bearer $AUTOSTUDIO_KEY" \
-H "Content-Type: application/json" \
-d '{ "backdrop": "gradient", "enhancement_intensity": "high" }'

Response

response.json
{
"data": { "id": "default", "name": "Storefront", "backdrop": "gradient",
"enhancement_intensity": "high", "plate_handling": "blur",
"output_aspect": "4:3", "is_default": true, "watermark": false,
"rendition_sizes": ["hero_2048", "thumb_512"] },
"error": null
}
GET/v1/keys

List API keys

Return your API keys (metadata only — the secret is shown once, at creation).

Request

curl
curl -X GET https://api.autostudio.ai/v1/keys \
-H "Authorization: Bearer $AUTOSTUDIO_KEY"

Response

response.json
{
"data": [
{ "id": "key_01", "name": "Production", "key_prefix": "sk_live_a1b2",
"environment": "live", "scopes": ["jobs:write"], "is_active": true,
"last_used_at": "2026-07-16T21:55:00Z", "created_at": "2026-07-01T09:00:00Z" }
],
"error": null
}
POST/v1/keys

Create an API key

Create a key for the chosen environment. Test keys (sk_test_…) run the free mock pipeline; live keys (sk_live_…) run the real pipeline. The full key is returned once.

Request

curl
curl -X POST https://api.autostudio.ai/v1/keys \
-H "Authorization: Bearer $AUTOSTUDIO_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Production", "environment": "live", "scopes": ["jobs:write"] }'

Response

response.json
{
"data": {
"id": "key_02",
"name": "Production",
"key_prefix": "sk_live_9x8y",
"environment": "live",
"scopes": ["jobs:write"],
"is_active": true,
"created_at": "2026-07-16T22:00:00Z",
"key": "sk_live_9x8y...shown_once"
},
"error": null
}
DELETE/v1/keys/{id}

Revoke an API key

Immediately revoke a key. Requests using it start failing at once.

Request

curl
curl -X DELETE https://api.autostudio.ai/v1/keys/{id} \
-H "Authorization: Bearer $AUTOSTUDIO_KEY"

Response

response.json
{ "data": { "ok": true }, "error": null }
GET/v1/webhooks

List webhooks

Return your registered webhook endpoints.

Request

curl
curl -X GET https://api.autostudio.ai/v1/webhooks \
-H "Authorization: Bearer $AUTOSTUDIO_KEY"

Response

response.json
{
"data": [
{ "id": "wh_01", "url": "https://yourapp.com/hooks/autostudio", "is_active": true }
],
"error": null
}
POST/v1/webhooks

Register a webhook

Register an endpoint to receive job.completed events. The returned secret signs every delivery — store it to verify signatures.

Request

curl
curl -X POST https://api.autostudio.ai/v1/webhooks \
-H "Authorization: Bearer $AUTOSTUDIO_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://yourapp.com/hooks/autostudio" }'

Response

response.json
{
"data": {
"id": "wh_01",
"url": "https://yourapp.com/hooks/autostudio",
"secret": "whsec_...store_this",
"is_active": true
},
"error": null
}
DELETE/v1/webhooks/{id}

Delete a webhook

Remove a webhook endpoint. Deliveries stop immediately.

Request

curl
curl -X DELETE https://api.autostudio.ai/v1/webhooks/{id} \
-H "Authorization: Bearer $AUTOSTUDIO_KEY"

Response

response.json
{ "data": { "ok": true }, "error": null }

Async

Webhooks

Register an endpoint with POST /v1/webhooks to receive the job.completed event when a job reaches a terminal state.

job.completed.json
{
"event": "job.completed",
"data": {
"id": "job_9f2c71a4",
"status": "completed",
"total_items": 1,
"completed_items": 1,
"failed_items": 0
}
}

Every delivery is signed. The X-AutoStudio-Signature header is the HMAC-SHA256 of the raw request body using your endpoint secret. Compute the same HMAC and compare in constant time before trusting the payload.

python
import hmac, hashlib
def verify(raw_body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
# signature = request.headers["X-AutoStudio-Signature"]

Reliability

Rate limits & errors

Errors return a non-2xx status and populate error with a stable code and a human message; data is null.

error.json
{
"data": null,
"error": { "code": "rate_limited", "message": "Too many requests. Retry after 2s." }
}

When you exceed your plan's throughput you'll get 429 with a Retry-After header. Back off for that many seconds, then retry with jitter. The SDKs in the next section handle polling for you.

Libraries

SDKs

Official thin clients wrap auth, base64 encoding, and polling. Find them under sdks/ in the repo.

python
pip install autostudio
python
from autostudio import AutoStudio
client = AutoStudio(api_key="sk_live_...", base_url="https://api.autostudio.ai")
job = client.create_job(
images=["front.jpg", "rear.jpg"],
preset_id="default",
)
done = client.wait_for_job(job["id"])
for item in done["items"]:
print(item["renditions"])