The SplashSend API lets your own code add and update people, manage lists, record events and orders, keep a product catalogue up to date and add rows to your data sets. Emails can't be sent through the API.

This article is for developers. The full reference, with an example of every request, is at splashsend.com/api/docs. The same reference as an OpenAPI file is at splashsend.com/api/openapi.

The API reference lists every request with an example.
The API reference lists every request with an example.

Authentication

Make an app in Apps, under Apps you've made, or create a key in Setup → API keys, and choose what it may do. See Making your own app with AI and API keys and what they can do. Send the key as a Bearer token on every request:

Authorization: Bearer sk_live_…

The base address is https://splashsend.com/api/v1. A request the key isn't allowed to make gets a 403. A key made under Apps you've made is refused when a web page sends it, with the code key_in_web_page.

An app for every SplashSend account uses an access token in place of a key. See Making an app for every SplashSend account.

Requests

  • GET /contacts and POST /contacts: list people, or add one.
  • GET, PATCH and DELETE /contacts/{id}: read, update or unsubscribe one person.
  • GET and PUT /contacts/{id}/properties: read or set a person's details.
  • POST /contacts/import: add up to 500 people in one request.
  • /lists, /lists/{id} and /lists/{id}/members: manage lists and who is on them.
  • GET and POST /events: list or record events.
  • GET and POST /orders: list or record orders.
  • GET and POST /products: list products, or send in up to 100 at a time.
  • /data, /data/{key} and /data/{key}/rows: read data sets, create sets you keep yourself, and add, update or delete their rows.

Things to know

  • POST /contacts adds a person, subscribed. Someone already on your list who never subscribed, for example someone first seen through an event, is subscribed too, with the request recorded as their consent. Someone who unsubscribed stays unsubscribed unless you send "resubscribe": true, so only send it when they've asked to hear from you again. An address that bounced or was reported as spam is never subscribed again. When the request subscribes someone, they start your welcome drips unless you send "startAutomations": false.
  • DELETE /contacts/{id} unsubscribes the person and keeps their record.
  • POST /contacts/import leaves the subscription of people who already exist as it is, and changes only their name and any details you send. It doesn't start drips unless you send "startAutomations": true. A row can send "subscriptionStatus": "unsubscribed" to add a new person unsubscribed, for example someone who had opted out of your old email service. Add listId to put everyone on a list. The key then also needs Read & write for Lists.
  • POST /events records something a person did, such as booking_made, and starts any drip whose trigger is A custom event happens with that name. That trigger lists the event names your systems have sent, so send one event before setting up the drip. If the person isn't on your list yet, they're added as unsubscribed, because an event isn't permission to email them. Send an external_id so a retried event is only recorded once. An event from more than 3 days ago is recorded but starts no drip, unless you send "startAutomations": true.
  • POST /orders records a sale from any shop and can start order drips. A buyer new to your list arrives unsubscribed unless you send "accepts_marketing": true. Sending the same order_id again updates the order. An order placed more than 3 days ago starts no order drips, apart from one case: an order from the last 30 days sent with a status of shipped or completed starts An order ships drips. When you send in past orders, switch those drips off first, or leave out the status on orders from the last 30 days. A buyer an order adds starts no welcome drips unless you send "startAutomations": true. They're credited to the email that led to them, as a Shopify store's orders are, and count in Reports.
  • POST /products only shows products with a status of ACTIVE in emails, and uses url as the product's link. Sending a product again changes only the fields you send.

Retries, pages, errors and limits

  • Send an Idempotency-Key header with POST /contacts, /contacts/import, /events, /orders, /lists, /data or /data/{key}/rows. If you retry with the same value, you get the first response back and nothing is done twice. Use a new value for each new request: the same value with a different request is refused.
  • Lists of results take page and limit (up to 100, 25 by default). Data-set rows take offset and limit instead (up to 200, 50 by default).
  • Errors come back as {"error": {"code": "…", "message": "…"}}.
  • Each key can make 100 requests a minute. Over that, you get a 429 with a Retry-After header.
  • A request can be up to 256KB, or 1MB for an import and 4MB for data-set rows.
  • An email address or name in a response needs People access. See API keys and what they can do.

Test mode

An app made under Apps you've made starts in test mode. Its requests work, but nothing it does starts a drip or sends an email, and no webhooks are sent for it, until you switch it to live on its page.

For AI tools

The same reference, written for AI tools to read, is at splashsend.com/developers/llms.txt. Claude Code and Cursor can also search it as an MCP server, with no key. In Claude Code, run claude mcp add --transport http splashsend-docs https://splashsend.com/api/mcp/docs.

Hearing about things as they happen

To be told when something happens in SplashSend, such as a link being clicked, use webhooks. See Sending events to your own systems.