# cURL Examples

> Copy-paste cURL commands for the main PicX Studio API endpoints.

> [!NOTE]
> Replace `pxsk_your_key` with your actual API key in every example. The base URL is `https://api.picxstudio.com/v1`.

## Generate image

```bash
curl -X POST https://api.picxstudio.com/v1/images/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "a beautiful sunset over the ocean, cinematic lighting",
    "model": "gemini-3.1-flash-image-preview",
    "size": "2K",
    "aspect_ratio": "16:9"
  }'
```

**Response** — `200 OK`

```json
{
  "id": "img_1317c7d9b20a",
  "url": "https://cdn.picxstudio.com/api/generated/image_abc123.png",
  "model": "gemini-3.1-flash-image-preview",
  "size": "2K",
  "aspect_ratio": "16:9",
  "credits_used": 53,
  "created_at": "2026-08-14T09:52:37Z"
}
```

## Edit image

```bash
curl -X POST https://api.picxstudio.com/v1/images/edit \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "instruction": "make the colors more vibrant and add a subtle glow effect",
    "image_urls": ["https://cdn.picxstudio.com/api/generated/image_abc123.png"],
    "model": "gemini-3.1-flash-image-preview",
    "size": "1K"
  }'
```

**Response** — `200 OK`

```json
{
  "id": "img_02b1b26add59",
  "url": "https://cdn.picxstudio.com/api/edited/image_def456.png",
  "model": "gemini-3.1-flash-image-preview",
  "size": "1K",
  "credits_used": 35,
  "created_at": "2026-08-14T09:53:17Z"
}
```

## Generate video (async)

```bash
# 1. Submit the async job
curl -X POST https://api.picxstudio.com/v1/videos/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "a cat stretching and yawning on a sunny windowsill",
    "model": "fal-ai/bytedance/seedance/v2",
    "duration": 5,
    "resolution": "720p",
    "sound": true
  }'
```

**Response** — `202 Accepted`

```json
{
  "id": "903c6150-060b-4b3e-bb15-79b7f56f58bc",
  "status": "pending",
  "type": "video",
  "model": "fal-ai/bytedance/seedance/v2",
  "poll_url": "/v1/generations/903c6150-060b-4b3e-bb15-79b7f56f58bc",
  "events_url": "/v1/generations/903c6150-060b-4b3e-bb15-79b7f56f58bc/events",
  "webhook": { "mode": "none", "id": null, "url": null, "events": [] }
}
```

```bash
# 2. Poll the generation until it completes
curl https://api.picxstudio.com/v1/generations/903c6150-060b-4b3e-bb15-79b7f56f58bc \
  -H "Authorization: Bearer pxsk_your_key"
```

**Response** — completed

```json
{
  "id": "903c6150-060b-4b3e-bb15-79b7f56f58bc",
  "status": "completed",
  "type": "video",
  "model": "fal-ai/bytedance/seedance/v2",
  "output_url": "https://cdn.picxstudio.com/videos/903c6150.mp4",
  "credits_used": 75,
  "created_at": "2026-08-14T09:54:00Z",
  "completed_at": "2026-08-14T09:55:50Z"
}
```

## Video with inline webhook

Bind a webhook so your server is notified on completion:

```bash
curl -X POST https://api.picxstudio.com/v1/videos/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "a cat jumping off a table",
    "model": "fal-ai/bytedance/seedance/v2",
    "duration": 5,
    "resolution": "480p",
    "webhook": { "url": "https://your-server.com/webhook" }
  }'
```

## Video modes

`POST /v1/videos/generate` takes a `mode` selecting what drives the render. Each mode has its own required inputs. Every mode except `lipsync` requires a non-empty `prompt`; `duration`, `resolution`, and `sound` are sent and priced for **every** mode, including `lipsync`.

```bash
# image — animate a single source image (needs prompt + image_url)
curl -X POST https://api.picxstudio.com/v1/videos/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "image",
    "prompt": "slow zoom out, gentle wind",
    "image_url": "https://cdn.picxstudio.com/uploads/api/scene.png",
    "duration": 5,
    "resolution": "720p"
  }'

# reference — guide the render with up to 10 reference images (needs prompt + reference_urls)
curl -X POST https://api.picxstudio.com/v1/videos/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "reference",
    "prompt": "the same character walking through a market",
    "reference_urls": [
      "https://cdn.picxstudio.com/uploads/api/ref1.png",
      "https://cdn.picxstudio.com/uploads/api/ref2.png"
    ],
    "duration": 5
  }'

# frames — interpolate from a start frame (needs prompt + start_frame_url; end_frame_url optional)
curl -X POST https://api.picxstudio.com/v1/videos/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "frames",
    "prompt": "smooth transition between the two frames",
    "start_frame_url": "https://cdn.picxstudio.com/uploads/api/first.png",
    "end_frame_url": "https://cdn.picxstudio.com/uploads/api/last.png",
    "duration": 5
  }'

# extend — continue an existing video (needs prompt + source_video_url)
curl -X POST https://api.picxstudio.com/v1/videos/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "extend",
    "prompt": "the car keeps driving down the coast road",
    "source_video_url": "https://cdn.picxstudio.com/uploads/api/clip.mp4",
    "duration": 5
  }'

# lipsync — drive the lips from an audio track (needs source_video_url + audio_url; NO prompt)
# duration/resolution/sound are still sent because the job is priced from them.
curl -X POST https://api.picxstudio.com/v1/videos/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "lipsync",
    "source_video_url": "https://cdn.picxstudio.com/uploads/api/speaker.mp4",
    "audio_url": "https://cdn.picxstudio.com/uploads/api/voiceover.mp3",
    "duration": 5,
    "resolution": "720p",
    "sound": true
  }'

# edit — edit a source video guided by an image (needs prompt + source_video_url + image_url)
curl -X POST https://api.picxstudio.com/v1/videos/generate \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "edit",
    "prompt": "restyle the scene as a watercolor painting",
    "source_video_url": "https://cdn.picxstudio.com/uploads/api/clip.mp4",
    "image_url": "https://cdn.picxstudio.com/uploads/api/style.png",
    "duration": 5
  }'
```

Each of these returns the same `202 Accepted` body shown under **Generate video (async)** above; poll `GET /v1/generations/{id}` for the result.

## Stream events via SSE

Real-time status updates without polling:

```bash
curl -N https://api.picxstudio.com/v1/generations/903c6150-060b-4b3e-bb15-79b7f56f58bc/events \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Accept: text/event-stream"
```

Each SSE frame is a JSON snapshot. The stream closes when the job reaches a terminal status.

## Templates

Search the public template catalogue (~50,000 approved templates). Requires an API key; charges no credits.

```bash
# Search "golden hour", image only, first page
curl "https://api.picxstudio.com/v1/templates?q=golden%20hour&media_type=image&limit=30&offset=0" \
  -H "Authorization: Bearer pxsk_your_key"

# Topic bucket + repeatable tags (any-match) + trending sort
curl "https://api.picxstudio.com/v1/templates?topic=fashion&tags=portrait&tags=studio&trending=true" \
  -H "Authorization: Bearer pxsk_your_key"

# Fetch one template by id
curl https://api.picxstudio.com/v1/templates/10423 \
  -H "Authorization: Bearer pxsk_your_key"
```

**Response** — `200 OK`

```json
{
  "templates": [
    {
      "id": "10423",
      "title": "Golden hour portrait",
      "prompt": "a portrait bathed in warm golden-hour light, shallow depth of field",
      "media_type": "image",
      "topic": null,
      "tags": ["portrait", "aesthetic"],
      "target_model": "gemini-3.1-flash-image-preview",
      "preview_url": "https://cdn.picxstudio.com/templates/10423/preview.jpg",
      "thumbnail_url": "https://cdn.picxstudio.com/templates/10423/thumb.jpg",
      "is_featured": true,
      "likes": 1284
    }
  ],
  "total": 31,
  "limit": 30,
  "offset": 0
}
```

> [!IMPORTANT]
> `total` is an **estimate**, not a count (no `COUNT` is run over the ~50k rows). It only signals whether another page exists. Page by increasing `offset` until a page returns fewer than `limit` templates. Also note: the `topic` field on every row is always `null` (topic is a query-time keyword filter, not a stored column), and `prompt` is `null` on premium/gated templates by design — `null` means gated, not missing. See [Templates](/docs/api-reference/templates) for the full field reference.

## List models

```bash
# All models (public — no auth required)
curl https://api.picxstudio.com/v1/models

# Filter by type
curl "https://api.picxstudio.com/v1/models?type=video"
curl "https://api.picxstudio.com/v1/models?type=image"
```

## Account and usage

```bash
# Account info
curl https://api.picxstudio.com/v1/account/me \
  -H "Authorization: Bearer pxsk_your_key"

# Usage stats
curl "https://api.picxstudio.com/v1/account/usage?period=30d" \
  -H "Authorization: Bearer pxsk_your_key"
```

## Generations

```bash
# List generations (with optional filters)
curl "https://api.picxstudio.com/v1/generations?type=video&limit=10" \
  -H "Authorization: Bearer pxsk_your_key"

# Cancel a pending generation
curl -X DELETE https://api.picxstudio.com/v1/generations/GENERATION_ID \
  -H "Authorization: Bearer pxsk_your_key"
```

## Webhooks

```bash
# Create a webhook
curl -X POST https://api.picxstudio.com/v1/webhooks \
  -H "Authorization: Bearer pxsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhook",
    "events": ["generation.completed", "generation.failed"]
  }'
# Response includes "secret": "whsec_..." — save it immediately

# List webhooks
curl https://api.picxstudio.com/v1/webhooks \
  -H "Authorization: Bearer pxsk_your_key"

# Test a webhook (sends a synthetic event)
curl -X POST https://api.picxstudio.com/v1/webhooks/WEBHOOK_ID/test \
  -H "Authorization: Bearer pxsk_your_key"

# View delivery history
curl https://api.picxstudio.com/v1/webhooks/WEBHOOK_ID/deliveries \
  -H "Authorization: Bearer pxsk_your_key"

# Redeliver a failed delivery
curl -X POST https://api.picxstudio.com/v1/webhooks/deliveries/DELIVERY_ID/redeliver \
  -H "Authorization: Bearer pxsk_your_key"

# Delete a webhook
curl -X DELETE https://api.picxstudio.com/v1/webhooks/WEBHOOK_ID \
  -H "Authorization: Bearer pxsk_your_key"
```

## Error responses

All errors return JSON with a `detail` field:

```json
{
  "detail": "Invalid API key"
}
```

| Status | Meaning |
| --- | --- |
| 401 | Key missing, malformed, or revoked. |
| 403 | Key lacks the scope for this operation. |
| 404 | Resource does not exist. |
| 422 | Invalid parameters. |
| 429 | Rate limit exceeded. Check the `Retry-After` header. |
| 500 | Server error. Safe to retry. |
