Getting started
Sign up with your Google account or email - your account and first workspace are created on first sign-in. A workspace holds its own contacts, phone numbers, conversations and settings, so an organization can run several isolated workspaces.
Before you can send anything you need a phone number and credits. Your trial includes free messages to get started; paid plans add a monthly credit allowance.
- Buy a number under Phone numbers: search the inventory by country and digits, then purchase. The first number becomes your default sender.
- Check your credit balance in Billing. Every outbound SMS segment consumes one credit.
- To use WhatsApp you also need a registered WhatsApp sender and at least one approved template - see the WhatsApp section below.
- Invite colleagues under Team - see Team & workspaces for how invitations work.
Contacts & consent
Contacts are the foundation of everything you send. Add them one by one or import a CSV with the import wizard, which maps your columns, validates numbers and skips duplicates.
Phone numbers must be in international format (for example +46701234567). Spaces, dashes and a leading 00 are accepted and normalized automatically; anything else is rejected rather than silently mangled.
- Every contact has a consent status: opted in, opted out, or unknown. Campaigns only reach opted-in contacts.
- Replies like STOP automatically opt a contact out - configure the keywords and confirmation texts under Settings → Keywords.
- Tags group contacts for campaign targeting and shift broadcasts. Create them on the fly when adding or importing contacts.
- Every consent change is recorded in an audit log you can produce on request - see Compliance.
Inbox
The inbox shows every two-way conversation in one place - SMS and WhatsApp side by side, each thread labeled with its channel.
Open a conversation to see the full message history and reply directly. Sending a reply consumes credits like any outbound message.
- Filter by status: open, pending or resolved.
- Unread counts update in real time as replies arrive.
- WhatsApp replies outside the 24-hour session window require an approved template - the composer will tell you when that is the case.
Campaigns
Campaigns send one message to many contacts - a promotion, a recall notice, a seasonal greeting. Target everyone, specific tags, or segment rules.
Before sending, the composer shows a cost estimate: how many recipients, how many message segments, and whether your credit balance covers it. Nothing is sent until you confirm.
- Send immediately or schedule for later; scheduled campaigns can be rescheduled or cancelled until they start.
- Personalize with variables like the contact's first name.
- Follow live stats while sending: sent, delivered, failed and replies.
- Campaigns skip contacts who are opted out or of unknown consent - this is not configurable, by design.
Smessa sends WhatsApp through your registered WhatsApp Business sender. Once the sender is connected, WhatsApp appears alongside SMS in the inbox, campaigns and reminders.
WhatsApp distinguishes between session messages and template messages. After a customer writes to you, a 24-hour session window opens in which you can reply freely. Outside that window, business-initiated messages must use a template that WhatsApp has approved.
- Manage templates under WhatsApp Templates: create them in categories (marketing, utility, authentication) and submit for approval.
- Template status is Pending, Approved or Rejected - use Sync to pull the latest review status.
- Templates use numbered placeholders ({{1}}, {{2}}) that you fill at send time.
- A rejected template shows the rejection reason so you can revise and resubmit.
Appointment reminders
Add-onThe appointments add-on sends automatic reminders that measurably cut no-shows. Create appointments manually or sync them from an external calendar.
Each appointment has a reminder schedule - for example 24 hours and 1 hour before the start time. Reminders go out as SMS, or WhatsApp with a chosen template.
- Customers confirm by replying; the confirmation is recorded on the appointment.
- Mark no-shows and completions to build an accurate history.
- A reminder can also be triggered manually from the appointment's page at any time.
Shift scheduling
Add-onThe shifts add-on fills open shifts by SMS or WhatsApp. Create a shift with time, location and pay, then broadcast it to matching staff by tag or individually - WhatsApp broadcasts use an approved template.
The first person to reply YES gets the shift - responses are locked in arrival order, so there is no double-booking. Everyone else is automatically told the shift is taken.
- Set a response deadline after which the broadcast expires.
- Track every response - accepted, declined, expired - on the shift's page.
- Cancel or complete shifts to keep the schedule tidy.
Automations
Add-onThe automations add-on reacts to events for you: an inbound message matching a keyword, a new contact, and more. Each rule pairs a trigger with one or more actions.
Actions include sending a reply, tagging the contact, and calling your own webhook. Each rule shows its execution history with success and failure counts.
- Rules are toggled on and off without deleting them.
- The webhook action POSTs a JSON payload to your URL with optional custom headers and a 10-second timeout. There are currently no retries and no request signature - treat the endpoint as best-effort notification, not as a source of truth.
- The execution log keeps the detail of every run for debugging.
One-time passcodes (OTP)
Add-onThe OTP add-on lets your own application send verification codes over SMS or WhatsApp through two simple API calls - one to send the code, one to verify what the user typed. WhatsApp delivery uses an approved authentication template.
Codes expire after a configurable number of minutes and are single-use. See the API reference below for the request format.
- Customize the message template and code length per request.
- Verification returns a clear verified true/false - no need to store codes yourself.
Team & workspaces
Invite colleagues to your workspace under Team. Three roles exist: owner (full control), admin (everything except ownership), and member.
Invitations work without email: create an invite for a colleague's address, and the moment they sign in to Smessa with that address, they join the workspace automatically. Invites expire after 7 days and can be renewed.
- Admins and owners manage roles, remove members, and handle invites.
- The owner cannot be demoted or removed.
- Switch between workspaces you belong to from the workspace selector.
Billing & credits
Plans include a monthly credit allowance; one credit covers one SMS segment. When credits run out, sending stops unless you allow overage or buy a top-up pack.
Checkout and payment run through our payment partner; invoices and payment methods are managed in the customer portal, one click from the Billing page.
- Credit packs are one-time purchases that stack on top of your monthly allowance.
- Add-ons (appointments, shifts, automations, OTP) are separate subscriptions activated per organization.
- Usage and transaction history are visible under Billing at any time.
Compliance & GDPR
Smessa is built for consent-first messaging. Opt-outs are enforced automatically, every consent change is logged with a timestamp and reason, and campaign sending never overrides consent.
For GDPR requests, the compliance tools export or erase everything stored about a phone number - contact record, messages and consent history.
- Data export produces a machine-readable file suitable for subject access requests.
- Deletion is irreversible and logged; it removes the contact, their messages and their consent trail.
- Configure opt-out, opt-in and info keywords with automatic confirmations under Settings → Keywords.
API reference
Everything the dashboard does is available over a JSON REST API. Authenticate with a workspace API key and integrate sending, contacts, campaigns and more into your own systems.
The base URL is your API host; all endpoints below are relative to it.
Authentication
Create an API key under Settings → API keys. The full key (starting with sf_) is shown exactly once at creation - store it in a secret manager.
Pass the key as a bearer token on every request. The key is bound to the workspace it was created in, so no workspace header is needed; if you do send X-Workspace-Id, it must match the key's workspace.
Keys grant full access to their workspace and keep working even if their creator later leaves the workspace - revoke keys in Settings when off-boarding people or rotating credentials.
curl https://api.smessa.com/api/v1/contacts \
-H "Authorization: Bearer sf_your_api_key"Conventions
- Request and response bodies are JSON with snake_case field names.
- Timestamps are ISO 8601 in UTC.
- Phone numbers use E.164 international format (+46701234567).
- List endpoints are paginated with page and limit query parameters and return the envelope shown below.
{
"data": [ ... ],
"pagination": { "page": 1, "limit": 50, "total": 132, "pages": 3 }
}Errors
- Errors return a JSON body with a detail field; validation errors (422) return a detail array with per-field messages.
- 401 - missing, invalid or revoked API key.
- 402 - insufficient credits or inactive subscription, with an object body: {"error": "insufficient_credits", "message": "..."}.
- 403 - X-Workspace-Id mismatch, or {"error": "feature_not_available"} when the endpoint needs an add-on your organization has not subscribed to.
- 404 - resource not found in this workspace.
Endpoints
Messages
| POST | /api/v1/messages | Send an SMS or WhatsApp message |
| GET | /api/v1/messages/{id} | Get a message and its delivery status |
OTP
| POST | /api/v1/otp/send | Send a verification code |
| POST | /api/v1/otp/verify | Verify a code the user entered |
Contacts
| GET | /api/v1/contacts | List contacts (search, consent and tag filters) |
| POST | /api/v1/contacts | Create a contact |
| POST | /api/v1/contacts/import | Bulk import contacts |
| GET | /api/v1/contacts/tags | List the workspace's tags |
| GET | /api/v1/contacts/{id} | Get a contact |
| PUT | /api/v1/contacts/{id} | Update a contact |
| DELETE | /api/v1/contacts/{id} | Delete a contact |
| PUT | /api/v1/contacts/{id}/consent | Update consent status |
| GET | /api/v1/contacts/{id}/messages | Message history with this contact |
Conversations
| GET | /api/v1/conversations | List conversations (inbox view) |
| GET | /api/v1/conversations/{id} | Get a conversation with its messages |
| PUT | /api/v1/conversations/{id} | Update status or assignment |
| POST | /api/v1/conversations/{id}/messages | Reply in a conversation |
Campaigns
| GET | /api/v1/campaigns | List campaigns |
| POST | /api/v1/campaigns | Create a campaign |
| GET | /api/v1/campaigns/{id} | Get a campaign with live stats |
| GET | /api/v1/campaigns/{id}/estimate | Estimate recipients and cost |
| POST | /api/v1/campaigns/{id}/schedule | Schedule a campaign |
| POST | /api/v1/campaigns/{id}/send | Send a campaign now |
| POST | /api/v1/campaigns/{id}/cancel | Cancel a campaign |
Phone numbers
| GET | /api/v1/phone-numbers | List your numbers |
| GET | /api/v1/phone-numbers/available | Search purchasable numbers |
| POST | /api/v1/phone-numbers | Purchase a number |
| PUT | /api/v1/phone-numbers/{id} | Rename or set as default |
| GET | /api/v1/phone-numbers/{id}/stats | Usage statistics for a number |
| DELETE | /api/v1/phone-numbers/{id} | Release a number |
| GET | /api/v1/whatsapp/senders | List registered senders |
| GET | /api/v1/whatsapp/templates | List message templates |
| POST | /api/v1/whatsapp/templates | Create a template for approval |
| POST | /api/v1/whatsapp/templates/sync | Sync template review status |
Appointments (add-on)
| GET | /api/v1/appointments | List appointments |
| POST | /api/v1/appointments | Create an appointment with a reminder schedule |
| PUT | /api/v1/appointments/{id} | Update an appointment |
| POST | /api/v1/appointments/{id}/cancel | Cancel an appointment |
| POST | /api/v1/appointments/{id}/remind | Send a reminder now |
Shifts (add-on)
| GET | /api/v1/shifts | List shifts |
| POST | /api/v1/shifts | Create a shift |
| POST | /api/v1/shifts/{id}/broadcast | Broadcast a shift to staff |
| GET | /api/v1/shifts/{id}/responses | List responses |
| POST | /api/v1/shifts/{id}/cancel | Cancel a shift |
Automations (add-on)
| GET | /api/v1/automation | List rules |
| POST | /api/v1/automation | Create a rule |
| PUT | /api/v1/automation/{id} | Update a rule |
| POST | /api/v1/automation/{id}/toggle | Toggle a rule on or off |
| GET | /api/v1/automation/{id}/logs | Execution log for a rule |
Analytics
| GET | /api/v1/analytics/overview | Dashboard overview stats |
| GET | /api/v1/analytics/messaging | Messaging analytics for a date range |
Examples
Send an SMS
curl -X POST https://api.smessa.com/api/v1/messages \
-H "Authorization: Bearer sf_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "+46701234567",
"body": "Your appointment is tomorrow at 14:00."
}'List contacts
curl "https://api.smessa.com/api/v1/contacts?page=1&limit=50" \
-H "Authorization: Bearer sf_your_api_key"Send a one-time passcode
curl -X POST https://api.smessa.com/api/v1/otp/send \
-H "Authorization: Bearer sf_your_api_key" \
-H "Content-Type: application/json" \
-d '{"phone_number": "+46701234567"}'Current limitations
- API keys have no scopes: every key has full access to its workspace. Create separate workspaces if you need isolation.
- There is no request rate limiting yet - please be considerate with polling and use pagination.
- There are no outbound event webhooks yet; poll message status or use the automation webhook action.