> ## Documentation Index
> Fetch the complete documentation index at: https://docs.creatorline.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Generating media

> Tools, models, inputs and parameters — and how a run actually flows.

A generation is a job. You start it, it costs credits, and you poll it until media comes
out. Nothing about it blocks: a photo takes around 30 seconds and a video several
minutes.

## Tools, not models

You address a **tool** (`ugc-video`, `text-to-photo`, `lipsync`), and the platform picks
the right model and pipeline. Pass `model` only when you specifically want to override it.

```bash theme={null}
curl https://api.creatorline.io/v1/models \
  -H "Authorization: Bearer $CREATORLINE_API_KEY"
```

<Note>
  **Read the catalog, don't hardcode it.** `GET /v1/models` returns every tool, every
  model, and the exact inputs and parameters each accepts. When we add a model, your code
  can use it without a change on your side. Narrow with `?tool=ugc-video` or
  `?model=<id>`.
</Note>

<CardGroup cols={3}>
  <Card title="Video" icon="video">
    `ugc-video` · `short-clip` · `scene-video` · `motion-control` · `hook-captions`
  </Card>

  <Card title="Photo" icon="image">
    `text-to-photo` · `photo-edit`
  </Card>

  <Card title="Audio" icon="waveform-lines">
    `text-to-speech` · `lipsync` · `change-voice` · `add-audio` · `dialogue`
  </Card>
</CardGroup>

## Generating as a creator

Pass `account_id` and the run inherits that creator's look, voice and persona, and the
output lands on their wall in the studio. Without it, the run is workspace-scoped and
generic.

```bash theme={null}
curl https://api.creatorline.io/v1/accounts \
  -H "Authorization: Bearer $CREATORLINE_API_KEY"
```

## Inputs and parameters

<ResponseField name="inputs" type="object">
  Slot key → asset id(s) **or** public `https` URL(s). A URL is adopted as an asset
  automatically, so there is no upload step when your media is already on the internet.
  Which slots a model takes — and which are required — is in its catalog entry.
</ResponseField>

<ResponseField name="params" type="object">
  Model parameters like `aspect_ratio`, `duration`, `resolution`. Validated against the
  model's schema.
</ResponseField>

<Warning>
  An unknown parameter is a `400`, never a silent drop. A typo'd parameter quietly ignored
  on a paid call is the worst possible outcome, so we refuse the call instead.
</Warning>

```json theme={null}
{
  "tool": "ugc-video",
  "prompt": "unboxing a skincare set, chatty and warm",
  "account_id": "e307923d-…",
  "inputs": { "characters": ["https://example.com/face.png"] },
  "params": { "aspect_ratio": "9:16", "duration": "5" }
}
```

## Uploading your own media

Bytes never pass through the API. Three steps, and the asset id is usable the moment the
`PUT` succeeds:

<Steps>
  <Step title="Ask for a presigned upload">
    `POST /v1/uploads` with `content_type` and `size_bytes`. You get `upload_url`,
    `headers` and the `asset_id` it will become.
  </Step>

  <Step title="PUT the bytes">
    Straight to storage, with the headers you were given.
  </Step>

  <Step title="Complete it">
    `POST /v1/uploads/{id}/complete`. This starts thumbnailing and transcoding, and hands
    you the finished asset.
  </Step>
</Steps>

Limits: images 25 MB, video 100 MB, audio 50 MB. The [CLI](/cli) does all three for you —
`--image ./face.png` just works.

## Cost

```bash theme={null}
curl https://api.creatorline.io/v1/generations/cost \
  -H "Authorization: Bearer $CREATORLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tool": "ugc-video", "params": { "duration": "10" } }'
```

```json theme={null}
{ "object": "cost_estimate", "model": "bytedance-seedance-2-0-reference-to-video-fast",
  "credits": 48, "credit_balance": 4433, "sufficient": true }
```

Free to call, available to `read` keys, and priced by the same function that performs the
debit — so an estimate cannot disagree with the charge. Credits are taken at kick-off;
a run that terminally fails, including a moderation rejection, is **refunded
automatically**.

## Polling

```
queued → processing → succeeded
                    ↘ failed
```

Poll `GET /v1/generations/{id}` every few seconds. On `succeeded`, `output[]` holds the
assets:

```json theme={null}
{
  "object": "generation",
  "id": "3f6c1a2b-…",
  "status": "succeeded",
  "output": [
    { "object": "asset", "id": "9b2f7c10-…", "file_type": "video",
      "ratio": "9:16", "duration_sec": 5, "url": "https://…/clip.mp4" }
  ]
}
```

<Warning>
  Media URLs are **time-limited**. Download the bytes; do not persist the link.
</Warning>

On `failed`, `error` carries the reason — a moderation rejection reads differently from a
provider failure — and your credits are already back.

## Next

<CardGroup cols={2}>
  <Card title="Publish it" icon="paper-plane" href="/publishing">
    Turn finished media into a post on your creator's social accounts.
  </Card>

  <Card title="Full reference" icon="code" href="/api-reference/generations/start-a-generation">
    Every field, with a live playground.
  </Card>
</CardGroup>


## Related topics

- [List media](/api-reference/assets/list-media.md)
- [Create a post](/api-reference/posts/create-a-post.md)
- [Creatorline API](/index.md)
- [Publishing](/publishing.md)
- [CLI](/cli.md)
