Skip to main content
The Klaviyo integration keeps your Sotto and Klaviyo audiences in step, in both directions. You connect it with a Klaviyo private API key, and each of the three capabilities can be toggled separately. All capabilities start disabled when you first connect. Saving a key stores your credentials and tests them, but nothing syncs or pushes until you switch each capability on:

API key and scopes

Sotto authenticates to Klaviyo with a private API key, created in Klaviyo under Settings → Account → API keys. A full-access key enables everything. If you prefer a restricted key (recommended), grant it the scopes for the features you plan to use: To enable the full integration, grant all seven scopes: lists:read, lists:write, segments:read, profiles:read, profiles:write, subscriptions:write, and events:write.
Sotto’s connection test validates the key with a read-only call, so it only proves the lists:read scope. A key missing the write scopes will test as healthy and then be rejected when the first profile or consent push runs. When Klaviyo rejects the key as unauthorized, Sotto pauses all pushes for your account automatically (no further calls are attempted) and the integration status shows the reason. (Only definitive authentication failures pause pushes; a transient Klaviyo error or outage never does.) Klaviyo keys cannot have scopes added after creation, so the fix is to create a new key with the right scopes and save it in Sotto: the save re-tests the key and pushes resume automatically. Testing the connection after fixing the key in Klaviyo resumes pushes the same way. Users whose changes were skipped while paused catch up on their next change.
The API key is write-only in Sotto: it is never displayed again after you save it. To rotate it, generate a new key in Klaviyo with the same scopes and enter it in Sotto; the old key can then be deleted in Klaviyo.

Profile push

Required scopes: profiles:write Whenever a user is created or changes in Sotto, their profile is pushed to Klaviyo within seconds. A push is triggered when a user:
  • is created or updated (including imports and API updates),
  • opts in to or out of SMS messaging,
  • has a custom data value change, or
  • records a purchase.
Changes that arrive from Klaviyo are never pushed back. Users created by list and segment sync and users created or updated through the inbound endpoint below are excluded from profile push for that change. Your Klaviyo data is not echoed back at you, and a Klaviyo flow that calls the inbound endpoint cannot create an update loop. The next genuine Sotto-side change to such a user (a reply, a purchase, a portal edit) pushes normally.

Field mapping

Pushes are upserts: Klaviyo matches profiles by phone number and email, so existing profiles are updated in place and no duplicates are created. Sotto stores the resulting Klaviyo profile ID alongside the user. Pushes are also self-healing: a transient failure (for example a Klaviyo rate limit) is retried automatically for a few minutes. If a push cannot be delivered, it is dropped rather than queued forever: the user’s next change pushes their complete, current profile, so nothing stays stale for long.

Custom data

Custom data is an option of the profile push, not a separate push: the properties travel in the same Klaviyo call as the profile attributes, so it needs no extra scope and cannot be enabled on its own.
  • Profile push on, custom data on: attributes, custom data properties and sotto_date_created are pushed.
  • Profile push on, custom data off: only the profile attributes are pushed. Use this to share contact fields with Klaviyo without sharing your business-specific custom data.
  • Profile push off: nothing is pushed to the profile, and custom data cannot be enabled.
Every custom data property is prefixed sotto_, the same namespace the tap event properties use. Klaviyo keeps the properties from all of your integrations side by side on the profile, so the prefix keeps Sotto’s properties apart from the ones your other tools write, and a Sotto field can never overwrite one of theirs. Properties written before the prefix was introduced (see the changelog) kept the bare field name, for example favorite_hobbies. They stay on your profiles but no longer update; build segments and flows on the sotto_ names.
Turning custom data off stops future property updates; it does not remove properties already written, because Klaviyo merges properties on update and never deletes them.

Date created

With custom data on, Sotto also sends one stock property, sotto_date_created: the date and time the user was first created in Sotto, in UTC ISO 8601 to the second, for example 2026-04-16T19:35:13+00:00. Klaviyo reads it as a date, so you can segment on it with date conditions such as is after or is in the last. It is the creation date, not the opt-in date: users imported from Shopify, a CSV file, or an external signup carry the date they were imported. There is no backfill; a profile that was pushed before the property existed receives it on its next push.
date_created is a reserved name and cannot be used for a custom data field, because the field would push to the same sotto_date_created property. Look-alikes are rejected too: matching ignores case and treats spaces and hyphens as underscores, so Date Created and date-created are blocked. Names that only contain it, such as first_order_date_created, are allowed.
Required scopes: lists:write, profiles:write, subscriptions:write Consent sync reflects each user’s Sotto SMS consent onto their Klaviyo profile. It is one-way, from Sotto to Klaviyo: changes made in Klaviyo do not affect consent in Sotto, and Sotto remains the source of truth for SMS consent. A few things to know:
  • Consent is matched and applied by phone number, and is profile-level in Klaviyo. No Klaviyo list is required.
  • Optionally, Sotto can also add subscribed users to a specific Klaviyo list. Contact support@withsotto.com to configure a target list.
  • Klaviyo processes consent changes as an asynchronous job, so the new state can take 30 to 90 seconds to appear in Klaviyo.
  • Consent sync is best-effort: a Klaviyo-side failure (for example, no SMS sending number for the user’s region) never blocks or reverses the profile push.

Tap events

Required scopes: events:write When a tap on one of your phygital devices is attributed to a user, Sotto sends Klaviyo a metric event for that profile. The events land on the metric Phygital Device Tap unless you set your own name in Sotto. Only attributed taps are sent. A tap that Sotto cannot tie to a user, because nobody has identified themselves yet, produces no event.

Event properties

Every property is prefixed sotto_, so tap events never collide with metrics your other tools write:
sotto_device_tap_count is the device’s lifetime tap count, across everyone who has ever tapped it. It is not the number of times this profile has tapped. Building a Klaviyo segment on it as a per-profile total gives numbers that look plausible and are wrong.
Klaviyo accepts events asynchronously: a successful send means Klaviyo has accepted the event, not that it has finished processing it and made it visible on the profile. Events normally appear within seconds, but if you are reconciling counts, allow for that gap before treating an event as lost.

List and segment sync

Required scopes: lists:read, segments:read, profiles:read Sotto imports the membership of the Klaviyo lists and segments you select. Each one appears in Sotto as a segment named Klaviyo - {name} and refreshes every 3 hours:
  • Members are matched to Sotto users by phone number. Klaviyo profiles without a phone number cannot be matched and are skipped.
  • A profile with no matching Sotto user creates a new user with the profile’s phone number, name, and email. Created users start without SMS consent; syncing a list never opts anyone in.
  • Users created this way are not pushed back to Klaviyo; their profile already exists on your side, so the sync never writes to Klaviyo.
  • Membership is mirrored on every refresh: users are added when they join the Klaviyo list or segment and removed when they leave it.
  • Joining or leaving a synced segment fires segment entry and exit events, so these segments can drive Sotto automations and campaign targeting like any other segment.

Creating users from Klaviyo

Independently of the sync above, your Klaviyo flows can create or update Sotto users directly, for example from a webhook action in a Klaviyo signup flow. Send a POST to /api/v1/klaviyo/users, authenticated with your Sotto API key in the X-Bigco-Api-Key header. This is not the Klaviyo API key, and not the request signing used by the rest of the Sotto API: Klaviyo’s webhook action can only send static headers, so this endpoint deliberately uses simple key-header authentication. In Klaviyo’s webhook action, add a header named X-Bigco-Api-Key with your Sotto API key as its value. Updates made through this endpoint are never echoed back to your Klaviyo account by profile push, so it is safe to call from flows that trigger on profile changes.
string
required
The user’s phone number in E.164 format. Users are matched by phone number, so repeated calls update the same user. A missing or invalid phone number is rejected with 422 and nothing is stored.
string
The user’s email address.
string
The user’s first name.
string
The user’s last name.
string
The user’s date of birth, in MM/DD/YYYY format.
string
The user’s postal code.
object
Custom data values, keyed by the Sotto field name (loyalty_tier), not the name the field has as a Klaviyo profile property (sotto_loyalty_tier). A flow that maps a profile property back into this field must send the Sotto name. Every field name must already be configured for your brand; an unrecognized field name, including a sotto_-prefixed one, is rejected with 400 and nothing from that request is stored.
boolean
default:"false"
When true, starts the SMS opt-in flow for users who have not already opted in. The endpoint never opts a user in directly.
Example request body

Error responses

Errors use the standard envelope (see Errors): A 200 response means the user was created or updated. Watch your Klaviyo flow’s webhook analytics for non-200 responses: a misconfigured flow (for example, a mis-mapped phone number field) fails loudly rather than silently.
Need help wiring a Klaviyo flow to this endpoint, or deciding between the push, the sync, and the inbound API? Reach out to support@withsotto.com.