---
name: activecampaign-api
description: Authenticate against and call the ActiveCampaign REST API v3 and Remote MCP server. Covers finding the account-specific base URL, the Api-Token header, pagination, rate-limit and error handling, and where to look up individual endpoints. Use when a task involves reading or writing ActiveCampaign contacts, lists, tags, campaigns, automations, deals, accounts, or custom fields.
license: Proprietary
compatibility: Requires network access to the user's ActiveCampaign account and a per-user API token supplied by the user.
metadata:
  author: activecampaign
  version: "1.0"
---

# ActiveCampaign API

Two ways to reach an ActiveCampaign account. Pick based on what the user has given you.

| You have | Use |
| --- | --- |
| A Remote MCP URL | The MCP server — tools are already wired up, no HTTP plumbing needed |
| An API token + account name | The REST API v3 directly |

Prefer MCP when it's available. It is the supported agent surface and keeps the credential out of your request construction.

## Credentials come from the user

Never guess, construct, or hunt for these. Both live in the ActiveCampaign app under **Settings → Developer**, and the user must paste them to you:

- **API token** — per *user*, not per account. Two users in the same account have different tokens.
- **Remote MCP URL** — unique per user, **with the credential embedded in the URL itself**.

Because the MCP URL *is* a secret, treat it like a password: don't log it, don't echo it back in full, and don't commit it. There is no OAuth flow for the ActiveCampaign API — no authorization server, no client registration, no refresh tokens. If you find yourself looking for an OAuth endpoint, stop; the token is the whole mechanism.

## REST API v3

Base URL is account-specific:

```
https://{account}.api-us1.com/api/3/
```

`{account}` is the subdomain of the user's ActiveCampaign URL. If they log in at `https://acme.activecampaign.com`, then `{account}` is `acme`. Ask if you don't know it — do not probe for it.

Authenticate with the `Api-Token` header:

```http
GET /api/3/contacts HTTP/1.1
Host: acme.api-us1.com
Api-Token: <token>
Accept: application/json
```

The token goes in the header. Not a query string, not a bearer token, not basic auth.

### Looking up endpoints

Do not guess endpoint paths or payload shapes. The full reference is machine-readable:

- **Index of every doc page:** <https://developers.activecampaign.com/llms.txt>
- **Any doc page as Markdown:** append `.md` to its URL — e.g. `https://developers.activecampaign.com/reference/authentication.md`

Fetch the relevant reference page before writing a call. There is no public OpenAPI/Swagger document, so the docs are the source of truth.

### Pagination

List endpoints page via `limit` and `offset`:

```
GET /api/3/contacts?limit=100&offset=200
```

Do not assume one response is a complete list. The default page size is small, and silently truncating is the most common way to get an ActiveCampaign integration subtly wrong.

**`meta.total` is not universally present.** Many collection endpoints return it; a number of the campaign reporting endpoints deliberately do not. So:

- If `meta.total` is present, page until you have seen that many records.
- If it is absent, page until a response comes back shorter than `limit`.

Write your paging loop to handle both — keying on `meta.total` alone will stop early on the endpoints that omit it. Some endpoints also cap `limit + offset` (for example at `1000`) and return `422` for a deeper window, so check the reference page for the specific endpoint before deep-paging a large collection.

### Errors

| Status | Meaning | What to do |
| --- | --- | --- |
| 401 / 403 | Token invalid, revoked, or lacks access | Stop and ask the user for a fresh token. Do not retry. |
| 404 | Record or endpoint doesn't exist | Re-check the path against the docs before assuming the record is missing. |
| 422 | Validation failure | Read the `errors` array — it names the offending field. |
| 429 | Rate limited | Back off and retry. |

The API rate-limits per account. Consult the current documented limit rather than hard-coding a number, and serialize bulk work instead of firing requests in parallel.

## Writing data safely

Contact and campaign data is production marketing data — a bad write can email real customers.

- **Read before you write.** Confirm a record's current state before updating it.
- **Confirm destructive actions.** Deletes, bulk imports, list removals, and anything that can trigger a send should be confirmed with the user first, with the affected record count stated.
- **Sync, don't duplicate.** Creating a contact whose email already exists is the usual cause of duplicates. Look the address up first, then update rather than create.
- **Automations have side effects.** Enrolling a contact can start a real email sequence immediately. Treat enrollment as a send, not a data edit.

## Reference

- API docs: <https://developers.activecampaign.com>
- Authentication: <https://developers.activecampaign.com/reference/authentication>
- Remote MCP server: <https://developers.activecampaign.com/page/mcp>
- MCP tool index: <https://developers.activecampaign.com/page/mcp-available-tools/>
- Agent auth guide: <https://www.activecampaign.com/auth.md>
