# ads_draft_launch

> Draft an ad launch

`POST /api/v2/ads/launches`

Makes a DRAFT only. Nothing launches or spends until a person opens review_url and presses Launch. Needs the `ads:write` scope.

- Auth: API key (Authorization: Bearer)
- Key scope needed: `ads:write`
- Raw spec: https://app.diffusr.ai/api/v2/openapi.json

## Request body (JSON)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `ad_account_id` | string | yes | An id from ads_list_accounts. Its platform (Meta or TikTok) and currency come with it. |
| `name` | string | no | The campaign's name. Leave out for "<account> · <date>". |
| `goal` | "traffic" \| "sales" | yes | "traffic" = visits to a site; "sales" = purchases, needs pixel_id. |
| `pixel_id` | string | no | Sales only: the Meta pixel / TikTok pixel code to count purchases with. |
| `daily_budget` | number | yes | What the whole launch may spend a day, in the account's currency as people say it: 20 = $20 a day. |
| `start_at` | string | no | Leave out to start as soon as it's approved. |
| `end_at` | string | no | Leave out to run until paused. |
| `countries` | string[] | yes | Two-letter country codes, like ["US", "CA"]. |
| `age_min` | integer | no | Default 18. |
| `age_max` | integer | no | Default 65. |
| `gender` | "all" \| "female" \| "male" | no | Default "all". |
| `ads` | object[] | yes | One ad per video or picture, each with its own words. |
| `ads[].creative_id` | string | yes | An id from ads_list_creatives. |
| `ads[].text` | string | yes | The ad's words over the video. TikTok allows 100 characters, Meta far more (first ~125 show). |
| `ads[].headline` | string | no | Meta only, optional: the bold line under the video. |
| `ads[].cta` | "learn_more" \| "shop_now" \| "sign_up" \| "download" \| "contact_us" \| "book_now" | yes | The button. |
| `ads[].url` | string | yes | Where the button goes. Must start with https://. |

## Example

**cURL**

```bash
curl -X POST "https://app.diffusr.ai/api/v2/ads/launches" \
  -H "Authorization: Bearer $DIFFUSR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "ad_account_id": "ACCOUNT_ID",
  "goal": "traffic",
  "daily_budget": 20,
  "countries": [
    "US"
  ],
  "ads": [
    {
      "creative_id": "asset:CREATIVE_ID",
      "text": "Fresh and fizzy.",
      "cta": "shop_now",
      "url": "https://example.com"
    }
  ]
}'
```

## Response

### 201 ApiAdsLaunch

A DRAFT with a review_url.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes |  |
| `status` | string | yes |  |
| `step` | string \| null | yes |  |
| `error` | string \| null | yes |  |
| `platform` | string | yes |  |
| `account` | string | yes |  |
| `name` | string | yes |  |
| `daily_budget` | number | yes |  |
| `currency` | string | yes |  |
| `review_url` | string \| null | yes |  |
| `open_url` | string \| null | yes |  |
| `live_at` | string \| null | yes |  |
| `next` | string | yes |  |

## Errors

Every error body is `{ error, code, request_id, ... }`. See https://diffusr.ai/docs/errors.

- 401: Missing, wrong, revoked or expired API key (code UNAUTHORIZED, KEY_REVOKED, KEY_EXPIRED).
- 403: The key may not do this (SCOPE_DENIED, MODEL_NOT_ALLOWED, TEST_MODE_UNSUPPORTED, ACCOUNT_BLOCKED, allowance_exceeded).
- 404: No such id, or it is not yours, or it belongs to the other key mode (NOT_FOUND).
- 422: The request is not valid (VALIDATION_FAILED, INVALID_JSON, PREFLIGHT_FAILED, CALLBACK_URL_INVALID, REFERENCE_*). `issues` lists each problem. Nothing was charged.
- 429: Too many requests or jobs (RATE_LIMITED, CONCURRENCY_LIMIT, UPLOAD_QUOTA, …). Wait Retry-After seconds, then retry.
- 500: Our fault (INTERNAL_ERROR). Quote request_id to support.
- 503: Paused or busy (API_PAUSED, MODEL_PAUSED, PROVIDER_PAUSED, PROVIDER_BUSY, UNAVAILABLE). Wait Retry-After seconds, then retry.

## Charges

Free. Makes a draft only; nothing launches or spends until a person presses Launch in the app.
