AI92 jau veikia – prasidėjo mūsų pasaulinis bandomasis paleidimas: visa platforma yra atvira visame pasaulyje pirmąsias 30 dienų.
Dokumentacijos meniu

Ši kūrėjų dokumentacija šiuo metu yra tik anglų kalba. Kodas ir API elgesys yra identiški visuose regionuose.

Async Jobs

Some operations take longer than a single HTTP request should wait — rendering a video, generating a full creative campaign, scanning a whole site, discovering thousands of contacts. These endpoints return immediately with a job handle, and you poll one endpoint for the result regardless of which service produced it.

The pattern

  1. Submit. Call the async endpoint. It reserves credits, kicks off the work, and returns a job_id with status: "queued".
  2. Poll. GET /v1/jobs/{job_id} until status is completed or failed.
  3. Settle. On completed, credits are consumed exactly once and result is included. On failed, the reserved credits are refunded automatically and error is included.
bash
# 1. Submit — generate a newsletter banner (15 credits, async)
curl -X POST https://api.ai92.ai/v1/creative/newsletter \
  -H "Authorization: Bearer ai92_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "X-AI92-Idempotency-Key: 9d2e...c7" \
  -d '{"brand_id": "brand_koloxo", "topic": "Summer launch"}'
json
{
  "job_id": "f_2c1a9b44-7e51-4c0d-9b2f-1a6d3e8f0011",
  "status": "queued",
  "service": "creative",
  "credits_reserved": 15,
  "poll_url": "/v1/jobs/f_2c1a9b44-7e51-4c0d-9b2f-1a6d3e8f0011",
  "created_at": "2026-06-21T10:30:00Z",
  "updated_at": "2026-06-21T10:30:00Z"
}
bash
# 2. Poll
curl https://api.ai92.ai/v1/jobs/f_2c1a9b44-7e51-4c0d-9b2f-1a6d3e8f0011 \
  -H "Authorization: Bearer ai92_live_YOUR_KEY"

A finished job:

json
{
  "job_id": "f_2c1a9b44-7e51-4c0d-9b2f-1a6d3e8f0011",
  "status": "completed",
  "service": "creative",
  "credits_reserved": 15,
  "result": { "asset_url": "https://cdn.ai92.ai/...", "format": "png" },
  "created_at": "2026-06-21T10:30:00Z",
  "updated_at": "2026-06-21T10:30:48Z"
}

A failed job (credits already refunded):

json
{
  "job_id": "f_2c1a9b44-...",
  "status": "failed",
  "service": "creative",
  "credits_reserved": 15,
  "error": { "code": "BACKEND_ERROR", "message": "render failed", "status": 503 }
}

Job statuses

statusMeaningResponse includes
queuedAccepted, not started yet.poll_url
processingRunning.poll_url
completedDone successfully — credits consumed once.result
failedDid not complete — credits refunded.error

completed and failed are terminal: stop polling once you see them.

Job ID prefixes

The job_id prefix tells you which backend produced the job. You never need to call those backends directly — GET /v1/jobs/{job_id} works for all of them — but the prefix is useful in logs:

PrefixBackendPoll at
f_Creative (image/video/newsletter renders) and site scansGET /v1/jobs/{job_id}
strat-int-Full campaign / creative-campaign pipelineGET /v1/jobs/{job_id}
g_Analysis / intelligenceGET /v1/jobs/{job_id}
c_, bdem_, j_, gxr_, a_Other internal producersGET /v1/jobs/{job_id}

Note: contacts bulk discovery and SEO audit are the exceptions — they return a UUID scan_id (no f_/strat-int- prefix) and are polled at their own namespace (GET /v1/contacts/bulk/{scan_id} and GET /v1/seo/audit/{scan_id} respectively), not at GET /v1/jobs/{...}. See Poll namespaces below.

Which endpoints are async

EndpointHandle returnedPoll atReserved cost
POST /v1/creative/generatejob_id (f_*)GET /v1/jobs/{job_id}50+
POST /v1/creative/newsletterjob_id (f_*)GET /v1/jobs/{job_id}15
POST /v1/creative/campaignsjob_id (strat-int-*)GET /v1/jobs/{job_id}250 / week
POST /v1/campaigns/buildjob_id (strat-int-*)GET /v1/jobs/{job_id}25
POST /v1/ai-visibility/{brand_id}/scanjob_id (f_*)GET /v1/jobs/{job_id}20
POST /v1/seo/auditscan_id (UUID)GET /v1/seo/audit/{scan_id}
POST /v1/contacts/bulk (large limits)scan_id (UUID)GET /v1/contacts/bulk/{scan_id}not /v1/jobs/300 / 100

Synchronous endpoints return their result directly and never give you a job handle.

Poll namespaces

Most async jobs poll at the unified GET /v1/jobs/{job_id} endpoint, but two endpoints return a UUID scan_id that is polled at its own namespace — GET /v1/jobs/{scan_id} returns 404 for these. There are four distinct poll namespaces in total:

ProducerHandlePoll at
f_* jobs (creative, scans)job_idGET /v1/jobs/{job_id}
strat-int-* jobs (campaign build)job_idGET /v1/jobs/{job_id}
SEO auditscan_id (UUID)GET /v1/seo/audit/{scan_id}
Contacts bulk discoveryscan_id (UUID)GET /v1/contacts/bulk/{scan_id}

Always poll a scan_id at the namespace listed above — not at /v1/jobs/, which will 404 for an SEO-audit or contacts-bulk scan_id.

Reserve + refund, exactly once

This is the contract that protects your balance:

  • On submit, the full cost is reserved (decremented with a TTL). If you can't afford it, you get 402 INSUFFICIENT_CREDITS and nothing is reserved.
  • On success, the reservation simply finalizes — you are charged once.
  • On failure or timeout, the reservation is refunded automatically by AI92's reconciler — you are charged zero.

So a job that fails costs you nothing, and a job that succeeds costs you exactly its published price — never more, never twice.

Polling guidance

  • Poll with backoff, not a tight loop: e.g. every 2 s for the first 30 s, then every 5–10 s. Most renders settle in well under a minute.
  • Stop on terminal status (completed / failed).
  • Prefer webhooks where available — subscribe to the relevant completion event and skip polling entirely. See Webhooks.
  • Ownership is enforced. GET /v1/jobs/{job_id} returns 404 for an unknown id or an id owned by another account — existence is never leaked across tenants.
python
import time, httpx

def wait_for_job(job_id, key, timeout=300):
    headers = {"Authorization": f"Bearer {key}"}
    delay = 2
    deadline = time.time() + timeout
    while time.time() < deadline:
        job = httpx.get(f"https://api.ai92.ai/v1/jobs/{job_id}", headers=headers).json()
        if job["status"] in ("completed", "failed"):
            return job
        time.sleep(delay)
        delay = min(delay * 1.5, 10)
    raise TimeoutError(job_id)