sk_…) key. Use it to register wallets as contacts, ingest form submissions, send pushes, and launch campaigns, everything that reads or writes data.
Authentication
Every call carries your secret key in a header. Two forms are accepted, use whichever your HTTP client makes easy:A
sk_test_… key runs against your workspace in test mode, which is the safe way to integrate before going live, custom events sent with a test key are dry-run, for example. Read-only keys reject writes with 403. See API keys for scopes, rolling, and revocation.Quickstart: ingest a capture
The highest-value first call for most backends: hand a consented email (and optional wallet) to a capture form from your server. If the form uses double opt-in, this kicks off the confirmation email; on confirmation the contact joins the bound list and can fire an automation.{token} is the form’s token), or the request 404s. See capture forms for the body fields and the confirmation flow.
The server-to-server surface
A secret key unlocks a small, deliberate set of endpoints. Reads never expose the email address itself.Email can’t be set through
POST /identify, by design. The only consent-first path for an address is a capture form, embedded or ingested server-side with the endpoint above.POST /identifyis idempotent on the wallet, lower-cases the address, and rejects any personal identifier (email,phone,name) with400 PERSONAL_IDENTIFIER_REJECTED. To attach traits, send a custom event instead.POST /campaigns/{id}/sendtakes a prepared campaign id, not thecampaignRunIdreturned by/inapp/push. It can’t compose or retarget; it launches what’s already in the dashboard.GET /events/catalogis a dashboard (session) route, not a secret-key one, so ask_key gets401there.

