> For the complete documentation index, see [llms.txt](https://scalemate.gitbook.io/scalemate-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://scalemate.gitbook.io/scalemate-api/api/launch-campaigns.md).

# Launch Campaigns

Launch a **Campaign Launcher** template with your own creatives. You build and save the template once in the visual builder at [Scalemate](https://app.scalemate.co/campaign-launcher); this endpoint launches it with the creative links you supply.

The template is **self-contained** — the ad account, campaign, ad set and ad settings all live inside it. Your request only supplies the creatives and a webhook.

> **v2 endpoint.** This launches **Campaign Launcher** templates and supports **Facebook sales templates only**. Use the [Campaign templates](https://www.scalemate.co/docs/api/campaign-templates) endpoint to see which of your templates are launchable.

### Endpoint Details

URL: `https://api.scalemate.co/api/external/v2/launch`

Method: `POST`

### Headers

```
Content-Type: application/json
X-Api-Key: <YOUR_API_KEY>
```

You can generate the API Key at the [Settings](https://app.scalemate.co/profile) page under the API Key section.

### Parameters

| Parameter                 | Type                   | Description                                                                                                                                                                                                                                         |
| ------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `template_id`             | integer (**required**) | Campaign Launcher template id. Find it via the [Campaign templates](https://www.scalemate.co/docs/api/campaign-templates) endpoint or at the end of the builder URL. The template must be **active** and **supported** (a Facebook sales template). |
| `file_links`              | array (**required**)   | Creatives to launch. Each item is either a **Google Drive URL** (string) or an **object** with per-creative metadata (see below). Only Google Drive links are supported.                                                                            |
| `webhook_url`             | string (**required**)  | Publicly accessible **HTTPS** URL. A `POST` with the launch result is sent here on completion.                                                                                                                                                      |
| `campaign_name_override`  | string (optional)      | Overrides the campaign name from the template.                                                                                                                                                                                                      |
| `adset_name_override`     | string (optional)      | Overrides all ad set names. Split numbering (`01_`, `02_`) is still appended when an ad set is split.                                                                                                                                               |
| `max_creatives_per_adset` | integer (optional)     | Overrides the template's per-ad-set max-creatives limit. Must be a positive integer.                                                                                                                                                                |

> Unlike the legacy v1 endpoint, v2 does **not** accept `pac_rules`, `config_id` or `schedule_date`, and there is **no `ad_account_id` param** — the ad account is taken from the template.

**`file_links` object form** (per-creative overrides):

| Field             | Required | Description                                     |
| ----------------- | -------- | ----------------------------------------------- |
| `url`             | yes      | Google Drive link to the creative file          |
| `title`           | no       | Ad headline for this creative                   |
| `description`     | no       | Ad primary text / description for this creative |
| `destination_url` | no       | Landing page URL for this creative              |

If an optional field is omitted, the value from the template's ad defaults is used.

### How creatives are placed

* The template's **stored ads are ignored.** Each ad set's **ad defaults** act as the prototype; one ad is created per accepted creative, **named after the file** (extension stripped).
* Ad sets can have a **creative filename filter** (set per ad set in the Campaign Launcher UI — comma-separated, case-insensitive substrings; `*` acts as a glob, e.g. `*_9x16.*`):
  * Ad set **with** a filter → receives only creatives whose filename matches.
  * Ad set **without** a filter → receives **all** supplied creatives.
* If an ad set ends up with more creatives than its max-creatives limit, it is **split into numbered copies** (`01_Name`, `02_Name`, …) — same behaviour as the builder.

### Example Request Body

```json
{
  "template_id": 123,
  "webhook_url": "https://webhook.site/your-webhook-url",
  "file_links": [
    "https://drive.google.com/file/d/1JbpRSvif7wR-6vwNA51A5pHcyHViSQ7d/view?usp=drive_link",
    {
      "url": "https://drive.google.com/file/d/1AkhHSkmPTZDVTeOGUvegy0gRNk-qVyaF/view?usp=drive_link",
      "title": "Save 40% this week",
      "description": "Limited-time offer on all plans",
      "destination_url": "https://acme.com/sale"
    }
  ],
  "campaign_name_override": "US Prospecting",
  "adset_name_override": "Broad 25-45",
  "max_creatives_per_adset": 3
}
```

### Example cURL Request

```bash
curl --location 'https://api.scalemate.co/api/external/v2/launch' \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <YOUR_API_KEY>' \
--data '{
    "template_id": 123,
    "webhook_url": "https://webhook.site/your-webhook-url",
    "file_links": [
        "https://drive.google.com/file/d/1JbpRSvif7wR-6vwNA51A5pHcyHViSQ7d/view?usp=drive_link",
        {
            "url": "https://drive.google.com/file/d/1AkhHSkmPTZDVTeOGUvegy0gRNk-qVyaF/view?usp=drive_link",
            "title": "Save 40% this week"
        }
    ]
}'
```

### Example Response

`202 Accepted`

```json
{
  "job_id": "63267564-2c14-4ccc-ab60-1a61a950a25d",
  "status": "pending",
  "message": "Launch job has been accepted and is being processed",
  "type": "launcher_v2",
  "results": null
}
```

Poll the [Launch Campaigns Status](https://www.scalemate.co/docs/api/launch-campaigns-status) endpoint with the `job_id` to track progress.

### Error Responses

| Status | Body                                                                    | Cause                                                                                                                                                          |
| ------ | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `422`  | `{ "error": "..." }`                                                    | Missing/invalid params (e.g. no `template_id`, invalid `webhook_url`, empty `file_links`), ad account not connected, or Google Drive not connected.            |
| `422`  | `{ "error": "Template not supported", "unsupported_reasons": [ ... ] }` | The template uses a feature v2 can't launch. See the [Campaign templates](https://www.scalemate.co/docs/api/campaign-templates) endpoint for the reason codes. |
| `404`  | `{ "error": "Template not found" }`                                     | No active template with that id for your account.                                                                                                              |

### Webhook Response

Sent as a `POST` to your `webhook_url` when the launch finishes. The same object (without `job_id`) is available under `results` on the [Launch Campaigns Status](https://www.scalemate.co/docs/api/launch-campaigns-status) endpoint.

The response is a **campaign → ad set → ad tree** describing what the launch created — no internal placeholders to resolve.

```json
{
  "job_id": "63267564-2c14-4ccc-ab60-1a61a950a25d",
  "status": "success",
  "campaigns": [
    {
      "remote_id": "120210000000000000",
      "name": "US Prospecting",
      "adsets": [
        {
          "remote_id": "120210000000000001",
          "name": "Broad 25-45",
          "ads": [
            {
              "remote_id": "120210000000000002",
              "name": "promo_a",
              "source_url": "https://drive.google.com/file/d/1JbpRSvif7wR-6vwNA51A5pHcyHViSQ7d/view"
            },
            {
              "remote_id": null,
              "name": "promo_b",
              "source_url": "https://drive.google.com/file/d/1AkhHSkmPTZDVTeOGUvegy0gRNk-qVyaF/view",
              "error": { "message": "..." }
            }
          ]
        }
      ]
    }
  ],
  "error": null,
  "completed_at": "2026-07-16T10:05:00Z"
}
```

| Field              | Description                                                                                                                                                                                                               |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`           | `success` (all entities created), `partial` (some ads failed), or `failed` (nothing created). On a hard error before execution, `status` is `failed`, `campaigns` is `null`, and the top-level `error` holds the message. |
| `campaigns[]`      | The campaign → ad set → ad tree this launch created. When the template **reuses an existing** campaign or ad set, it appears with its existing `remote_id` and name, and only the newly created ads are nested under it.  |
| `….adsets[].ads[]` | One entry per created ad: `remote_id`, `name` (the creative filename) and `source_url` (the link you supplied). A **failed** ad has `"remote_id": null` and an `"error"` field.                                           |
| `error`            | Top-level error message when the whole launch fails before execution; otherwise `null`.                                                                                                                                   |
| `completed_at`     | ISO 8601 timestamp of completion.                                                                                                                                                                                         |
