API Reference

The Sailup API is organized around REST. It accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes and authentication. All endpoints are served under the /v1 base path.

Getting Started

Base URL

All API requests are made to the following base URL. Append the endpoint path to this URL for every request. Note that resource paths end with a trailing slash.

Base URL
https://api.sailup.io/v1

Authentication

The Sailup API authenticates requests with a project API key. You can manage your API keys in the Developer Settings section of your dashboard. Each key is scoped to a single project, so requests are automatically associated with the right project — no project ID is needed in the URL.

Include your API key in the Authorization header as a Bearer token. Every key is prefixed with sailup_. Requests without a valid key return 401 Unauthorized.

Example Header
Authorization: Bearer sailup_a1b2c3d4e5f6g7h8

SMS

Send text messages and track their delivery. Messages are queued on receipt and dispatched to recipients in real time.

POST/sms/

Send SMS

Send a text message to one or more recipients. The message is queued immediately and returns 202 Accepted; track its delivery with the Get a message endpoint.

Body Parameters

fromstringrequired

Your registered sender ID. Must be set up in the dashboard before use.

tostring[]required

Array of destination phone numbers. Local (e.g. 0201234567) and E.164 (e.g. +233201234567) formats are accepted.

bodystringrequired

The text content of the message.

Request Body
{
  "from": "Sail",
  "to": ["0201234567"],
  "body": "Hello from Sail!"
}
202 AcceptedAccepted
{
  "id": "58cf292d-417e-4f61-9687-662b845574cf",
  "to": ["0201234567"],
  "sender": "Sail",
  "body": "Hello from Sail!",
  "quantity": 1,
  "status": "queued",
  "delivery_status": "",
  "created_at": "2026-04-03T00:59:45.600037Z"
}
GET/sms/

List messages

Retrieve a paginated list of SMS messages sent from this project, most recent first.

Query Parameters

limitinteger

Maximum number of messages to return. Defaults to 20.

offsetinteger

Number of messages to skip. Defaults to 0.

200 OKResponse
{
  "count": 3,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "58cf292d-417e-4f61-9687-662b845574cf",
      "to": ["0201234567"],
      "sender": "Sail",
      "body": "Hello from Sail!",
      "quantity": 1,
      "status": "dispatched",
      "delivery_status": "",
      "created_at": "2026-04-03T00:59:45.600037Z"
    }
  ]
}
GET/sms/{message_id}/

Get a message

Retrieve a single SMS message by its ID, including its current delivery status.

Path Parameters

message_idstringrequired

The UUID of the message.

200 OKResponse
{
  "id": "58cf292d-417e-4f61-9687-662b845574cf",
  "to": ["0201234567"],
  "sender": "Sail",
  "body": "Hello from Sail!",
  "quantity": 1,
  "status": "dispatched",
  "delivery_status": "",
  "created_at": "2026-04-03T00:59:45.600037Z"
}

Contacts

Create and manage the people you message. Contacts can be added to lists for targeted campaigns.

GET/contacts/

List contacts

Retrieve a paginated list of contacts in the project. Supports search and filtering by opt-in status.

Query Parameters

searchstring

Search by phone, name, or email.

opted_inboolean

Filter by opt-in status (true or false).

limitinteger

Maximum number of contacts to return. Defaults to 20.

offsetinteger

Number of contacts to skip. Defaults to 0.

200 OKResponse
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "25659b22-d307-4912-907e-63ed0b353f39",
      "phone": "+233201234567",
      "first_name": "Alice",
      "last_name": "Mensah",
      "email": "",
      "attributes": {},
      "opted_in": true,
      "opt_in_source": "MANUAL",
      "opted_out_at": null,
      "created_at": "2026-04-01T19:05:07.109303Z"
    }
  ]
}
POST/contacts/

Create a contact

Create a new contact. Either phone or email (or both) must be provided. Optionally add the contact to lists at creation time with list_ids.

Body Parameters

phonestring

Phone number in E.164 format (e.g. +233241234567). Maximum 30 characters. Required if email is not provided.

emailstring

Email address. Maximum 254 characters. Required if phone is not provided.

first_namestring

Contact's first name. Maximum 100 characters.

last_namestring

Contact's last name. Maximum 100 characters.

attributesobject

Custom key-value attributes for the contact.

opted_inboolean

Whether the contact has opted in to receive messages.

opt_in_sourcestring

How the contact opted in. One of API, CSV, or MANUAL.

list_idsstring[]

Array of list IDs to add the contact to. Maximum 10.

Request Body
{
  "phone": "+233241234567",
  "first_name": "Alice",
  "last_name": "Mensah",
  "email": "[email protected]",
  "attributes": {},
  "opted_in": true,
  "opt_in_source": "API",
  "list_ids": ["a7bd4b07-7e58-4785-933c-424d728a2790"]
}
201 CreatedCreated
{
  "id": "1597951f-e00f-42c3-9924-26a0044ba820",
  "phone": "+233241234567",
  "first_name": "Alice",
  "last_name": "Mensah",
  "email": "[email protected]",
  "attributes": {},
  "opted_in": true,
  "opt_in_source": "API",
  "opted_out_at": null,
  "created_at": "2026-04-03T13:56:18.900086Z"
}
GET/contacts/{contact_id}/

Get a contact

Retrieve a single contact by ID. The response includes the lists the contact belongs to.

Path Parameters

contact_idstringrequired

The UUID of the contact.

200 OKResponse
{
  "id": "25659b22-d307-4912-907e-63ed0b353f39",
  "phone": "+233201234567",
  "first_name": "Alice",
  "last_name": "Mensah",
  "email": "",
  "attributes": {},
  "opted_in": true,
  "opt_in_source": "MANUAL",
  "opted_out_at": null,
  "created_at": "2026-04-01T19:05:07.109303Z",
  "lists": [
    {
      "id": "a7bd4b07-7e58-4785-933c-424d728a2790",
      "name": "VIP Customers",
      "created_at": "2026-04-03T13:55:44.050666Z"
    }
  ]
}
PATCH/contacts/{contact_id}/

Update a contact

Partially update a contact. All fields are optional — only the fields you include are changed. Updatable fields: first_name, last_name, email, attributes, opted_in.

Path Parameters

contact_idstringrequired

The UUID of the contact.

Body Parameters

first_namestring

Contact's first name. Maximum 100 characters.

last_namestring

Contact's last name. Maximum 100 characters.

emailstring

Email address. Maximum 254 characters.

attributesobject

Custom key-value attributes for the contact.

opted_inboolean

Whether the contact has opted in to receive messages.

Request Body
{
  "last_name": "Owusu",
  "opted_in": true
}
200 OKResponse
{
  "id": "25659b22-d307-4912-907e-63ed0b353f39",
  "phone": "+233201234567",
  "first_name": "Alice",
  "last_name": "Owusu",
  "email": "",
  "attributes": {},
  "opted_in": true,
  "opt_in_source": "MANUAL",
  "opted_out_at": null,
  "created_at": "2026-04-01T19:05:07.109303Z"
}
DELETE/contacts/{contact_id}/

Delete a contact

Soft-delete a contact. Returns 204 No Content on success.

Path Parameters

contact_idstringrequired

The UUID of the contact.

204 No ContentNo content

Empty body — no content is returned.

POST/contacts/bulk/

Bulk upsert

Create or update contacts in bulk. Existing contacts are matched by phone first, then email. Maximum 500 contacts per request.

Body Parameters

contactsobject[]required

Array of contact objects, each using the same fields as Create a contact. Maximum 500 items.

Request Body
{
  "contacts": [
    {
      "phone": "+233241000002",
      "first_name": "Bob"
    }
  ]
}
200 OKResponse
{
  "imported": 1,
  "skipped": 0,
  "failed": 0,
  "errors": []
}

Lists

Group contacts into lists to organize segments and target messaging campaigns.

GET/lists/

List contact lists

Retrieve a paginated list of contact lists in the project.

Query Parameters

limitinteger

Maximum number of lists to return. Defaults to 20.

offsetinteger

Number of lists to skip. Defaults to 0.

200 OKResponse
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "a7bd4b07-7e58-4785-933c-424d728a2790",
      "name": "VIP Customers",
      "description": "High-value customers",
      "contact_count": 2,
      "created_at": "2026-04-03T13:55:44.050666Z"
    }
  ]
}
POST/lists/

Create a list

Create a new contact list.

Body Parameters

namestringrequired

Name of the list. Maximum 100 characters.

descriptionstring

Optional description of the list. Maximum 500 characters.

Request Body
{
  "name": "VIP Customers",
  "description": "High-value customers"
}
201 CreatedCreated
{
  "id": "a7bd4b07-7e58-4785-933c-424d728a2790",
  "name": "VIP Customers",
  "description": "High-value customers",
  "contact_count": 0,
  "created_at": "2026-04-03T13:55:44.050666Z"
}
GET/lists/{list_id}/

Get a list

Retrieve a single contact list by ID, including its current contact count.

Path Parameters

list_idstringrequired

The UUID of the list.

200 OKResponse
{
  "id": "a7bd4b07-7e58-4785-933c-424d728a2790",
  "name": "VIP Customers",
  "description": "High-value customers",
  "contact_count": 2,
  "created_at": "2026-04-03T13:55:44.050666Z"
}
PATCH/lists/{list_id}/

Update a list

Partially update a contact list. All fields are optional — only the fields you include are changed.

Path Parameters

list_idstringrequired

The UUID of the list.

Body Parameters

namestring

Name of the list. Maximum 100 characters.

descriptionstring

Description of the list. Maximum 500 characters.

Request Body
{
  "description": "Updated description"
}
200 OKResponse
{
  "id": "a7bd4b07-7e58-4785-933c-424d728a2790",
  "name": "VIP Customers",
  "description": "Updated description",
  "contact_count": 2,
  "created_at": "2026-04-03T13:55:44.050666Z"
}
DELETE/lists/{list_id}/

Delete a list

Soft-delete a contact list. Returns 204 No Content on success, or 409 Conflict if the list still has associated campaigns.

Path Parameters

list_idstringrequired

The UUID of the list.

204 No ContentNo content

Empty body — no content is returned.

GET/lists/{list_id}/contacts/

List contacts in a list

Retrieve a paginated list of the contacts that belong to a specific list.

Path Parameters

list_idstringrequired

The UUID of the list.

Query Parameters

limitinteger

Maximum number of contacts to return. Defaults to 20.

offsetinteger

Number of contacts to skip. Defaults to 0.

200 OKResponse
{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "1597951f-e00f-42c3-9924-26a0044ba820",
      "phone": "+233241234567",
      "first_name": "Alice",
      "last_name": "Mensah",
      "email": "[email protected]",
      "attributes": {},
      "opted_in": true,
      "opt_in_source": "API",
      "opted_out_at": null,
      "created_at": "2026-04-03T13:56:18.900086Z"
    }
  ]
}
POST/lists/{list_id}/contacts/

Add contacts to a list

Add one or more existing contacts to a list. The response reports how many were added, were already members, or could not be found.

Path Parameters

list_idstringrequired

The UUID of the list.

Body Parameters

contact_idsstring[]required

Array of contact IDs to add to the list. Maximum 500.

Request Body
{
  "contact_ids": ["25659b22-d307-4912-907e-63ed0b353f39"]
}
200 OKResponse
{
  "added": 1,
  "already_in_list": 0,
  "not_found": 0
}
DELETE/lists/{list_id}/contacts/{contact_id}/

Remove a contact

Remove a single contact from a list. Returns 204 No Content on success.

Path Parameters

list_idstringrequired

The UUID of the list.

contact_idstringrequired

The UUID of the contact to remove.

204 No ContentNo content

Empty body — no content is returned.

EmailComing Soon

Send transactional and marketing emails with built-in tracking and template support.

Email API coming soon

We're building a powerful email delivery API. Stay tuned for updates.

Sailup

The communication infrastructure for modern applications. Built for scale, designed for developers.

Product

Company

© 2026 Sailup Inc. All rights reserved.