Source: https://docs.sogni.ai/api-reference/getting-started/

# Getting Started

Everything on this page applies to every endpoint in the reference: where the API lives, how you authenticate, how errors and rate limits behave, and how spend is billed. Read it once, then go build.

## [#](https://docs.sogni.ai/api-reference/getting-started/#introduction-1)Introduction

The Sogni REST API lives at `https://api.sogni.ai`. One surface covers an OpenAI-compatible chat endpoint, synchronous creative tools, a durable agent runtime, a creative-workflow engine, project status, account balances, worker analytics, and model discovery. Hosted chat and workflows stream over Server-Sent Events; everything else is an ordinary JSON read or write.

### [#](https://docs.sogni.ai/api-reference/getting-started/#whats-here)What's here

[Generation RecipesOne-step image, video, image-to-video, and music jobs when you already know exactly what to make.](https://docs.sogni.ai/api-reference/direct-generation/)[Project Status APIPoll a generation project you submitted until it finishes, fails, or is canceled.](https://docs.sogni.ai/api-reference/project-status/)[Media Utilities, 3D and SpeechBackground removal, object selection, image-to-3D, video upscaling, speech and voice cloning, and audio-driven or two-stage H3 video.](https://docs.sogni.ai/api-reference/media-utilities/)[Personal LoRAsImport LoRA files into your library and use them on compatible models.](https://docs.sogni.ai/api-reference/personal-loras/)[Chat CompletionsOpenAI-compatible chat, with Sogni creative tools the model can call server-side.](https://docs.sogni.ai/api-reference/chat-completions/)[Direct Tool ExecutionRun one synchronous composition or planning tool with exact JSON arguments.](https://docs.sogni.ai/api-reference/tool-execution/)[Durable Chat RunsPersisted, replayable chat turns with cancel, resume, and cost-approval pauses.](https://docs.sogni.ai/api-reference/chat-runs/)[Creative WorkflowsPre-planned multi-step jobs with a dependency graph and durable execution.](https://docs.sogni.ai/api-reference/workflows/)[Workflow TemplatesSaved, parameterized recipes you can invoke by ID with typed inputs.](https://docs.sogni.ai/api-reference/templates/)[Media and Image URLsPresigned upload and download URLs for reference assets and generated results, plus reusable saved uploads.](https://docs.sogni.ai/api-reference/media/)[Account Balances, Usage, and EarningsPrivate generation-account balances, subscription state, usage, and worker earnings.](https://docs.sogni.ai/api-reference/account-and-usage/)[Model Discovery and Network DemandPublic generation-model catalogs and live worker supply and demand.](https://docs.sogni.ai/api-reference/model-discovery/)

### [#](https://docs.sogni.ai/api-reference/getting-started/#quick-start)Quick start

The shortest path to a result: a chat completion that runs Sogni creative tools server-side.

```bash
curl https://api.sogni.ai/v1/chat/completions \
  -H "Authorization: Bearer $SOGNI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "user", "content": "Generate a cinematic image of a neon alley in Tokyo during rain."}
    ]
  }'
```

**Want the bigger picture?** The [Sogni Intelligence guides](https://docs.sogni.ai/sogni-intelligence/introduction/) explain how chat, tools, and workflows fit together.

## [#](https://docs.sogni.ai/api-reference/getting-started/#authentication-1)Authentication

Authenticated endpoints accept a bearer token in the `Authorization` header. Create API keys in the Sogni account dashboard. Public endpoints, including aggregate worker analytics and generation-model discovery, do not require a key.

```headers
Authorization: Bearer YOUR_API_KEY
```

### [#](https://docs.sogni.ai/api-reference/getting-started/#two-credential-types)Two credential types

-   **API keys** are long-lived UUIDs scoped to a wallet, intended for backend and SDK use. They are required for durable chat runs and creative workflow execution. Generate or rotate yours at [dashboard.sogni.ai/api-key](https://dashboard.sogni.ai/api-key).
-   **Session tokens** are short-lived browser JWTs issued by the Sogni auth flow. Most read endpoints accept either credential type.

The legacy `api-key` header is still accepted, but new integrations should use `Authorization: Bearer`.

**Treat API keys like passwords.** They authorize spend on your behalf. Keep them on your server, never in a browser bundle. Rotate from the dashboard if a key is exposed; revoked keys stop authenticating immediately.

## [#](https://docs.sogni.ai/api-reference/getting-started/#versioning-1)Versioning

Each endpoint has its own versioned path. Most use `/v1/*`; newer-shape replacements include owner-scoped project status at `/v2/projects/:id` and account balances at `/v4/account/balance`. Use the exact path shown for each endpoint. Do not change the version prefix across your whole integration.

## [#](https://docs.sogni.ai/api-reference/getting-started/#errors-1)Errors

The API uses standard HTTP status codes. Successful responses return `200`, `201`, or `202`; failures return `4xx` for caller mistakes and `5xx` for server-side problems. Error bodies are JSON.

<table class="status-table"><tbody><tr><td><span class="status status-2xx">200</span></td><td>OK. Synchronous success.</td></tr><tr><td><span class="status status-2xx">201</span></td><td>Created. A workflow (inline start or reseed), a workflow template (create or fork), or a replay record was saved.</td></tr><tr><td><span class="status status-2xx">202</span></td><td>Accepted. A durable chat run or a personal LoRA import was accepted, a workflow template run is waiting for cost approval, or a workflow resume was scheduled.</td></tr><tr><td><span class="status status-3xx">304</span></td><td>Not modified. A cached public read matched your <code>If-None-Match</code> tag; reuse your cached body.</td></tr><tr><td><span class="status status-4xx">400</span></td><td>Validation error. A body or query parameter failed validation.</td></tr><tr><td><span class="status status-4xx">401</span></td><td>Authentication missing or invalid.</td></tr><tr><td><span class="status status-4xx">402</span></td><td>Insufficient balance. The selected token can't cover the request, or a vendor-model step needs Premium Spark.</td></tr><tr><td><span class="status status-4xx">403</span></td><td>Forbidden. The credential or account isn't allowed to perform the action, such as a subscriber-only feature without an active plan or publishing a public workflow template.</td></tr><tr><td><span class="status status-4xx">404</span></td><td>Resource not found, or hidden from the caller.</td></tr><tr><td><span class="status status-4xx">409</span></td><td>Conflict. The run or workflow is in the wrong state for the action (for example not awaiting cost approval, a stale or expired cost preview, or already finished), an idempotency key was reused with a different confirm-cost body, too many workflows are active, or a resource already exists.</td></tr><tr><td><span class="status status-4xx">413</span></td><td>Payload too large. A replay record exceeds 1&nbsp;MB, or a workflow template exceeds its size limit.</td></tr><tr><td><span class="status status-4xx">422</span></td><td>Unprocessable entity. A workflow template failed schema validation or could not compile.</td></tr><tr><td><span class="status status-4xx">429</span></td><td>Rate limited. Wait for the <code>Retry-After</code> header or the <code>retryAfter</code> body field (seconds) when present; otherwise back off with jitter.</td></tr><tr><td><span class="status status-5xx">500</span></td><td>Internal error. Retry after backoff; report persistent failures.</td></tr><tr><td><span class="status status-5xx">502</span></td><td>Upstream model error, such as a failed model stream or a malformed tool call. Retry.</td></tr><tr><td><span class="status status-5xx">503</span></td><td>Temporarily unavailable. Retry with exponential backoff and jitter; do not treat it as data loss.</td></tr><tr><td><span class="status status-5xx">504</span></td><td>Upstream timeout. Retry with backoff.</td></tr></tbody></table>

### [#](https://docs.sogni.ai/api-reference/getting-started/#error-envelopes)Error envelopes

LLM routes (`/v1/chat/completions`, `/v1/models`) emit the OpenAI-compatible error shape:

```json
{
  "error": {
    "message": "'messages' is required and must be a non-empty array",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_request_error"
  }
}
```

All other endpoints emit the Sogni envelope:

```json
{
  "status": "error",
  "errorCode": 102,
  "message": "Creative workflow requires input.steps"
}
```

Sogni envelopes may also include `details` (structured context, such as why a `409` happened) and `retryAfter` in seconds. OpenAI-shaped errors may include `details`. Some `429` bodies are a plain `{ "error": "Too Many Requests" }`, and workflow template validation failures return `{ "status": "error", "data": { "validation": { "issues": [ … ] } } }`. Branch on the HTTP status first.

## [#](https://docs.sogni.ai/api-reference/getting-started/#rate-limits-1)Rate limits

When a request is rate-limited, the API returns `429 Too Many Requests`. Honor the `Retry-After` header when present. Otherwise, retry with exponential backoff and jitter. Reduce concurrency instead of immediately repeating failed requests.

**Active-workflow cap.** If a workflow start returns `409` because too many workflows are active, cancel or finish an existing run before submitting another, or batch work into a single multi-step workflow. Check the error message: other conflicts also use `409`. The active-workflow `409` carries `details.activeWorkflowCount` and `details.activeWorkflowLimit`, and it does not use up your start allowance. A `429` on a workflow start means starts arrived too quickly or overall workflow capacity is full. A start-rate refusal carries the wait in the `Retry-After` header and, in seconds, in the body's `retryAfter`; a start sent before then is refused again. Retry with the same `Idempotency-Key`.

Default limits for workflows, render concurrency, and SDK connections, and how to design around them, are in [Production Integrations](https://docs.sogni.ai/api-reference/production-integrations/).

## [#](https://docs.sogni.ai/api-reference/getting-started/#idempotency-1)Idempotency

Write endpoints that can produce side effects accept an **idempotency key**. Reusing the same key for the same caller returns the original result instead of starting a duplicate run. Use it to make retries safe across network failures and double-clicks.

### [#](https://docs.sogni.ai/api-reference/getting-started/#headers)Headers

```headers
Idempotency-Key: 7c9e6f7c-23a1-4f06-9d33-2dd5d6c8f5fb
```

`X-Idempotency-Key` is accepted as an alias.

### [#](https://docs.sogni.ai/api-reference/getting-started/#supported-endpoints)Supported endpoints

-   [`POST /v1/chat/runs`](https://docs.sogni.ai/api-reference/chat-runs/) starts a durable chat run and also accepts `idempotency_key` in the body.
-   [`POST /v1/chat/runs/:id/confirm-cost`](https://docs.sogni.ai/api-reference/chat-runs/#chat-runs-confirm-cost) resolves a chat-run cost-approval pause and also accepts `idempotency_key` in the body.
-   [`POST /v1/creative-agent/workflows`](https://docs.sogni.ai/api-reference/workflows/) starts a durable workflow (header only).
-   [`POST /v1/creative-agent/workflows/:id/confirm-cost`](https://docs.sogni.ai/api-reference/workflows/#workflows-confirm-cost) resolves a workflow cost-approval pause and also accepts `idempotency_key` in the body.
-   [`POST /v1/creative-agent/workflows/:id/reseed`](https://docs.sogni.ai/api-reference/workflows/#workflows-reseed) starts a new take of a finished workflow (header only). A reseed mints new seeds, so without a key a retry starts a second take.

**Scope.** The key is scoped to the calling wallet, so the same key from a different wallet does not collide. Chat-run keys longer than 200 characters are ignored, and workflow keys longer than 192 characters are truncated; a UUID is ideal for both.

## [#](https://docs.sogni.ai/api-reference/getting-started/#billing-and-tokens)Billing and tokens

Spend is denominated in two token types. Pick one explicitly with `token_type` on a request, or let the API choose.

| Token | How acquired | Used for |
| --- | --- | --- |
| sogni | Native. Earned through Supernet participation or staking. | Pays for Sogni-native models (such as Krea, Qwen, LTX, WAN, MiniMax H3, and ACE-Step) when selected, or as the fallback for `auto`. |
| spark | Purchased with cash, or earned. | Paid first under `auto`. Premium Spark is required for external vendor models: `gpt-image-2`, `gpt-image-2.5-sunburst`, `gpt-image-2.5-flare`, `seedance2`, `seedance2-mini`, `seedance2-5`, `happyhorse-1.1-*`, `wan3.0-video`, and `wan3.0-spicy-video`. |

### [#](https://docs.sogni.ai/api-reference/getting-started/#selecting-a-token)Selecting a token

Accepted values are `auto` (default), `sogni`, and `spark`. When tokens are billed, `auto` pays with Spark first and falls back to SOGNI.

```json
{ "token_type": "auto" }
```

`/v1/chat/completions` also accepts an `X-Token-Type` header (the body field wins); other endpoints read `token_type` from the body only. Vendor-model jobs are normalized to `spark` automatically, regardless of preference.

### [#](https://docs.sogni.ai/api-reference/getting-started/#plan-or-tokens)Plan or tokens

`token_type` only picks which token pays. Whether an active [Unlimited plan](https://docs.sogni.ai/pricing/unlimited-plan-details/) or your token balance pays is a separate field, `billing_mode`, accepted by [chat completions](https://docs.sogni.ai/api-reference/chat-completions/), [tool execution](https://docs.sogni.ai/api-reference/tool-execution/), [chat runs](https://docs.sogni.ai/api-reference/chat-runs/), and [workflows](https://docs.sogni.ai/api-reference/workflows/) (start, resume, and reseed).

| billing\_mode | Behavior |
| --- | --- |
| auto | Default. An active Unlimited plan covers the work it can, and no tokens are spent on that work. Everything else bills your token balance according to `token_type`. |
| subscription | Bill eligible work against the plan only. Work the plan can't cover fails instead of billing tokens. |
| tokens | Always bill your token balance, even when a plan is active. |

With an active plan, changing `token_type` between `spark` and `auto` does not move a job off the plan. To spend Premium Spark you hold, which gets fastest-priority queue access ahead of plan-covered jobs, send `billing_mode: "tokens"`. Vendor models are never plan-covered and always bill Premium Spark. A request that asks to pay in SOGNI (`token_type: "sogni"`) is not plan-covered either.

```json
{ "token_type": "spark", "billing_mode": "tokens" }
```

### [#](https://docs.sogni.ai/api-reference/getting-started/#vendor-model-gating)Vendor model gating

Models from external vendors (OpenAI GPT Image 2 and GPT Image 2.5 Sunburst / Flare, [ByteDance Seedance 2.0](https://www.sogni.ai/models/seedance-2-0) / Mini, [Seedance 2.5](https://docs.sogni.ai/models/seedance-2-5/), [Alibaba HappyHorse 1.1](https://www.sogni.ai/models/happyhorse-1-1), [Wan 3](https://docs.sogni.ai/models/wan-3/), and [Wan 3 Uncensored](https://docs.sogni.ai/models/wan-3-uncensored/)) bill Premium Spark. Hosted chat may choose a GPT Image model for storyboard or character-sheet work; if the account is not eligible for Premium Spark, chat uses a Sogni-hosted model instead. Workflows never substitute: a workflow that names a vendor model returns `402` with `details.vendorModels` before any step runs, including a `confirm_cost: false` estimate.

### [#](https://docs.sogni.ai/api-reference/getting-started/#cost-approval)Cost approval

-   **Creative workflows** use a two-step confirmation. Submit with `confirm_cost: false` to get a `400` whose `details.estimatedCapacity` holds the estimate, then resubmit with `confirm_cost: true`. `max_estimated_capacity_units` is a hard cap: plans over it are rejected with `400` before anything is saved. Template runs (`workflow_id`) always return `202` with a `preview` and wait for [`POST /v1/creative-agent/workflows/:id/confirm-cost`](https://docs.sogni.ai/api-reference/workflows/#workflows-confirm-cost).
-   **Chat runs** opt in with `runtime_config.requireJobConfirmation: true`. When the model calls a paid media tool, the run pauses in `waiting_for_user` with reason `cost_approval_required`, holds every paid call from that round, and emits `run_awaiting_cost_confirmation` for each held call. Resume or decline with [`POST /v1/chat/runs/:id/confirm-cost`](https://docs.sogni.ai/api-reference/chat-runs/#chat-runs-confirm-cost), echoing `waiting.details.costApprovalPreview`. `confirm_cost` and `max_estimated_capacity_units` are recorded on chat runs but not enforced.
