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.
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.
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_createdare 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.
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.SMS consent sync
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 prefixedsotto_, so tap events never collide with metrics
your other tools write:
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 aPOST 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.