# CRM · Auto-campaign

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## POST /crm/auto-campaign/sell-like-mad

**Generate a campaign automatically**

`operationId: AutoCampaignController_generateSellLikeMad`

Generates a complete multi-platform ad campaign from a brief — copy, creative and targeting — and returns it as a **preview**.

Nothing is published and no money is spent at this point. The preview is reviewed, regenerated or edited, and only becomes a real campaign when approved.

#### Signature

```http
POST /crm/auto-campaign/sell-like-mad (body) -> The generated campaign preview — per-platform creative plus predictions (reach, clicks, CPC, and `projectedRoas` / `averageOrderValue` from the promoted products' prices, null when prices are unknown)
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Generates only. Nothing runs until `POST /crm/auto-campaign/approve`.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /crm/auto-campaign/preview/{previewId}`
- `POST /crm/auto-campaign/approve`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The brief to generate from.

```json
{
  "productIds": [
    "PRD-4821"
  ],
  "totalBudget": 50,
  "budgetType": "daily",
  "durationDays": 14,
  "platforms": [
    "facebook",
    "instagram"
  ],
  "objective": "SALES",
  "brandVoice": "casual"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The generated campaign preview — per-platform creative plus predictions (reach, clicks, CPC, and `projectedRoas` / `averageOrderValue` from the promoted products' prices, null when prices are unknown) |
| `400` | Invalid request |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | No products found |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /crm/auto-campaign/preview/{previewId}

**Get a campaign preview**

`operationId: AutoCampaignController_getPreview`

Fetches a generated preview — the copy, creative and targeting proposed for each platform, before anything is published.

#### Signature

```http
GET /crm/auto-campaign/preview/{previewId} (previewId: string) -> The campaign preview
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Preview not found | No preview has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/auto-campaign/approve`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `previewId` | path | string | yes | Campaign preview id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The campaign preview |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Preview not found — No preview has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /crm/auto-campaign/preview/{previewId}

**Discard a campaign preview**

`operationId: AutoCampaignController_discardPreview`

Deletes an unapproved preview. Nothing was published, so nothing is withdrawn.

#### Signature

```http
DELETE /crm/auto-campaign/preview/{previewId} (previewId: string) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Preview not found | No preview has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/auto-campaign/sell-like-mad`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `previewId` | path | string | yes | Campaign preview id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Preview not found — No preview has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/auto-campaign/approve

**Approve and launch a generated campaign**

`operationId: AutoCampaignController_approveCampaign`

Turns an approved preview into a real campaign and launches it.

**This is the point money starts being spent.** Everything before it is generation and review; this publishes to the ad platforms against the budget in the brief.

#### Signature

```http
POST /crm/auto-campaign/approve (body) -> The launched campaign
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Starts real ad spend. Review every platform variation before approving.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Preview not found | No preview has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /crm/auto-campaign/preview/{previewId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Which preview to approve, with any last changes.

```json
{
  "previewId": "PRV-4821",
  "modifications": [
    {
      "platform": "instagram",
      "enabled": false
    }
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The launched campaign |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Preview not found — No preview has that id. |
| `410` | Preview expired |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/auto-campaign/preview/{previewId}/regenerate/{platform}

**Regenerate one platform's creative**

`operationId: AutoCampaignController_regeneratePlatformAds`

Regenerates the copy and creative for a single platform within a preview, leaving the others as they are — for when one platform's variation misses and the rest are fine.

#### Signature

```http
POST /crm/auto-campaign/preview/{previewId}/regenerate/{platform} (previewId: string, platform: string, body) -> The regenerated platform variation
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Preview not found | No preview has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/auto-campaign/preview/{previewId}/variations/{platform}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `previewId` | path | string | yes | Campaign preview id. |
| `platform` | path | string | yes | Ad platform. |

### Request body

Optional guidance for the regeneration.

```json
{
  "guidance": "Make it shorter and lead with the discount"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Ads regenerated |
| `201` | The regenerated platform variation |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Preview not found — No preview has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /crm/auto-campaign/platforms

**List auto-campaign platforms**

`operationId: AutoCampaignController_getAvailablePlatforms`

The platforms auto-generated campaigns can target.

#### Signature

```http
GET /crm/auto-campaign/platforms () -> Available platforms
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/auto-campaign/sell-like-mad`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Available platforms |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/auto-campaign/ai/audience-suggestions

**Get AI audience suggestions**

`operationId: AutoCampaignController_getAudienceSuggestions`

Suggests audiences to target for a campaign brief. Suggestions only — nothing is created, and each still needs reviewing against your own data.

#### Signature

```http
POST /crm/auto-campaign/ai/audience-suggestions (body) -> Suggested audiences
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/marketing/audiences/estimate-reach`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The brief to suggest audiences for.

```json
{
  "product": "Cola 330ml multipack",
  "goal": "conversions"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Suggested audiences |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | No products found |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/auto-campaign/preview/{previewId}/variations/{platform}

**Generate creative variations**

`operationId: AutoCampaignController_getCopyVariations`

Produces alternative creatives for one platform, so several can be compared — or tested against each other — before approval.

#### Signature

```http
POST /crm/auto-campaign/preview/{previewId}/variations/{platform} (previewId: string, platform: string, body) -> The generated variations
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Preview not found | No preview has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /crm/auto-campaign/preview/{previewId}/predictions/{platform}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `previewId` | path | string | yes | Campaign preview id. |
| `platform` | path | string | yes | Ad platform. |

### Request body

How many variations, and any guidance.

```json
{
  "count": 3
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The generated variations |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Preview not found — No preview has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /crm/auto-campaign/preview/{previewId}/predictions/{platform}

**Get performance predictions**

`operationId: AutoCampaignController_getPerformancePredictions`

Predicted performance for a platform's creative before it runs — estimated reach and engagement.

These are model estimates, not commitments. Treat them as a way to compare variations against each other, not as a forecast of actual results.

#### Signature

```http
GET /crm/auto-campaign/preview/{previewId}/predictions/{platform} (previewId: string, platform: string) -> Predicted performance — impressions, clicks, CPC and, when product prices are known, `projectedRoas: { min, max }` and `averageOrderValue`. A daily budget counts as spend on every day of the run.
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Estimates only — useful for ranking variations, not for budgeting.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Preview not found | No preview has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/auto-campaign/preview/{previewId}/variations/{platform}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `previewId` | path | string | yes | Campaign preview id. |
| `platform` | path | string | yes | Ad platform. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Predicted performance — impressions, clicks, CPC and, when product prices are known, `projectedRoas: { min, max }` and `averageOrderValue`. A daily budget counts as spend on every day of the run. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Preview not found — No preview has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/auto-campaign/ai/generate-images

**Generate campaign images**

`operationId: AutoCampaignController_generateAdImages`

Generates ad imagery from a prompt. Generated images may still need rights and brand review before use — this does not check either.

#### Signature

```http
POST /crm/auto-campaign/ai/generate-images (body) -> The generated images
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Review generated imagery before publishing — nothing here checks brand or likeness rights.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/auto-campaign/preview/{previewId}/variations/{platform}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to generate.

```json
{
  "prompt": "A chilled cola can on ice, summer sunlight",
  "count": 3
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The generated images |
| `400` | No products found |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /crm/auto-campaign/health

**Get auto-campaign health**

`operationId: AutoCampaignController_healthCheck`

Whether the generation and publishing pipeline is working. Check this first when generation fails.

#### Signature

```http
GET /crm/auto-campaign/health () -> Pipeline health
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /crm/auto-campaign/platforms`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Pipeline health |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

