Skip to main content

Klaviyo ExecModule

Overview

KlaviyoModule connects ValkyrAI workflows to Klaviyo's stable Profiles, Lists, Events, and Metrics APIs. It exposes 13 bounded operations through the native map I/O ExecModule ABI and keeps the private API key in a READY IntegrationAccount.

The module fixes all production calls to https://a.klaviyo.com/api, sends JSON:API requests with revision 2026-07-15, validates IDs, filters, cursors, event/profile/list payloads, caps requests and responses at 5 MiB, returns one cursor page per execution, retries transient failures only for safe GET operations, verifies response identities, and redacts credentials from failures.

n8n's Klaviyo integration currently uses its generic HTTP Request node, which informed the broad HTTP/auth workflow reference. ValkyrAI provides a native typed connector with IntegrationAccount isolation, fixed-host enforcement, explicit operations, bounded JSON:API envelopes, write-reconciliation semantics, normalized outputs, and metadata discovery.

Usage

  1. Create a Klaviyo private API key with only the scopes required by the selected operations.
  2. Store the key only in the encrypted apiKey field of a ValkyrAI IntegrationAccount, set the account to READY, and bind it through ExecModuleConfig.authConfig.integrationAccount.
  3. Choose one operation and provide its conditional identifiers or payload.
  4. For list operations, pass nextCursor into a later execution when hasMore is true.
  5. Give every create_event call a durable caller-owned uniqueId; reuse that same value only when reconciling the same logical event.
  6. Set confirmRemove: true only after reviewing the exact list/profile relationship to remove.

Inputs

NameTypeRequiredDescriptionConstraints
operationstringYesOperation listed below.Exact allowlist of 13 values.
profileIdstringConditionalKlaviyo profile ID.1–128 letters, digits, _, or -; required by profile get/update and membership operations.
listIdstringConditionalKlaviyo list ID.Same bounded identifier contract; required by list get/update and membership operations.
recordobjectConditionalProfile or list attributes.Non-empty allowlist; at most 50 profile fields or exactly the list name; recursive credential-like fields rejected.
eventobjectConditionalCustom-event definition.Requires metricName, profile, properties, and uniqueId; at most eight top-level fields and 5 MiB serialized.
filterFieldstringNoExact-match list filter field.Profiles: email, phone_number, external_id; events: profile_id, metric_id.
filterValuestringConditionalValue paired with filterField.At most 320 characters; control characters rejected.
cursorstringNoOpaque cursor from nextCursor.1–2,048 bounded opaque characters; never treated as a URL.
pageSizeintegerNoProvider page size.1–100; default 20.
confirmRemovebooleanConditionalGuard for remove_profile_from_list.Must be exactly true.

Profile attributes allow email, phone_number, external_id, first_name, last_name, organization, locale, title, image, and properties. create_profile requires at least one of email, phone_number, or external_id. Custom event profile identifiers allow id, email, phone_number, and external_id; use only identifiers known to describe the same profile.

The event object supports:

FieldRequiredDescription
metricNameYesExisting or new Klaviyo metric name, up to 255 characters.
profileYesOne to four known profile identifiers.
propertiesYesEvent properties object with at most 400 top-level fields.
uniqueIdYesCaller-owned deduplication identifier, 1–255 characters.
timeNoProvider-supported event timestamp; include it for historical data.
valueNoNumeric event value.
backfillNoSet true for historical imports that must not trigger live flows.

Outputs

NameTypeWhen presentDescription
statusstringAlwayssuccess or error.
operationstringAlwaysNormalized operation.
resourcestringAfter validationprofiles, lists, events, metrics, or list-profiles.
dataobjectSingle/action successVerified JSON:API resource or normalized action receipt.
idstringSingle-resource successVerified provider identity.
itemsarrayList successOne bounded JSON:API page.
countintegerList successItems returned in this execution.
hasMorebooleanList successWhether a trusted next link supplied another cursor.
nextCursorstringWhen another page existsOpaque cursor for the next execution.
httpStatusintegerProvider successProvider HTTP status, including 202 for accepted events.
attemptsintegerProvider call or errorHTTP attempts consumed.
requestIdstringWhen suppliedKlaviyo request trace identifier.
errorobjectFailureRedacted code, message, and retryable fields.

Customer and event data are classified restricted. API keys, provider bodies, filters, event properties, and profile fields are not copied into progress logs.

IntegrationAccount Requirements

SettingRequirement
ProviderKlaviyo stable JSON:API
AuthenticationPrivate API key in Authorization: Klaviyo-API-Key ...
API revision2026-07-15
StatusExactly READY
accountNameHuman-readable Klaviyo account/application identity
apiKeyEncrypted private API key, 16–2,048 non-whitespace characters
RelationshipExecModuleConfig.authConfig.integrationAccount

Grant only the required profiles:read/write, lists:read/write, events:read/write, and metrics:read scopes. Read-only workflows should omit write scopes. Never place the key in record, event, filterValue, URLs, examples, logs, or WorkflowState.

Configuration

Illustrative persisted configuration:

{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:klaviyo-lifecycle-automation"
},
"payloadConfig": {
"parameters": "{\"operation\":\"list_profiles\",\"filterField\":\"email\",\"filterValue\":\"buyer@example.com\",\"pageSize\":20}"
}
}

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

Operations

ResourceOperations
Profileslist_profiles, get_profile, create_profile, update_profile
Listslist_lists, get_list, create_list, update_list
Membershipadd_profile_to_list, remove_profile_from_list
Eventslist_events, create_event
Metricslist_metrics

Profiles and lists use the corresponding /api/{resource} JSON:API routes. Membership operations use /api/lists/{listId}/relationships/profiles. Events use /api/events, and metrics use /api/metrics.

Bulk imports, subscriptions/consent mutations, segments, flows, templates, catalogs, reporting, campaigns, webhooks, conversations, push tokens, profile merges/suppressions, and deletion are deferred. The beta multi-channel Campaigns API is deliberately excluded from version 1.0.0.

Errors and Failure Modes

FailureCauseRetry guidance
VALIDATION_ERRORMissing/unsafe field, invalid ID/filter/cursor/bound, untrusted next link, mismatched identity, or incompatible success shape.Correct the request; local validation sends no provider call. Provider-shape failures need 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.
KLAVIYO_HTTP_400/404Provider validation failure or missing resource.Correct JSON:API shapes, IDs, filters, event profile identifiers, or metric names.
KLAVIYO_HTTP_401/403Invalid key or insufficient private-key scope.Rotate the key or grant only the missing scope.
KLAVIYO_HTTP_409Resource conflict or duplicate relationship state.Read the current resource/relationship before deciding whether to retry.
KLAVIYO_HTTP_429API rate limit.Reads use bounded retry and numeric Retry-After; writes remain single-attempt.
KLAVIYO_HTTP_5xx / NETWORK_ERRORProvider or transport failure.Reads retry up to three total attempts. Reconcile mutations before manually retrying.
RESPONSE_TOO_LARGEProvider response exceeded 5 MiB.Narrow the filter or page size.

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

Example

Record a custom event with an explicit deduplication key:

{
"operation": "create_event",
"event": {
"metricName": "Viewed Enterprise Plan",
"profile": {
"email": "buyer@example.com"
},
"properties": {
"plan": "enterprise",
"source": "pricing-page"
},
"uniqueId": "evt-20260811-001",
"backfill": false
}
}

Expected normalized result:

{
"status": "success",
"operation": "create_event",
"resource": "events",
"data": {
"accepted": true
},
"httpStatus": 202,
"attempts": 1
}

Notes

  • Pagination: one execution returns one page. Reuse nextCursor; the module never follows provider URLs or silently loops all pages.
  • Rate limits: Klaviyo uses endpoint-specific burst and steady limits. The module treats 429 as transient, honors bounded numeric Retry-After, and caps retries to three safe-read attempts.
  • API limits: pageSize is locally capped at 100, request and response JSON at 5 MiB, event properties at 400 top-level fields, and event uniqueId at 255 characters. Klaviyo may enforce stricter endpoint or plan limits.
  • Idempotency: GET calls are retry-safe. create_event is logically deduplicated by the caller-owned uniqueId; other writes are single-attempt and require read-after-write reconciliation after ambiguous failures.
  • Destructive behavior: profile and list deletion are not exposed. remove_profile_from_list requires confirmRemove: true. List membership and event/profile changes can alter flows, segmentation, and outbound customer messaging.
  • Consent: creating a profile or adding it to a list does not establish lawful email/SMS consent. Subscription endpoints are intentionally deferred; workflows must use an approved consent source and preserve audit evidence.
  • Historical data: set the source event time and backfill: true for historical replays so existing flows do not send duplicate live messages.
  • External verification: deterministic tests cover validation, fixed routing, JSON:API envelopes, key/revision headers, cursor pagination, trusted next links, typed filters, retries, write non-retry, redaction, response identities, membership guards, and annotation discovery. Live provider execution is deferred until a separately authorized Klaviyo account is supplied.

See the official Klaviyo API overview, Profiles API, Lists API, Events API, and n8n Klaviyo integration for upstream behavior and workflow reference.