Join our Slack Community!
API Integration
/ API Integration

Base URL

https://api.sbl.so

POST/auth/token

Generate Token

Authenticates a user with email/password and returns a bearer token valid for 30 days. If a 401 Unauthorized is returned on any other endpoint, regenerate the token and retry.

Request Body Fields

NameTypeRequiredDescription
emailstringYesYour account email address
passwordstringYesYour account password

Request Body Example

{
  "email": "user@example.com",
  "password": "your_password"
}

Response (200 OK)

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5..."
}

Error Responses

StatusDescription
400Missing or invalid parameters
401Invalid email or password
429Too many requests — check Retry-After header and retry

GET/campaigns

List Campaigns

Returns a list of campaigns for a company.

Authentication

Authorization: Bearer <token>

Query Parameters

NameTypeRequiredDescription
companyIdstringYesThe ID of the company
statusesstring | string[]NoFilter by campaign status(es)
typesstring | string[]NoFilter by campaign type(s)
isArchivedbooleanNoFilter archived campaigns (default: false)
searchQuerystringNoSearch campaigns by name
lastCampaignIdstringNoPagination cursor — ID of the last campaign from previous page

Response (200 OK)

[
  {
    "id": "123",
    "name": "My Campaign",
    "status": "running",
    "type": "outbound",
    "communicationChannelToUse": 1,
    "statistics": {},
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
]

Error Responses

StatusDescription
401Token expired or invalid
403Company does not belong to the logged-in user
429Too many requests — check Retry-After header and retry

GET/campaigns/:campaignId

Get Campaign

Returns full details for a single campaign.

Authentication

Authorization: Bearer <token>

Path Parameters

NameTypeRequiredDescription
campaignIdstringYesThe ID of the campaign

Query Parameters

NameTypeRequiredDescription
companyIdstringYesThe ID of the company

Response (200 OK)

{
  "id": "123",
  "name": "My Campaign",
  "status": "running",
  "type": "outbound",
  "objective": "...",
  "initialMessage": "Hello!",
  "communicationChannelToUse": 1,
  "statistics": {},
  "analytics": {},
  "batches": [],
  "createdAt": "2024-01-01T00:00:00.000Z"
}

Error Responses

StatusDescription
401Token expired or invalid
403Company does not belong to the logged-in user
429Too many requests — check Retry-After header and retry

GET/campaigns/:campaignId/users

List Campaign Users

Returns a paginated list of users in a campaign.

Authentication

Authorization: Bearer <token>

Path Parameters

NameTypeRequiredDescription
campaignIdstringYesThe ID of the campaign

Query Parameters

NameTypeRequiredDescription
companyIdstringYesThe ID of the company
userChatStatusnumberNoFilter by user chat status
searchQuerystringNoSearch users by name
lastUserIdstringNoPagination cursor — ID of the last user from previous page

Response (200 OK)

[
  {
    "id": "456",
    "name": "John Doe",
    "phoneNumber": "+1234567890",
    "email": null,
    "linkedinChannelDetails": null,
    "tags": [],
    "aiChatOff": false,
    "status": 1,
    "lastMessageCreatedAt": "2024-01-01T00:00:00.000Z",
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
]

Error Responses

StatusDescription
401Token expired or invalid
403Company does not belong to the logged-in user
429Too many requests — check Retry-After header and retry

GET/campaigns/:campaignId/users/:userId/messages

Get User Conversation

Returns messages in a user's conversation within a campaign, ordered oldest first.

Authentication

Authorization: Bearer <token>

Path Parameters

NameTypeRequiredDescription
campaignIdstringYesThe ID of the campaign
userIdstringYesThe ID of the company user

Query Parameters

NameTypeRequiredDescription
companyIdstringYesThe ID of the company
lastMessageIdstringNoPagination cursor — ID of the last message from previous page

Response (200 OK)

[
  {
    "id": "789",
    "senderType": "bot",
    "content": "Hello, welcome!",
    "type": "text",
    "status": 2,
    "communicationChannelUsed": 1,
    "trigger": "initial",
    "scheduledFor": null,
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
]

Error Responses

StatusDescription
401Token expired or invalid
403Company does not belong to the logged-in user
429Too many requests — check Retry-After header and retry

GET/campaigns/:campaignId/human-intervention

List Human Intervention Users

Returns users in the campaign that require human intervention.

Authentication

Authorization: Bearer <token>

Path Parameters

NameTypeRequiredDescription
campaignIdstringYesThe ID of the campaign

Query Parameters

NameTypeRequiredDescription
companyIdstringYesThe ID of the company
lastUserIdstringNoPagination cursor — ID of the last user from previous page

Response (200 OK)

[
  {
    "id": "456",
    "name": "John Doe",
    "phoneNumber": "+1234567890",
    "email": null,
    "linkedinChannelDetails": null,
    "tags": [],
    "aiChatOff": false,
    "status": 1,
    "lastMessageCreatedAt": "2024-01-01T00:00:00.000Z",
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
]

Error Responses

StatusDescription
401Token expired or invalid
403Company does not belong to the logged-in user
429Too many requests — check Retry-After header and retry

POST/campaigns/generate

Generate Campaign

AI-generates a new campaign based on a natural language description.

Authentication

Authorization: Bearer <token>

Request Body Fields

NameTypeRequiredDescription
companyIdstringYesThe ID of the company
descriptionstringYesNatural language description of the campaign goal
communicationChannelnumberYes1 = WhatsApp, 3 = LinkedIn

Request Body Example

{
  "companyId": "123",
  "description": "Reach out to CTOs at fintech companies about our new product",
  "communicationChannel": 1
}

Response (200 OK)

{
  "id": "456",
  "pendingCommentToDM": false,
  "pendingMetaAdId": false,
  "pendingProductLinks": []
}

Error Responses

StatusDescription
400Missing or invalid parameters
401Token expired or invalid
403Company does not belong to the logged-in user
429Too many requests — check Retry-After header and retry

POST/campaigns/:campaignId/send-message

Send Message in Campaign

Sends a message to a specific user in a campaign.

Authentication

Authorization: Bearer <token>

Path Parameters

NameTypeRequiredDescription
campaignIdstringYesThe ID of the campaign

Request Body Fields

NameTypeRequiredDescription
userIdstringYesThe ID of the company user
messagestringYesThe message text to send

Request Body Example

{
  "userId": "789",
  "message": "Hello, following up on our conversation!"
}

Response (200 OK)

{
  "messageId": "xxxx"
}

Error Responses

StatusDescription
400User not in campaign, campaign not running, channel not connected, or user in invalid chat state
401Token expired or invalid — regenerate using /auth/token
403Campaign does not belong to the logged-in user
404Campaign not found
429Too many requests — check Retry-After header and retry

POST/campaigns/:campaignId/add-user

Add User to Campaign

Adds a new user to a campaign. WhatsApp campaigns require phoneNumber; LinkedIn campaigns require linkedinProfileUrl. LinkedIn campaigns can also include customMessage for templates that use [custom message].

Authentication

Authorization: Bearer <token>

Path Parameters

NameTypeRequiredDescription
campaignIdstringYesThe ID of the campaign

Request Body Fields

NameTypeRequiredDescription
namestringYesFull name of the user
phoneNumberstringNoRequired for WhatsApp campaigns
linkedinProfileUrlstringNoRequired for LinkedIn campaigns
customVariablesobjectNoKey-value pairs of custom data to attach to the user. Keys and values must be non-empty strings.
customMessagestringNoLinkedIn-only custom text used to replace [custom message] in campaign messages.

Request Body Example

{
  "name": "John Doe",
  "linkedinProfileUrl": "https://www.linkedin.com/in/johndoe",
  "customVariables": {
    "company": "Acme Inc",
    "role": "CTO"
  },
  "customMessage": "I noticed Acme recently expanded its engineering team."
}

Response (200 OK)

This endpoint returns an empty response body (HTTP 200).

Error Responses

StatusDescription
400Campaign not in a valid state, contact field does not match campaign channel, or customMessage is used outside a LinkedIn campaign
401Token expired or invalid — regenerate using /auth/token
403Campaign does not belong to the logged-in user
404Campaign not found
409User is already part of this campaign
429Too many requests — check Retry-After header and retry