docs

API & integrations

How to get data into Sendra programmatically — events, contacts, and form submissions.

Sendra exposes a JSON API under /api on your workspace origin (for example https://your-workspace.sendra.so/api/...). Today it's designed for two integration styles: inbound webhooks you can wire up without code, and session-scoped calls for tooling that runs as a signed-in user.

Standalone workspace API keys are on the roadmap. Until they land, the no-code paths below — event sources and form endpoints — are the recommended way to integrate third-party services, since they don't require a session.

Authentication, today

MethodUse it for
Event source URLInbound custom events from third parties. The unguessable URL is the credential — no headers needed.
Form submit endpointPublic signup form posts from your site.
SessionCalls made as a signed-in user (e.g. internal scripts, the app itself).

Custom events

The most common integration is sending custom events — "this user signed up," "this customer upgraded" — to trigger automations.

No-code: event sources

Create an Event source under Settings → Events to get an inbound webhook URL, then point a service like Stripe at it. Sendra maps the payload to a contact email and event name for you. Full details in Events → Event sources.

curl -X POST https://your-workspace.sendra.so/api/ingest/YOUR_SOURCE_TOKEN \
  -H "Content-Type: application/json" \
  -d '{ "data": { "customer": { "email": "ada@example.com" } }, "type": "purchaseCompleted" }'

A GET to the same URL returns { "ok": true } so providers can verify the endpoint.

Direct: events/send

curl -X POST https://your-workspace.sendra.so/api/events/send \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ada@example.com",
    "eventName": "signUp",
    "eventProperties": { "plan": "pro" },
    "contactProperties": { "firstName": "Ada" }
  }'
FieldRequiredNotes
emailyesLower-cased; the contact is created if it doesn't exist.
eventNameyesThe string automations match on. Use camelCase, no spaces.
eventPropertiesnoArbitrary JSON; shown in the event log.
contactPropertiesnoPatches firstName, lastName, name, and your custom fields.

Response: { "enrolled": <n>, "exited": <n> } — how many automations the contact entered and how many active enrollments were dropped by an exit event.

See the Events guide for naming conventions, patterns, and the event log.

Contacts

Manage your audience programmatically.

# Create or update a contact (upserts on email)
curl -X POST https://your-workspace.sendra.so/api/contacts \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ada@example.com",
    "firstName": "Ada",
    "lastName": "Lovelace",
    "customFields": { "company": "Analytical Engines" },
    "subscribed": true
  }'

Other contact endpoints: GET /api/contacts (with search, page, limit), and GET/PUT/DELETE /api/contacts/{id}. Creating a contact fires contact_added automations; updating one fires contact_updated.

For signup-style flows where you want to record GDPR consent and optionally drop the contact onto a list:

curl -X POST https://your-workspace.sendra.so/api/subscribe \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ada@example.com",
    "firstName": "Ada",
    "listId": "LIST_ID",
    "consent": true,
    "consentText": "I agree to receive the newsletter",
    "source": "api"
  }'

Response: { "success": true, "contactId": "...", "requiresConfirmation": <bool> }. If the list uses double opt-in, requiresConfirmation is true and a confirmation email goes out.

Forms

Hosted and embeddable forms post to a public, form-scoped endpoint — no auth required. You don't usually call this yourself; the embed snippet handles it. See embedding forms.

Outbound webhooks

Rules can call your endpoints when an event fires. Add a webhook action with a URL and method; Sendra POSTs { event, payload, timestamp } when the rule triggers — useful for syncing engagement back into your own systems.

On this page