# Campaigns, automations and agents

> Bulk sends, journey enrollment, AI agents, scheduled messages and Postman.

Source: https://developers.converzap.com/en/campanhas-e-automacoes

Campaigns, automations, AI agents and scheduled messages follow **the same rules as the app**: whatever the API refuses, the app would refuse too.

## Bulk template campaign

1. Pick the number (`GET https://api.converzap.com/v1/channels`) and an **approved** template (`GET https://api.converzap.com/v1/templates?status=approved`).
2. Create the draft — nothing is sent yet:

```bash
curl -X POST https://api.converzap.com/v1/campaigns \
  -H "Authorization: Bearer czk_live_YOUR_KEY" \
  -H "Idempotency-Key: black-friday-campaign-1" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Black Friday",
    "channel": "123456789012345",
    "template_id": "TEMPLATE_UUID",
    "variables": { "body:1": { "kind": "field", "field": "first_name", "fallback": "customer" } },
    "audience": { "labels": ["customer"], "exclude_labels": ["inactive"] },
    "rate_per_minute": 60
  }'
```

3. Start it: `POST https://api.converzap.com/v1/campaigns/{id}/start`. With a future `scheduled_at` it becomes `scheduled`; otherwise it goes to `sending`.
4. Track it with `GET https://api.converzap.com/v1/campaigns/{id}` (`stats`: sent, delivered, read, failed, skipped) and control it with `pause`, `resume` and `cancel`.

**Variables**: each template variable (`body:1`, `body:name`, `header:1`, `button:0`) gets a contact field (`first_name`, `name`, `company`, `city`, `uf`, `email`, `phone` — plus, from the contact's company data found by enrichment, `razao_social`, `cnpj`, `endereco_empresa` and `socios`, up to 3), a custom field (`{"kind": "custom", "key": "plan"}`) or fixed text (`{"kind": "text", "value": "BF10"}`). A contact with no value and no `fallback` is skipped (instead of a Meta error).

**Audience**: `all`, `list_ids`, `labels`, `segment_ids` and the exclusions `exclude_labels` / `exclude_segment_ids`. Opted-out contacts, landlines and contacts without a phone are never included.

**Common errors**: `402 limit_reached` (the plan's monthly contact limit or a number outside the plan), `409 conflict` (action not valid in the current state, e.g. starting a campaign that already started), `400 invalid_request` with `errors[]` listing what is missing to start.

## Automations (journeys)

Automations are built in the app; through the API you list them and **enroll contacts**:

```bash
curl -X POST https://api.converzap.com/v1/automations/{id}/enrollments \
  -H "Authorization: Bearer czk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contact_id": "CONTACT_UUID" }'
```

- The automation must be `active` (otherwise `409`).
- **Each contact goes through an automation once**: enrolling again returns `409`.
- `DELETE https://api.converzap.com/v1/automations/{id}/enrollments/{contact_id}` stops the journey (`stopped`).
- Tip: to start a journey from your system, create the automation with a **manual** trigger and enroll through the API.

## AI agents

- `GET https://api.converzap.com/v1/agents` lists the agents (status `draft`, `active`, `paused`).
- `POST https://api.converzap.com/v1/agents/{id}/activate` turns the agent on; with `{"channel": "<phone_number_id>"}` it goes live on that number. The activation checklist, the active agent limit and "one agent per number" apply as in the app.
- `POST https://api.converzap.com/v1/agents/{id}/pause` stops replies.
- To take over or hand back ONE conversation, use `POST https://api.converzap.com/v1/conversations/{id}/ai-agent`.

## Scheduled messages

`POST https://api.converzap.com/v1/conversations/{id}/scheduled-messages` with `send_at` (1 minute to 30 days ahead) and `text` **or** `template` (`id` or `name` + `language`, with `params` as when sending). Text only if the 24-hour window is still open at the chosen time (otherwise `409 outside_24h_window`). With `cancel_if_replied` (default) the message is not sent if the contact writes first. Cancel: `DELETE https://api.converzap.com/v1/scheduled-messages/{id}`.

## Postman and Insomnia

1. In Postman: **Import → Link** and paste `https://api.converzap.com/v1/openapi.json?lang=en`.
2. In the new collection, **Authorization → Bearer Token** with your key (ideally in an environment variable, never in code).
3. The `baseUrl` already comes as `https://api.converzap.com/v1`.

In Insomnia: **Create → Import → From URL** with the same address. Re-import when the [changelog](https://developers.converzap.com/en/changelog) announces a new version.
