> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# Effect API

> Create an asynchronous image or video Effect task using a versioned BeatAPI effect.

`POST https://api.beatapi.io/v1/effects/tasks`

Create an asynchronous image or video Effect task using a versioned BeatAPI effect.

## Authorization

`Authorization`   `string`   **required**

Send your BeatAPI API key as a Bearer token. Create one on the [Dashboard](https://beatapi.io/dashboard).

```
Authorization: Bearer <BEATAPI_API_KEY>
```

Keep permanent API keys on trusted servers. `Content-Type: application/json` is required for the request body. `Idempotency-Key` is optional when the endpoint exposes it and is recommended for safe retries with the exact same body.

## Request body

`effect_id`   `string`   **required**

Stable published Effect ID from `GET /v1/effects`.

---

`effect_version`   `integer`   **optional**

Optional immutable version. Omit to use the current published version.

**Range:** x >= 1

---

`images`   `string[]`   **required**

Public HTTPS input images in the order required by the selected Effect version. Read `GET /v1/effects/{effect_id}` for the exact count and accepted media rules; upload local files with `POST /v1/files`.

**Count:** 1 to 7 items

---

`options`   `object`   **optional**

Optional controls supported by the selected Effect version. Omit unsupported controls; the catalog is the source of truth.

---

`options.aspect_ratio`   `string`   **optional**

Requested output aspect ratio when the selected Effect exposes this option.

---

`options.resolution`   `string`   **optional**

Requested output resolution when the selected Effect exposes this option.

---

`options.duration`   `integer`   **optional**

Requested video duration in seconds when the selected Effect exposes this option.

---

`options.bgm`   `boolean`   **optional**

Include background music when supported by the selected Effect.

---

`options.seed`   `integer`   **optional**

Optional deterministic seed when supported by the selected Effect.

## Response

A successful request returns HTTP `201`.

```json
{
  "data": {
    "id": "task_effect123",
    "object": "task",
    "task_kind": "effect",
    "capability_id": "video-muscle-max",
    "capability_version": 1,
    "effect_id": "video-muscle-max",
    "effect_version": 1,
    "status": "queued",
    "stage": "queued",
    "created_at": 1782210000,
    "updated_at": 1782210000,
    "completed_at": null,
    "output": null,
    "usage": {
      "credits_reserved": 1.2,
      "credits_charged": 1.2,
      "credits_settled": 0,
      "credits_refunded": 0
    },
    "request_id": "req_effect123",
    "error_code": null,
    "error_message": null
  }
}
```

## Next step

Save `data.id` from the accepted response and poll `GET /v1/tasks/{task_id}` every 5–10 seconds until `status` is `succeeded` or `failed`. Read finished assets from `data.output.media`.

## Errors

| Status | Meaning                                                                                                                                                                                                                                                                                    |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400`  | Malformed JSON or a field, value or combination this endpoint does not accept (`bad_request`; the message names the field), or input refused by moderation (`content_policy_violation`). Not retryable unchanged.                                                                          |
| `401`  | No API key (`missing_api_key`), or a key that is wrong, expired, disabled or exhausted (`invalid_api_key`; the message says which). Send it as `Authorization: Bearer <key>`; the key works with or without the `sk-` prefix. Not retryable.                                               |
| `402`  | Insufficient balance (`insufficient_credits`). The account balance is zero or below the price of this request. Top up, then send it again; not retryable before that.                                                                                                                      |
| `403`  | The key or account is not permitted to make this call (`forbidden`), for example a model that is not available on free credit (a top-up unlocks it), a request from outside the key's IP allowlist, or a model outside the key's group. Not retryable.                                     |
| `404`  | Effect or requested version is unavailable (`not_found`).                                                                                                                                                                                                                                  |
| `409`  | The `Idempotency-Key` was already used with a different request body or path within 24 hours, or the first request with it is still running (`idempotency_conflict`). Not retryable unchanged.                                                                                             |
| `429`  | Too many requests (`rate_limit_exceeded`, including the free-model limits). Retryable after `Retry-After` seconds (also `error.retry_after_seconds`).                                                                                                                                      |
| `500`  | Unexpected internal error (`internal_error`). Retryable; keep `request_id` for support if it persists.                                                                                                                                                                                     |
| `503`  | The request could not be completed (`processing_unavailable`, `processing_timeout`, `processing_failed` or `result_transfer_failed`). Nothing was charged. Retryable with backoff; a 503 carries no `Retry-After` header and no `retry_after_seconds`. BeatAPI does not answer 502 or 504. |