Textos API Documentation
This document describes the Textos REST API. All endpoints are prefixed with /api/v1 unless otherwise noted.
Authentication
The API uses JWT (JSON Web Token) for authentication. Include the access token in the Authorization header:
Obtaining Tokens
Login
Request:
Response:
Refresh Token
Response:
Using API Keys
For programmatic access, you can use API keys instead of JWT tokens. Include the API key in the X-API-Key header:
Note: API keys inherit the permissions of the user who created them. When using API keys, you may need to specify the organization_id parameter on certain endpoints (like /teams) since there is no interactive session to track the current organization.
Authentication Endpoints
Register with Invitation
Register a new user using an invitation token.
Request:
{
"token": "invitation-token",
"password": "secure-password",
"name": "John Doe",
"language": "fr"
}
Get Current User
Returns the authenticated user's profile.
Update Current User
Request:
{
"name": "New Name",
"language": "en",
"password": "new-password",
"default_organization_id": "org-id-here"
}
Note: The default_organization_id parameter sets the user's default organization. When the user accesses a domain, if their default organization belongs to that domain, they will be automatically switched to it.
User Object:
{
"id": "user-id",
"email": "user@example.com",
"name": "John Doe",
"role": "admin",
"organization_id": "org-id",
"team_id": "team-id",
"language": "fr",
"oauth_provider": null,
"is_active": true,
"created_at": "2024-01-15T10:30:00Z",
"last_login": "2024-01-15T10:30:00Z",
"default_organization_id": "org-id"
}
| Field | Type | Description |
|---|---|---|
| id | string | User unique identifier |
| string | User email address | |
| name | string | User display name |
| role | string | User role: super_admin, domain_admin, admin, manager, agent |
| organization_id | string | Current organization ID |
| team_id | string | Current team ID (if assigned) |
| language | string | Preferred language: fr, en |
| oauth_provider | string | OAuth provider if using SSO: google, microsoft, apple |
| is_active | boolean | Whether the user is active |
| default_organization_id | string | Default organization ID (used when switching domains) |
| domain_ids | array | List of domain IDs the user can manage (for domain_admin role) |
Forgot Password
Request:
Reset Password
Request:
OAuth Providers
Returns list of enabled OAuth providers for the current domain.
SMS & Conversations
Send SMS
Request:
{
"to": "+15141234567",
"body": "Hello from Textos!",
"team_id": "optional-team-id",
"from_number": "optional-from-number",
"media_urls": [
{
"url": "https://example.com/image.jpg",
"content_type": "image/jpeg"
}
]
}
Parameters: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | to | string | Yes | Destination phone number in E.164 format | | body | string | No | Message text (required if no media_urls) | | team_id | string | No | Team ID to send from | | from_number | string | No | Specific phone number to send from | | media_urls | array | No | Array of media attachments for MMS |
Media URL Object: | Field | Type | Description | |-------|------|-------------| | url | string | Public URL of the media file | | content_type | string | MIME type (image/jpeg, image/png, video/mp4, etc.) |
Note: MMS support depends on the provider. Only providers that support MMS (e.g., ISP Telecom) can send media attachments. SMS-only providers (e.g., Ubity) will ignore media_urls.
Response:
{
"message": {
"id": "...",
"direction": "outbound",
"status": "sent",
"body": "Hello from Textos!",
"from_number": "+15149876543",
"to_number": "+15141234567",
"media_urls": [...],
"created_at": "2024-01-15T10:30:00Z"
},
"conversation": { ... }
}
Upload File (MMS)
Upload a file to use as an MMS attachment.
Request:
- file: The file to upload (multipart/form-data)
Supported formats: - Images: JPG, JPEG, PNG, GIF, WebP - Videos: MP4, MOV - Audio: MP3, WAV, M4A
Limits: - Maximum file size: 10 MB
Response:
Note: The returned URL should be used in the media_urls array of the Send SMS endpoint. For external API calls, prepend the base URL to create an absolute URL.
List Conversations
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| team_id | string | Filter by team |
| status | string | open or closed |
| skip | integer | Pagination offset |
| limit | integer | Results per page (max 100) |
Get Conversation
Returns conversation details with messages and provider capabilities.
Query Parameters: | Parameter | Type | Description | |-----------|------|-------------| | skip | integer | Message pagination offset | | limit | integer | Messages per page (max 100) |
Response:
{
"conversation": {
"id": "...",
"phone_number": "+15141234567",
"status": "open",
"created_at": "2024-01-15T10:00:00Z",
...
},
"messages": [
{
"id": "...",
"direction": "inbound",
"body": "Hello!",
"status": "received",
"media_urls": [],
"created_at": "2024-01-15T10:30:00Z"
},
...
],
"capabilities": ["SMS", "MMS"]
}
Capabilities: | Value | Description | |-------|-------------| | SMS | Basic SMS messaging (always present) | | MMS | Multimedia messaging (images, videos, audio) |
The capabilities array indicates what features are available for this conversation based on the provider configuration. Use this to conditionally show/hide MMS attachment controls in your UI.
Close Conversation
Reopen Conversation
Archive Conversation
Archives a conversation. Requires manager role or higher.
Response:
Delete Conversation
Permanently deletes a conversation and all its messages. Requires admin role or higher.
Response:
List Messages
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| team_id | string | Filter by team |
| direction | string | inbound or outbound |
| status | string | Message status |
| skip | integer | Pagination offset |
| limit | integer | Results per page |
Teams
List Teams
Returns teams from the user's current organization (selected in the sidebar).
Query Parameters: | Parameter | Type | Description | |-----------|------|-------------| | organization_id | string | Filter by organization (required for API key users, optional for JWT users) | | skip | integer | Pagination offset | | limit | integer | Results per page (max 100) |
Note: When using JWT authentication, the organization is determined by the user's current selection in the web interface. When using API key authentication, you should specify the organization_id parameter to indicate which organization's teams to retrieve.
Get Team
Create Team
Request:
Update Team
Request:
{
"name": "Updated Team Name",
"phone_number": "+15149876543",
"business_hours": [
{ "day": 0, "start": "09:00", "end": "17:00" },
{ "day": 1, "start": "09:00", "end": "17:00" }
],
"outside_hours_behavior": "queue",
"auto_reply_message": "We're currently closed...",
"welcome_message": "Thank you for contacting us!",
"timezone": "America/Montreal"
}
Delete Team
Update Business Hours
Request:
{
"business_hours": [
{ "day": 0, "start": "09:00", "end": "17:00" },
{ "day": 1, "start": "09:00", "end": "17:00" },
{ "day": 2, "start": "09:00", "end": "17:00" },
{ "day": 3, "start": "09:00", "end": "17:00" },
{ "day": 4, "start": "09:00", "end": "17:00" }
],
"outside_hours_behavior": "queue",
"auto_reply_message": "We're currently closed. We'll respond during business hours.",
"timezone": "America/Montreal"
}
Notes:
- Day 0 = Monday, 6 = Sunday
- outside_hours_behavior: queue or reject
- auto_reply_message: optional, sent when SMS received outside hours (for both behaviors)
Team Members
List Members
Add Member
Request:
Remove Member
Team Phone Numbers
Regenerate Webhook
Team Archives
List Archived Dates
Returns a list of dates (YYYY-MM-DD format) that have archived conversations. Requires manager role or higher.
Response:
List Archived Conversations
Returns archived conversations for a team. Requires manager role or higher.
Query Parameters: | Parameter | Type | Description | |-----------|------|-------------| | date | string | Filter by date (YYYY-MM-DD format) | | skip | integer | Pagination offset | | limit | integer | Results per page (max 100) |
Response:
{
"conversations": [
{
"id": "...",
"phone_number": "+15141234567",
"contact_name": "John Doe",
"status": "archived",
"archived_at": "2024-01-15T14:30:00Z",
...
}
],
"skip": 0,
"limit": 50
}
Organizations
My Organizations
Returns all organizations the current user belongs to.
Switch Organization
Request:
Current Organization
Update Current Organization
Request:
Organization Members
Invitations
List Invitations
Create Invitation
Request:
Response includes token for the invitation URL.
Delete Invitation
Verify Invitation (Public)
API Keys
List API Keys
Create API Key
Request:
Response includes key field - save it as it's only shown once!
Get API Key
Revoke API Key
orMetrics
Overview
Query Parameters: | Parameter | Type | Description | |-----------|------|-------------| | team_id | string | Filter by team (admin only) | | start_date | string | ISO date | | end_date | string | ISO date | | days | integer | Days to look back (default 30) |
Volume
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| team_id | string | Filter by team |
| start_date | string | ISO date |
| end_date | string | ISO date |
| days | integer | Days to look back |
| granularity | string | hour, day, week, or month |
Performance
Team Metrics
User Metrics
Export Metrics
Webhooks
These endpoints are called by SMS providers to deliver incoming messages.
Receive SMS (Team)
The secret_token is the team's webhook secret.
Receive SMS (Domain)
provider:ubityorisp_telecomsecret_token: Domain's webhook secret
Message Status Update
Admin Endpoints (Super Admin Only)
Organizations
List All Organizations
Create Organization
Request:
Get Organization
Notes: - Super admins can access any organization - Organization admins can only access their own organization
Get Organization Invitations
Notes: - Super admins can access any organization - Organization admins can only access their own organization
Update Organization
Delete Organization
Update Organization Member
Request:
Delete Organization Member
Domains
List Domains
Create Domain
Request:
{
"name": "my-domain",
"hostnames": ["app.example.com", "app.example.com:8080"],
"display_name": "My Domain"
}
Get Domain
Update Domain
Delete Domain
Get Current Domain (Public)
Domain Settings
SMTP Settings
OAuth Settings
GET /api/v1/domains/{domain_id}/settings/oauth
PUT /api/v1/domains/{domain_id}/settings/oauth/{provider}
SMS Providers
GET /api/v1/domains/{domain_id}/sms-providers
PUT /api/v1/domains/{domain_id}/sms-providers/{provider}
Domain Phone Numbers
List Phone Numbers
Create Phone Number(s)
Request (batch):
Update Phone Number
Configure Provider
Request:
Assign to Organization
Request:
Delete Phone Number
Domain Webhooks
Domain SMS Logs
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| direction | string | inbound or outbound |
| provider | string | Filter by provider |
| start_date | string | ISO date |
| end_date | string | ISO date |
| skip | integer | Pagination offset |
| limit | integer | Results per page (max 100) |
Domain Admin Management
These endpoints allow managing domain administrators. Accessible to super_admin and domain_admin (for their own domains).
List Domain Admins
Returns all domain admins and pending invitations for a domain.
Response:
{
"admins": [
{
"id": "user-id",
"email": "admin@example.com",
"first_name": "John",
"last_name": "Doe"
}
],
"pending_invitations": [
{
"id": "invitation-id",
"email": "pending@example.com",
"created_at": "2024-01-15T10:30:00Z",
"expires_at": "2024-01-22T10:30:00Z"
}
]
}
Add Domain Admin
Adds a user as domain admin. If the user exists, they are added immediately. If not, an invitation is created.
Request:
Response (existing user):
Response (new invitation):
{
"invitation": {
"id": "...",
"email": "user@example.com",
"token": "...",
"created_at": "...",
"expires_at": "..."
},
"message": "Invitation sent to user@example.com",
"invited": true
}
Remove Domain Admin
Removes a user from domain admins. If the user has no other domains, their role is changed to admin.
Response:
Delete Domain Admin Invitation
Deletes a pending domain admin invitation.
Response:
Billing
The billing API allows managing credits, pricing plans, and usage tracking.
Get Billing Info
Returns billing information for the current organization.
Response:
{
"billing": {
"organization_id": "...",
"balance": 150.00,
"currency": "CAD",
"pricing_plan": {
"id": "...",
"name": "Standard",
"sms_rate": 0.05,
"mms_rate": 0.15
},
"auto_recharge": {
"enabled": true,
"threshold": 50.00,
"amount": 100.00
}
}
}
Get Balance
Response:
Check Balance
Checks if balance is sufficient to send a message.
Request:
Recharge Credits
Recharge account with a credit card.
Request:
Configure Auto-Recharge
Request:
Get Usage
Query Parameters: | Parameter | Type | Description | |-----------|------|-------------| | start_date | string | Start date (ISO) | | end_date | string | End date (ISO) |
Response:
{
"usage": {
"sms_sent": 1234,
"sms_received": 567,
"mms_sent": 89,
"mms_received": 12,
"total_cost": 75.50
}
}
Get Usage Summary
Get Detailed Usage
Get Transactions
List transactions (recharges, deductions).
Get Invoices
Get Invoice
Pricing Plans (Super Admin)
List Plans
Create Plan
Request:
Update Plan
Delete Plan
Assign Plan to Organization
Request:
Add Credits to Organization
Request:
Multi-domain
For multi-domain support, include the X-Frontend-Host header with the domain hostname:
This header is used to: - Filter organizations by domain - Apply domain-specific configurations (SMTP, OAuth, branding) - Load the domain's phone numbers and providers
Note for mobile apps: Mobile apps must send this header to access resources from the correct domain.
Error Responses
All errors follow this format:
Common error codes:
- validation_error - Invalid request data
- unauthorized - Authentication required
- forbidden - Insufficient permissions
- not_found - Resource not found
- send_failed - SMS sending failed
- provider_error - SMS provider error
Rate Limits
| Endpoint | Limit |
|---|---|
| POST /auth/login | 20/minute |
| POST /auth/register | 10/hour |
| POST /auth/forgot-password | 5/hour |
| POST /auth/reset-password | 10/hour |
| POST /sms/send | 100/hour |
Roles & Permissions
| Role | Description |
|---|---|
super_admin |
Full system access, can manage all domains and organizations |
domain_admin |
Can manage assigned domains: organizations, settings, SMS logs. Cannot create/delete domains or add credits. |
admin |
Organization administrator, can manage teams and members |
manager |
Team manager, can configure team settings and view metrics |
agent |
Can handle conversations assigned to their team |
Domain Admin Capabilities
Domain admins have access to their assigned domains only. They can:
- Access all organizations within their domains
- Manage domain settings (SMTP, OAuth)
- View SMS logs for their domains
- Manage other domain admins for their domains
Domain admins cannot:
- Create or delete domains
- Add credits to organizations
- Access domains not assigned to them