Endpoints

GET — Job Status

Poll this endpoint every 2 seconds after submitting a generation job. When status reaches "completed", the image_url field contains a permanent URL to your generated image.

Overview

GEThttps://www.sharkapi.dev/api/v1/jobs/:id

Replace :id with the job_id returned from POST /api/v1/image. Generation typically takes 30 – 120 seconds — poll until the status is terminal.

A 200 OK response means the poll succeeded, not that generation is complete. Always check the status field.

Request

ParameterTypeRequiredDescription
AuthorizationstringRequiredYour API key. Format: "Bearer sk_live_..."
:idstringRequiredJob ID from the POST /api/v1/image response.

cURL example

bash
curl https://www.sharkapi.dev/api/v1/jobs/3a8f2c1d-7b4e-4f9a-b2d6-1c5e8f3a9b7d \
  -H "Authorization: Bearer sk_live_••••••••"

Response

HTTP 200 OK. Check status to know if generation is done.

ParameterTypeRequiredDescription
job_idstringRequiredUnique job identifier.
statusstringRequired"queued" | "processing" | "completed" | "failed"
image_urlstring | nullRequiredPermanent URL of the generated image. Present only when status is "completed".
coststring | nullRequiredFinal cost, e.g. "$0.03". Set only when status is "completed".
errorstring | nullRequiredError message when status is "failed". Null otherwise.
queued_atstringRequiredISO 8601 timestamp when the job entered the queue.
started_atstring | nullRequiredISO 8601 timestamp when the worker began processing. Null if still queued.
completed_atstring | nullRequiredISO 8601 timestamp of completion. Null if not yet finished.
created_atstringRequiredISO 8601 timestamp of job creation.

While queued or processing

json
{
  "job_id":       "3a8f2c1d-7b4e-4f9a-b2d6-1c5e8f3a9b7d",
  "status":       "queued",
  "image_url":    null,
  "cost":         null,
  "error":        null,
  "queued_at":    "2025-01-15T10:23:44Z",
  "started_at":   null,
  "completed_at": null,
  "created_at":   "2025-01-15T10:23:44Z"
}

Completed — image ready

json
{
  "job_id":       "3a8f2c1d-7b4e-4f9a-b2d6-1c5e8f3a9b7d",
  "status":       "completed",
  "image_url":    "https://your-project.supabase.co/storage/v1/object/public/generated-images/...",
  "cost":         "$0.03",
  "error":        null,
  "queued_at":    "2025-01-15T10:23:44Z",
  "started_at":   "2025-01-15T10:23:46Z",
  "completed_at": "2025-01-15T10:24:18Z",
  "created_at":   "2025-01-15T10:23:44Z"
}

Failed — no charge

json
{
  "job_id":       "9b3c1a2d-4f8e-4c7b-a1e5-2d9f6b4a8c3e",
  "status":       "failed",
  "image_url":    null,
  "cost":         null,
  "error":        "Provider request timed out after 180s.",
  "queued_at":    "2025-01-15T10:30:00Z",
  "started_at":   "2025-01-15T10:30:02Z",
  "completed_at": null,
  "created_at":   "2025-01-15T10:30:00Z"
}

Job statuses

queued

Job received and waiting for a worker to pick it up.

processing

Worker is actively generating your image. Usually 30–120 seconds.

completed

Done. image_url is set and your wallet has been charged.

failed

Generation failed (timeout or provider error). No charge applied. Safe to retry.

Polling pattern

Poll every 2 seconds. Handle all terminal states. Do not poll more frequently — there is no benefit and it wastes your bandwidth.

Set a client-side timeout of ~3 minutes. If a job is still not completed after 3 minutes, something went wrong on our end — the job will be marked failed automatically with no charge.

JavaScript / Node.js

javascript
async function waitForJob(jobId) {
  const url     = `https://www.sharkapi.dev/api/v1/jobs/${jobId}`;
  const headers = { "Authorization": `Bearer ${process.env.SHARKAPI_KEY}` };

  while (true) {
    const res = await fetch(url, { headers });

    if (!res.ok) throw new Error(`Poll failed: HTTP ${res.status}`);

    const job = await res.json();

    if (job.status === "completed") {
      return job; // job.image_url is ready
    }

    if (job.status === "failed") {
      throw new Error(job.error ?? "Job failed — no charge applied");
    }

    // "queued" or "processing" — keep waiting
    await new Promise(r => setTimeout(r, 2000));
  }
}

// Full flow
const { job_id } = await generateImage("A shark in neon waters");
const job        = await waitForJob(job_id);

console.log(job.image_url); // permanent URL, ready to use
console.log(job.cost);      // "$0.03"

Python

python
import time, httpx

def wait_for_job(job_id: str) -> dict:
    url     = f"https://www.sharkapi.dev/api/v1/jobs/{job_id}"
    headers = {"Authorization": f"Bearer {SHARKAPI_KEY}"}

    while True:
        res = httpx.get(url, headers=headers, timeout=10)
        res.raise_for_status()
        job = res.json()

        if job["status"] == "completed":
            return job  # job["image_url"] is ready

        if job["status"] == "failed":
            raise RuntimeError(job.get("error") or "Job failed — no charge applied")

        # "queued" or "processing" — keep waiting
        time.sleep(2)

# Full flow
job_id = generate_image("A shark in neon waters")["job_id"]
job    = wait_for_job(job_id)

print(job["image_url"])  # permanent URL
print(job["cost"])       # "$0.03"

Errors

ParameterTypeRequiredDescription
401 UnauthorizedHTTPOptionalMissing or invalid API key.
404 Not FoundHTTPOptionalJob ID does not exist or belongs to a different account.