Skip to main content

ActiveCampaign ExecModule

Overview

ActiveCampaignModule connects ValkyrAI workflows to the tenant-scoped ActiveCampaign API v3 for contacts, accounts, deals, lists, and tags. It exposes 14 bounded operations through the native map I/O ExecModule ABI and keeps the user API token in a READY IntegrationAccount.

The module accepts only HTTPS ActiveCampaign tenant origins, sends the token in the Api-Token header, validates record IDs, filters, tenant hosts, and write fields, caps JSON requests at 256 KiB and responses at 5 MiB, returns one offset page per execution, retries transient failures only for safe GET operations, and never automatically retries writes.

The official n8n ActiveCampaign node informed the resource and operation selection. ValkyrAI adds the generated IntegrationAccount security boundary, trusted-host enforcement, bounded payloads, explicit retry safety, normalized outputs, response identity checks, and credential redaction.

Usage

  1. Create or select a least-privilege ActiveCampaign user with access only to the intended CRM and marketing records.
  2. In ActiveCampaign, open Settings > Developer and copy the account API URL and API key.
  3. Store the API key only in the encrypted apiKey field of a ValkyrAI IntegrationAccount, set the account to READY, and bind it through ExecModuleConfig.authConfig.integrationAccount.
  4. Set accountUrl to the HTTPS tenant origin, such as https://acme.api-us1.com, without /api/3.
  5. Choose one operation and provide its conditional fields.
  6. For list operations, pass nextOffset into a later execution when hasMore is true.

Inputs

NameTypeRequiredDescriptionConstraints
operationstringYesOperation listed below.Exact allowlist of 14 values.
accountUrlstringYesActiveCampaign tenant API origin.HTTPS only; clean origin on a supported api-<region><number>.com or activehosted.com tenant host; no credentials, query, fragment, port, or /api/3 path.
recordIdintegerConditionalProvider ID for get_* and update_*.Positive integer.
recordobjectConditionalAllowlisted fields for create_* and update_*.Non-empty, at most 50 top-level fields and 256 KiB serialized; credential-like fields rejected.
queryobjectNoResource-specific list filters.At most 20 allowlisted scalar fields; values at most 2,048 characters.
offsetintegerNoZero-based collection offset.0–1,000,000; default 0.
limitintegerNoProvider page size.1–100; default 100.

Create requirements:

  • create_contact: non-empty record.email.
  • create_account: non-empty record.name.
  • create_deal: non-empty record.title and record.currency; positive record.contact, record.group, and record.stage; non-negative numeric record.value.

Contact records allow email, firstName, lastName, phone, and fieldValues. Account records allow name, accountUrl, and fields. Deal records allow title, description, contact, organization, group, stage, value, currency, owner, percent, and status.

List-query fields are resource-specific. Contacts support search, email, status, tag/list filters, time filters, id_greater, and documented ordering. Accounts support search and deal-count inclusion. Deals support search, status, owner, contact, pipeline group, stage, and tag filters. Lists and tags accept only their documented name/search filters.

Outputs

NameTypeWhen presentDescription
statusstringAlwayssuccess or error.
operationstringAlwaysNormalized operation.
resourcestringAfter validationcontacts, accounts, deals, lists, or tags.
dataobjectSingle-record successVerified provider record.
idintegerSingle-record successPositive provider identity.
itemsarrayList successOne bounded API page.
countintegerList successItems returned in this page.
totalintegerList successProvider-reported meta.total, or the bounded page end if omitted.
hasMorebooleanList successWhether another offset page exists.
nextOffsetintegerWhen another page existsOffset for the next execution.
attemptsintegerProvider call or errorHTTP attempts consumed.
errorobjectFailureRedacted code, message, and retryable fields.

CRM and marketing responses are classified restricted. Tokens, provider bodies, and record values are never copied into progress logs.

IntegrationAccount Requirements

SettingRequirement
ProviderActiveCampaign API v3
AuthenticationUser API key in the Api-Token request header
StatusExactly READY
accountNameHuman-readable tenant/user identity
apiKeyEncrypted API token, 16–2,048 non-whitespace characters
RelationshipExecModuleConfig.authConfig.integrationAccount

ActiveCampaign API keys inherit the associated user’s permissions and should be treated as secrets. Use a dedicated least-privilege user, rotate the key deliberately, and never place it in record, query, URLs, examples, logs, or WorkflowState. OAuth application lifecycle and token refresh are outside this version’s contract.

Configuration

Illustrative persisted configuration:

{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:activecampaign-revenue-automation"
},
"payloadConfig": {
"parameters": "{\"accountUrl\":\"https://acme.api-us1.com\",\"operation\":\"list_deals\",\"limit\":100,\"query\":{\"status\":0}}"
}
}

The relationship is symbolic. The generated IntegrationAccount record owns the encrypted token.

Operations

ResourceCreateGetListUpdate
Contactscreate_contactget_contactlist_contactsupdate_contact
Accountscreate_accountget_accountlist_accountsupdate_account
Dealscreate_dealget_deallist_dealsupdate_deal
Listslist_lists
Tagslist_tags

Create uses POST /api/3/{resource}, get uses GET /api/3/{resource}/{id}, list uses GET /api/3/{resource}, and update uses PUT /api/3/{resource}/{id}. Contact-list and contact-tag associations, deal notes, e-commerce connections/orders/customers, custom-field administration, automations, webhooks, deletion, and OAuth lifecycle management are deferred.

Errors and Failure Modes

FailureCauseRetry guidance
VALIDATION_ERRORMissing field, invalid tenant/ID/filter/bound, unsafe write key, invalid success shape, or invalid provider total.Correct the request; local validation sends no provider call. Invalid provider responses require compatibility review.
INTEGRATION_ACCOUNT_REQUIREDNo bound secure account.Bind the intended account.
INTEGRATION_ACCOUNT_NOT_READYAccount status is not READY.Repair or reauthorize the account.
ACTIVECAMPAIGN_HTTP_400/404Provider validation failure or missing record.Correct IDs, field shapes, pipeline/stage values, or filters.
ACTIVECAMPAIGN_HTTP_401/403Invalid token, plan restriction, or insufficient user permission.Rotate the key or correct the ActiveCampaign user’s access.
ACTIVECAMPAIGN_HTTP_429API rate limit.Reads use bounded retry and numeric Retry-After; writes remain single-attempt.
ACTIVECAMPAIGN_HTTP_5xx / NETWORK_ERRORProvider or transport failure.Reads retry up to three total attempts. Reconcile create/update state before manually retrying.
RESPONSE_TOO_LARGEProvider response exceeded 5 MiB.Narrow filters or page size.

Provider errors are bounded to 500 characters and pass through token replacement plus the shared sensitive-data policy. A failed write may have reached ActiveCampaign, so the module refuses automatic replay.

Example

Create an opted-in contact:

{
"accountUrl": "https://acme.api-us1.com",
"operation": "create_contact",
"record": {
"email": "buyer@example.com",
"firstName": "Ada",
"lastName": "Lovelace",
"phone": "+15550123456"
}
}

Expected normalized result:

{
"status": "success",
"operation": "create_contact",
"resource": "contacts",
"id": 123,
"data": {
"id": "123",
"email": "buyer@example.com",
"firstName": "Ada",
"lastName": "Lovelace"
},
"httpStatus": 201,
"attempts": 1
}

Notes

  • Pagination: one execution returns one page. Reuse nextOffset; no silent all-pages loop occurs. ActiveCampaign reports meta.total, uses a default page size of 20, and allows at most 100 records. Large contact collections should prefer orders[id]=ASC with id_greater as recommended by the provider.
  • Rate limits: the module treats HTTP 429 as transient, honors bounded numeric Retry-After, and caps retries to three safe-read attempts.
  • API limits: offset is locally capped at 1,000,000, request JSON at 256 KiB, and response JSON at 5 MiB. The provider may enforce stricter plan- or endpoint-specific limits.
  • Idempotency: GET calls are retry-safe. Creates can duplicate records and updates can complete ambiguously after a timeout, so writes are single-attempt.
  • Destructive behavior: deletion is intentionally not exposed. Creates and updates can still trigger ActiveCampaign automations, messages, scoring, and sales processes and must be governed as outbound changes.
  • Consent: creating a contact does not prove marketing consent. Workflows must establish and preserve lawful consent before subscription or campaign activity.
  • External verification: deterministic tests cover validation, routing, JSON envelopes, Api-Token authentication, offset pagination, retries, write non-retry, redaction, identity checks, trusted tenant hosts, response shapes, and annotation discovery. Live provider execution is deferred until a separately authorized ActiveCampaign account is supplied.

See the official ActiveCampaign authentication guide, pagination guide, contact reference, deals reference, and n8n ActiveCampaign node for the upstream functional reference.