Multi-tenant SMS & Email platform providing reliable message delivery through provider integrations.
Welcome to the ExoSend API documentation. This API allows you to send SMS messages, send emails, manage sender IDs and domains, run campaigns, and monitor delivery status.
Authorization: Bearer {token} header for all requests.API requests are rate-limited per organization. The default limit is 60 requests per minute. Contact support if you need higher limits.
ExoSend uses a prepaid credits system. SMS messages deduct credits based on the destination country and message length. Email messages deduct credits based on the provider cost per email. Check your balance via the /balance endpoint.
As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_API_TOKEN}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
You can retrieve your API token by logging into the ExoSend admin panel at /admin and navigating to your profile settings. Click Create New Token to generate an API token.
APIs for sending SMS messages and checking delivery status.
Queue a single SMS message for delivery. The message will be sent asynchronously and credits will be deducted immediately.
curl --request POST \
"https://send.exoclass.com/api/v1/sms/send" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"recipient\": \"+37061234567\",
\"message\": \"Hello from ExoSend! Your verification code is 123456.\",
\"sender_id\": \"EXOCLASS\"
}"
{
"success": true,
"data": {
"message_id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"status": "pending",
"cost": 0.035,
"segments": 1,
"balance_remaining": 99.965
},
"message": "SMS queued for sending"
}
Queue multiple SMS messages to different recipients with the same content. Invalid phone numbers will be filtered out, and only valid recipients will receive messages. Credits are deducted for all valid recipients before sending.
curl --request POST \
"https://send.exoclass.com/api/v1/sms/send-bulk" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"recipients\": [
\"+37061234567\",
\"+37061234568\",
\"+37061234569\"
],
\"message\": \"Bulk notification: System maintenance scheduled for tonight.\",
\"sender_id\": \"EXOCLASS\"
}"
{
"success": true,
"data": {
"total_messages": 3,
"total_cost": 0.105,
"balance_remaining": 99.895,
"message_ids": [
"9a7f2e5c-1234-5678-90ab-cdef12345678",
"9a7f2e5c-1234-5678-90ab-cdef12345679",
"9a7f2e5c-1234-5678-90ab-cdef12345680"
],
"invalid_recipients": []
},
"message": "Bulk SMS queued for sending"
}
Retrieve the current delivery status of a previously sent SMS message. Only messages belonging to your organization can be accessed.
The UUID of the message.
curl --request GET \
--get "https://send.exoclass.com/api/v1/sms/9a7f2e5c-1234-5678-90ab-cdef12345678/status" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"status": "delivered",
"recipient": "+37061234567",
"cost": 0.035,
"segments": 1,
"sent_at": "2026-01-03T14:30:00+00:00",
"delivered_at": "2026-01-03T14:30:15+00:00",
"error_message": null,
"error_code": null
}
}
APIs for sending transactional and marketing emails, checking delivery status, and listing sent emails. Credits are deducted per email sent.
Queue a single email for delivery. The email will be sent asynchronously via the configured email provider. Credits are deducted immediately. If html_content is provided without text_content, a plain-text version is auto-generated.
curl --request POST \
"https://send.exoclass.com/api/v1/emails/send" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "[email protected]"\
--form "from_name=ExoSend Team"\
--form "[email protected]"\
--form "to_name=John Doe"\
--form "subject=Welcome to ExoSend!"\
--form "html_content=<h1>Welcome!</h1><p>Thanks for signing up.</p>"\
--form "text_content=Welcome! Thanks for signing up."\
--form "[email protected]"\
--form "template_id=9a7f2e5c-1234-5678-90ab-cdef12345678"\
--form "variables[first_name]=John"\
--form "variables[company]=Acme"\
--form "metadata[order_id]=12345"\
--form "metadata[campaign]=onboarding"\
--form "email_domain_id=9a7f2e5c-1234-5678-90ab-cdef12345678"\
--form "attachments[]=@/tmp/php7k9snt3t716icfYDXkC" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"status": "pending",
"to_email": "[email protected]",
"subject": "Welcome to ExoSend!",
"cost": 0.01,
"created_at": "2026-01-15T10:30:00+00:00"
},
"message": "Email queued for sending."
}
Queue multiple emails for delivery in a single request. Each email can have different recipients, subjects, and content. All emails are validated and credits are deducted for the entire batch before sending begins. Maximum 1000 emails per batch.
curl --request POST \
"https://send.exoclass.com/api/v1/emails/send-batch" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "emails[]=architecto"\
--form "attachments[]=@/tmp/phpq5hk39o3a8is8t5oB9s" {
"success": true,
"data": {
"total_emails": 3,
"total_cost": 0.03,
"balance_remaining": 99.97,
"email_ids": [
"9a7f2e5c-1234-5678-90ab-cdef12345678",
"9a7f2e5c-1234-5678-90ab-cdef12345679",
"9a7f2e5c-1234-5678-90ab-cdef12345680"
]
},
"message": "Batch emails queued for sending."
}
Retrieve the summary and paginated email list for a previously created batch. Only batches belonging to your organization can be accessed.
The UUID of the email batch.
curl --request GET \
--get "https://send.exoclass.com/api/v1/emails/batch/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"batch": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"subject": "Welcome to ExoSend!",
"from_email": "[email protected]",
"from_name": "ExoSend Team",
"source": "api",
"status": "pending",
"total_recipients": 3,
"total_cost": 0.03,
"total_sent": 0,
"total_delivered": 0,
"total_opened": 0,
"total_bounced": 0,
"total_failed": 0,
"delivery_rate": 0,
"open_rate": 0,
"scheduled_at": null,
"created_at": "2026-01-15T10:30:00+00:00"
},
"emails": {}
}
}
Retrieve the current delivery status and tracking events for a previously sent email. Only emails belonging to your organization can be accessed.
The UUID of the email.
curl --request GET \
--get "https://send.exoclass.com/api/v1/emails/9a7f2e5c-1234-5678-90ab-cdef12345678/status" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"status": "delivered",
"to_email": "[email protected]",
"subject": "Welcome to ExoSend!",
"cost": 0.01,
"sent_at": "2026-01-15T10:30:00+00:00",
"delivered_at": "2026-01-15T10:30:05+00:00",
"opened_at": "2026-01-15T11:00:00+00:00",
"clicked_at": "2026-01-15T11:05:30+00:00",
"bounced_at": null,
"error_message": null,
"error_code": null
}
}
Retrieve a paginated list of all sent emails for your organization, sorted by newest first. Optionally filter by delivery status.
Filter by email status. Options: pending, sent, delivered, opened, clicked, bounced, failed, complained.
Number of results per page (default 25).
curl --request GET \
--get "https://send.exoclass.com/api/v1/emails?status=delivered&per_page=10" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"emails": [
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"from_email": "[email protected]",
"to_email": "[email protected]",
"subject": "Welcome to ExoSend!",
"status": "delivered",
"cost": 0.01,
"created_at": "2026-01-15T10:30:00+00:00"
}
],
"pagination": {
"total": 42,
"per_page": 25,
"current_page": 1,
"last_page": 2
}
}
}
APIs for managing email sending domains. Domains must have proper DNS records (SPF, DKIM, DMARC) configured and verified before they can be used for sending emails.
Retrieve all email domains registered for your organization, including their verification status and DNS records.
curl --request GET \
--get "https://send.exoclass.com/api/v1/email-domains" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": [
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"domain": "exosend.com",
"from_email_default": "[email protected]",
"from_name_default": "ExoSend",
"status": "verified",
"spf_verified": true,
"dkim_verified": true,
"dmarc_verified": true,
"is_default": true,
"dns_records": [
{
"type": "TXT",
"name": "exosend.com",
"value": "v=spf1 include:mailgun.org ~all"
}
],
"verified_at": "2026-01-10T12:00:00+00:00",
"created_at": "2026-01-10T10:00:00+00:00"
}
]
}
Register a new email sending domain for your organization. After adding, you must configure the returned DNS records with your domain registrar, then trigger verification. Domain registration with the email provider is done asynchronously.
curl --request POST \
"https://send.exoclass.com/api/v1/email-domains" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"domain\": \"exosend.com\",
\"from_email_default\": \"[email protected]\",
\"from_name_default\": \"ExoSend Team\",
\"region\": \"eu\"
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"domain": "exosend.com",
"from_email_default": "[email protected]",
"from_name_default": "ExoSend Team",
"status": "pending",
"spf_verified": false,
"dkim_verified": false,
"dmarc_verified": false,
"is_default": false,
"dns_records": [
{
"type": "TXT",
"name": "exosend.com",
"value": "v=spf1 include:mailgun.org ~all"
},
{
"type": "TXT",
"name": "k1._domainkey.exosend.com",
"value": "k=rsa; p=MIGf..."
},
{
"type": "TXT",
"name": "_dmarc.exosend.com",
"value": "v=DMARC1; p=none;"
}
],
"verified_at": null,
"created_at": "2026-01-15T10:00:00+00:00"
},
"message": "Domain added. Please add the DNS records shown below, then verify."
}
Retrieve full details of a specific email domain, including DNS records and verification status for SPF, DKIM, and DMARC.
The UUID of the domain.
curl --request GET \
--get "https://send.exoclass.com/api/v1/email-domains/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"domain": "exosend.com",
"from_email_default": "[email protected]",
"from_name_default": "ExoSend Team",
"status": "verified",
"spf_verified": true,
"dkim_verified": true,
"dmarc_verified": true,
"is_default": true,
"dns_records": [
{
"type": "TXT",
"name": "exosend.com",
"value": "v=spf1 include:mailgun.org ~all"
}
],
"verified_at": "2026-01-10T12:00:00+00:00",
"created_at": "2026-01-10T10:00:00+00:00"
}
}
Trigger DNS verification for a domain. This queues a background job that checks whether the required SPF, DKIM, and DMARC records are properly configured. The domain status will be updated asynchronously after verification completes.
The UUID of the domain.
curl --request POST \
"https://send.exoclass.com/api/v1/email-domains/9a7f2e5c-1234-5678-90ab-cdef12345678/verify" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"domain": "exosend.com",
"from_email_default": "[email protected]",
"from_name_default": "ExoSend Team",
"status": "pending",
"spf_verified": false,
"dkim_verified": false,
"dmarc_verified": false,
"is_default": false,
"dns_records": [],
"verified_at": null,
"created_at": "2026-01-15T10:00:00+00:00"
},
"message": "DNS verification has been queued."
}
Set a verified domain as the default sending domain for your organization. Only verified domains can be set as default. The previous default domain will be automatically unset.
The UUID of the domain.
curl --request PATCH \
"https://send.exoclass.com/api/v1/email-domains/9a7f2e5c-1234-5678-90ab-cdef12345678/default" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"domain": "exosend.com",
"from_email_default": "[email protected]",
"from_name_default": "ExoSend Team",
"status": "verified",
"spf_verified": true,
"dkim_verified": true,
"dmarc_verified": true,
"is_default": true,
"dns_records": [],
"verified_at": "2026-01-10T12:00:00+00:00",
"created_at": "2026-01-10T10:00:00+00:00"
},
"message": "Domain set as default."
}
Remove an email domain from your organization. This does not affect emails that have already been sent through this domain.
The UUID of the domain.
curl --request DELETE \
"https://send.exoclass.com/api/v1/email-domains/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": null,
"message": "Domain removed."
}
APIs for managing reusable email templates with variable substitution. Templates support MJML, HTML, and plain-text content with merge tags for personalization. System templates are shared across all organizations and cannot be edited by non-admins.
Retrieve all active email templates for your organization, including system templates. Optionally filter by category. Returns summary data; use the show endpoint for full content.
Filter by template category. Options: transactional, marketing, notification, onboarding, custom.
curl --request GET \
--get "https://send.exoclass.com/api/v1/email-templates?category=marketing" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": [
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "Welcome Email",
"slug": "welcome-email",
"category": "onboarding",
"subject_template": "Welcome, {{first_name}}!",
"is_system": false,
"is_active": true,
"version": 1,
"times_used": 150,
"created_at": "2026-01-10T10:00:00+00:00",
"updated_at": "2026-01-12T14:30:00+00:00"
}
]
}
Create a new email template for your organization. Templates can include
merge tag variables (e.g., {{first_name}}) that are replaced at send time.
If only html_content is provided, a plain-text version is auto-generated.
curl --request POST \
"https://send.exoclass.com/api/v1/email-templates" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Monthly Newsletter\",
\"slug\": \"monthly-newsletter\",
\"category\": \"marketing\",
\"subject_template\": \"Your {{month}} Newsletter\",
\"html_content\": \"<h1>Hello {{first_name}}<\\/h1><p>Here is your newsletter.<\\/p>\",
\"text_content\": \"Hello {{first_name}}, here is your newsletter.\",
\"mjml_content\": \"<mjml><mj-body><mj-section><mj-column><mj-text>Hello<\\/mj-text><\\/mj-column><\\/mj-section><\\/mj-body><\\/mjml>\",
\"description\": \"Sent monthly with latest updates\",
\"variables\": [
\"architecto\"
]
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "Monthly Newsletter",
"slug": "monthly-newsletter",
"category": "marketing",
"subject_template": "Your {{month}} Newsletter",
"is_system": false,
"is_active": true,
"version": 1,
"times_used": 0,
"created_at": "2026-01-15T10:00:00+00:00",
"updated_at": "2026-01-15T10:00:00+00:00",
"description": "Sent monthly with latest updates",
"html_content": "<h1>Hello {{first_name}}</h1><p>Here is your newsletter.</p>",
"text_content": "Hello {{first_name}}, here is your newsletter.",
"mjml_content": null,
"variables": [
{
"key": "first_name",
"label": "First Name",
"default": "there",
"required": true
}
]
},
"message": "Template created."
}
Retrieve full details of a specific email template, including HTML content, text content, MJML source, and variable definitions.
The UUID of the template.
curl --request GET \
--get "https://send.exoclass.com/api/v1/email-templates/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "Welcome Email",
"slug": "welcome-email",
"category": "onboarding",
"subject_template": "Welcome, {{first_name}}!",
"is_system": false,
"is_active": true,
"version": 1,
"times_used": 150,
"created_at": "2026-01-10T10:00:00+00:00",
"updated_at": "2026-01-12T14:30:00+00:00",
"description": "Sent to new users after registration",
"html_content": "<h1>Welcome, {{first_name}}!</h1><p>Thanks for joining.</p>",
"text_content": "Welcome, {{first_name}}! Thanks for joining.",
"mjml_content": null,
"variables": [
{
"key": "first_name",
"label": "First Name",
"default": "there",
"required": true
}
]
}
}
Update an existing email template. Only organization-owned templates can be edited; system templates require super admin privileges. All fields are optional; only provided fields will be updated.
The UUID of the template.
curl --request PUT \
"https://send.exoclass.com/api/v1/email-templates/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Monthly Newsletter v2\",
\"category\": \"marketing\",
\"subject_template\": \"Your {{month}} Newsletter - Updated\",
\"html_content\": \"<h1>Hello {{first_name}}<\\/h1><p>New content.<\\/p>\",
\"text_content\": \"Hello {{first_name}}, new content.\",
\"description\": \"Updated monthly newsletter\",
\"variables\": [
\"architecto\"
],
\"is_active\": true
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "Monthly Newsletter v2",
"slug": "monthly-newsletter",
"category": "marketing",
"subject_template": "Your {{month}} Newsletter - Updated",
"is_system": false,
"is_active": true,
"version": 1,
"times_used": 150,
"created_at": "2026-01-10T10:00:00+00:00",
"updated_at": "2026-01-15T14:30:00+00:00",
"description": "Updated monthly newsletter",
"html_content": "<h1>Hello {{first_name}}</h1><p>New content.</p>",
"text_content": "Hello {{first_name}}, new content.",
"mjml_content": null,
"variables": []
},
"message": "Template updated."
}
Soft-delete an email template. System templates require super admin privileges to delete. Deleted templates are no longer available for sending but their data is preserved for historical reference.
The UUID of the template.
curl --request DELETE \
"https://send.exoclass.com/api/v1/email-templates/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": null,
"message": "Template deleted."
}
Render a template with sample data and return the resulting subject, HTML, and
plain-text content. Useful for previewing how merge tags will be replaced before
sending. Pass variable values in the data object.
The UUID of the template.
curl --request POST \
"https://send.exoclass.com/api/v1/email-templates/9a7f2e5c-1234-5678-90ab-cdef12345678/preview" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"data\": {
\"first_name\": \"John\",
\"month\": \"January\"
}
}"
{
"success": true,
"data": {
"subject": "Welcome, John!",
"html_content": "<h1>Welcome, John!</h1><p>Thanks for joining.</p>",
"text_content": "Welcome, John! Thanks for joining."
}
}
Create a copy of an existing template in your organization. The copy will have " (Copy)" appended to its name and a unique slug with a timestamp suffix. Useful for customizing system templates or creating variations of existing ones.
The UUID of the template to duplicate.
curl --request POST \
"https://send.exoclass.com/api/v1/email-templates/9a7f2e5c-1234-5678-90ab-cdef12345678/duplicate" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9b8f3e6d-2345-6789-01bc-def123456789",
"name": "Welcome Email (Copy)",
"slug": "welcome-email-copy-1705312200",
"category": "onboarding",
"subject_template": "Welcome, {{first_name}}!",
"is_system": false,
"is_active": true,
"version": 1,
"times_used": 0,
"created_at": "2026-01-15T10:30:00+00:00",
"updated_at": "2026-01-15T10:30:00+00:00",
"description": "Sent to new users after registration",
"html_content": "<h1>Welcome, {{first_name}}!</h1><p>Thanks for joining.</p>",
"text_content": "Welcome, {{first_name}}! Thanks for joining.",
"mjml_content": null,
"variables": [
{
"key": "first_name",
"label": "First Name",
"default": "there",
"required": true
}
]
},
"message": "Template duplicated."
}
APIs for creating, managing, and sending email campaigns. Campaigns follow a lifecycle: draft -> sending/scheduled -> completed/cancelled. Only draft campaigns can be edited or deleted.
Retrieve a paginated list of all email campaigns for your organization, sorted by newest first. Optionally filter by campaign status.
Filter by campaign status. Options: draft, scheduled, sending, paused, completed, cancelled, failed.
Number of results per page (default 25).
curl --request GET \
--get "https://send.exoclass.com/api/v1/campaigns?status=draft&per_page=10" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"data": [
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter",
"status": "completed",
"subject": "Your January Update",
"from_email": "[email protected]",
"total_recipients": 5000,
"total_sent": 4980,
"total_opened": 2100,
"total_clicked": 450,
"total_bounced": 20,
"created_at": "2026-01-10T10:00:00+00:00"
}
],
"pagination": {
"total": 15,
"per_page": 25,
"current_page": 1,
"last_page": 1
}
}
}
Create a new email campaign in draft status. The campaign can then be sent immediately or scheduled for later delivery. You can specify target contact lists and optionally use a pre-built template.
curl --request POST \
"https://send.exoclass.com/api/v1/campaigns" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"January Newsletter\",
\"description\": \"Monthly newsletter for January 2026\",
\"email_template_id\": \"9a7f2e5c-1234-5678-90ab-cdef12345678\",
\"subject\": \"Your January Update\",
\"html_content\": \"<h1>January Update<\\/h1><p>Here are our latest updates.<\\/p>\",
\"text_content\": \"Here are our latest updates.\",
\"template_variables\": {
\"month\": \"January\",
\"year\": \"2026\"
},
\"email_domain_id\": \"9a7f2e5c-1234-5678-90ab-cdef12345678\",
\"from_email\": \"[email protected]\",
\"from_name\": \"ExoSend Team\",
\"reply_to\": \"[email protected]\",
\"target_list_ids\": [
\"9a7f2e5c-1234-5678-90ab-cdef12345678\"
],
\"segment_filters\": {
\"status\": \"active\"
},
\"send_rate_per_minute\": 500,
\"batch_size\": 100,
\"timezone\": \"Asia\\/Yekaterinburg\",
\"scheduled_at\": \"2026-03-04T23:25:31\"
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter",
"status": "draft",
"subject": "Your January Update",
"from_email": "[email protected]",
"from_name": "ExoSend Team",
"total_recipients": 0,
"total_sent": 0,
"created_at": "2026-01-15T10:00:00+00:00"
},
"message": "Campaign created."
}
Retrieve full details of a specific campaign, including computed engagement rates (open rate, click rate, bounce rate) if the campaign has been sent.
The UUID of the campaign.
curl --request GET \
--get "https://send.exoclass.com/api/v1/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter",
"status": "completed",
"subject": "Your January Update",
"from_email": "[email protected]",
"from_name": "ExoSend Team",
"total_recipients": 5000,
"total_sent": 4980,
"total_opened": 2100,
"total_clicked": 450,
"total_bounced": 20,
"open_rate": "42.2%",
"click_rate": "9.0%",
"bounce_rate": "0.4%",
"created_at": "2026-01-10T10:00:00+00:00",
"sent_at": "2026-01-10T12:00:00+00:00",
"completed_at": "2026-01-10T13:30:00+00:00"
}
}
Update an existing campaign. Only campaigns in draft status can be updated. All fields are optional; only provided fields will be modified.
The UUID of the campaign.
curl --request PUT \
"https://send.exoclass.com/api/v1/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"January Newsletter v2\",
\"description\": \"Revised newsletter content\",
\"email_template_id\": \"9a7f2e5c-1234-5678-90ab-cdef12345678\",
\"subject\": \"Your Updated January Newsletter\",
\"html_content\": \"<h1>Updated Content<\\/h1>\",
\"text_content\": \"Updated content.\",
\"template_variables\": {
\"month\": \"February\"
},
\"from_email\": \"[email protected]\",
\"from_name\": \"ExoSend Newsletter\",
\"reply_to\": \"[email protected]\",
\"target_list_ids\": [
\"9a7f2e5c-1234-5678-90ab-cdef12345678\"
],
\"send_rate_per_minute\": 300,
\"timezone\": \"Asia\\/Yekaterinburg\",
\"scheduled_at\": \"2026-03-04T23:25:31\"
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter v2",
"status": "draft",
"subject": "Your Updated January Newsletter",
"from_email": "[email protected]",
"created_at": "2026-01-10T10:00:00+00:00",
"updated_at": "2026-01-15T14:30:00+00:00"
},
"message": "Campaign updated."
}
Start sending a draft campaign immediately. The campaign status will change to "sending" and emails will be dispatched to all target recipients asynchronously.
The UUID of the campaign.
curl --request POST \
"https://send.exoclass.com/api/v1/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678/send" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter",
"status": "sending",
"total_recipients": 5000,
"sent_at": "2026-01-15T12:00:00+00:00"
},
"message": "Campaign sending started."
}
Schedule a draft campaign for future delivery at the specified date and time. The campaign status will change to "scheduled" and sending will begin automatically at the scheduled time.
The UUID of the campaign.
curl --request POST \
"https://send.exoclass.com/api/v1/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678/schedule" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"scheduled_at\": \"2026-02-01T09:00:00Z\",
\"timezone\": \"Asia\\/Yekaterinburg\"
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter",
"status": "scheduled",
"scheduled_at": "2026-02-01T09:00:00+00:00"
},
"message": "Campaign scheduled."
}
Pause a campaign that is currently sending. Emails already queued will still be delivered, but no new emails will be dispatched until the campaign is resumed.
The UUID of the campaign.
curl --request POST \
"https://send.exoclass.com/api/v1/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678/pause" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter",
"status": "paused",
"total_sent": 2500,
"total_recipients": 5000
},
"message": "Campaign paused."
}
Resume a previously paused campaign. Email dispatch will continue from where it left off, sending to remaining recipients.
The UUID of the campaign.
curl --request POST \
"https://send.exoclass.com/api/v1/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678/resume" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter",
"status": "sending",
"total_sent": 2500,
"total_recipients": 5000
},
"message": "Campaign resumed."
}
Cancel a campaign that is in draft, scheduled, sending, or paused status. Completed or already-cancelled campaigns cannot be cancelled. Emails already sent will not be affected.
The UUID of the campaign.
curl --request POST \
"https://send.exoclass.com/api/v1/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678/cancel" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "January Newsletter",
"status": "cancelled",
"total_sent": 2500,
"total_recipients": 5000
},
"message": "Campaign cancelled."
}
Permanently delete a draft campaign. Only campaigns in draft status can be deleted. Campaigns that have been sent, scheduled, or completed cannot be deleted.
The UUID of the campaign.
curl --request DELETE \
"https://send.exoclass.com/api/v1/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": null,
"message": "Campaign deleted."
}
APIs for managing email contacts. Contacts are individual email recipients that can be organized into lists for campaign targeting. Supports CRUD operations and CSV import.
Retrieve a paginated list of all contacts for your organization. Supports filtering by status and full-text search across email, first name, and last name.
Filter by contact status. Options: active, unsubscribed, bounced, complained.
Search contacts by email, first name, or last name.
Number of results per page (default 25).
curl --request GET \
--get "https://send.exoclass.com/api/v1/contacts?status=active&search=john&per_page=50" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"data": [
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"status": "active",
"custom_fields": {
"company": "Acme Inc"
},
"subscribed_at": "2026-01-10T10:00:00+00:00",
"created_at": "2026-01-10T10:00:00+00:00"
}
],
"pagination": {
"total": 1250,
"per_page": 25,
"current_page": 1,
"last_page": 50
}
}
}
Add a new contact to your organization. The contact will be automatically subscribed upon creation. Each email address must be unique within the organization.
curl --request POST \
"https://send.exoclass.com/api/v1/contacts" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"[email protected]\",
\"first_name\": \"John\",
\"last_name\": \"Doe\",
\"custom_fields\": {
\"company\": \"Acme Inc\",
\"role\": \"Developer\"
}
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"status": "active",
"custom_fields": {
"company": "Acme Inc",
"role": "Developer"
},
"subscribed_at": "2026-01-15T10:00:00+00:00",
"created_at": "2026-01-15T10:00:00+00:00"
},
"message": "Contact created."
}
Update an existing contact's information. All fields are optional; only provided fields will be modified.
The UUID of the contact.
curl --request PUT \
"https://send.exoclass.com/api/v1/contacts/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"[email protected]\",
\"first_name\": \"Jane\",
\"last_name\": \"Smith\",
\"custom_fields\": {
\"company\": \"New Corp\"
},
\"status\": \"unsubscribed\"
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Smith",
"status": "active",
"custom_fields": {
"company": "New Corp"
},
"subscribed_at": "2026-01-10T10:00:00+00:00",
"created_at": "2026-01-10T10:00:00+00:00",
"updated_at": "2026-01-15T14:30:00+00:00"
},
"message": "Contact updated."
}
Permanently delete a contact from your organization. This also removes the contact from all associated contact lists.
The UUID of the contact.
curl --request DELETE \
"https://send.exoclass.com/api/v1/contacts/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": null,
"message": "Contact deleted."
}
Import contacts from a CSV file. The CSV should have columns for email, first_name, and last_name (at minimum). Duplicate emails are automatically skipped. Optionally assign all imported contacts to a specific contact list. Maximum file size: 10MB.
curl --request POST \
"https://send.exoclass.com/api/v1/contacts/import" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "list_id=9a7f2e5c-1234-5678-90ab-cdef12345678"\
--form "file=@/tmp/phpb1tib3c2s0gkfcKCrJW" {
"success": true,
"data": {
"imported": 450,
"skipped": 12,
"errors": [
{
"row": 5,
"error": "Invalid email format"
},
{
"row": 23,
"error": "Missing required email field"
}
]
},
"message": "Import completed."
}
APIs for managing contact lists. Lists are collections of contacts used for targeting email campaigns. Contacts can belong to multiple lists simultaneously.
Retrieve a paginated list of all contact lists for your organization, including the number of contacts in each list.
Number of results per page (default 25).
curl --request GET \
--get "https://send.exoclass.com/api/v1/contact-lists?per_page=10" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"data": [
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "Newsletter Subscribers",
"description": "Users who opted in to the monthly newsletter",
"is_default": true,
"contacts_count": 3500,
"created_at": "2026-01-10T10:00:00+00:00",
"updated_at": "2026-01-15T14:30:00+00:00"
}
],
"pagination": {
"total": 8,
"per_page": 25,
"current_page": 1,
"last_page": 1
}
}
}
Create a new contact list for your organization. List names must be unique within the organization.
curl --request POST \
"https://send.exoclass.com/api/v1/contact-lists" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Newsletter Subscribers\",
\"description\": \"Users who opted in to the monthly newsletter\",
\"is_default\": false
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "Newsletter Subscribers",
"description": "Users who opted in to the monthly newsletter",
"is_default": false,
"created_at": "2026-01-15T10:00:00+00:00",
"updated_at": "2026-01-15T10:00:00+00:00"
},
"message": "Contact list created."
}
Update an existing contact list's name, description, or default status. All fields are optional; only provided fields will be modified.
The UUID of the contact list.
curl --request PUT \
"https://send.exoclass.com/api/v1/contact-lists/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Premium Subscribers\",
\"description\": \"Premium tier newsletter subscribers\",
\"is_default\": true
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"name": "Premium Subscribers",
"description": "Premium tier newsletter subscribers",
"is_default": true,
"created_at": "2026-01-10T10:00:00+00:00",
"updated_at": "2026-01-15T14:30:00+00:00"
},
"message": "Contact list updated."
}
Delete a contact list. This removes the list itself but does not delete the contacts that were in the list. Contacts will remain in the organization.
The UUID of the contact list.
curl --request DELETE \
"https://send.exoclass.com/api/v1/contact-lists/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": null,
"message": "Contact list deleted."
}
Add one or more existing contacts to a contact list. Contacts that are already in the list will be silently skipped (no duplicates). All contact IDs must belong to your organization.
The UUID of the contact list.
curl --request POST \
"https://send.exoclass.com/api/v1/contact-lists/9a7f2e5c-1234-5678-90ab-cdef12345678/contacts" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"contact_ids\": [
\"9a7f2e5c-1234-5678-90ab-cdef12345678\",
\"9b8f3e6d-2345-6789-01bc-def123456789\"
]
}"
{
"success": true,
"data": null,
"message": "Contacts added to list."
}
Remove a single contact from a contact list. The contact itself is not deleted and remains in the organization. If the contact is not in the list, the operation completes silently.
The UUID of the contact list.
The UUID of the contact to remove.
curl --request DELETE \
"https://send.exoclass.com/api/v1/contact-lists/9a7f2e5c-1234-5678-90ab-cdef12345678/contacts/9b8f3e6d-2345-6789-01bc-def123456789" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": null,
"message": "Contact removed from list."
}
APIs for retrieving email analytics and engagement metrics. Includes organization-level overviews, per-campaign statistics, link tracking, device breakdowns, and individual email event timelines.
Retrieve aggregate email analytics for your organization over a specified date range. Includes totals for sent, delivered, opened, clicked, bounced, and complained emails.
optional Start date for the analytics period (ISO 8601 format). Defaults to 30 days ago.
optional End date for the analytics period (ISO 8601 format). Defaults to today.
curl --request GET \
--get "https://send.exoclass.com/api/v1/analytics/overview?from=2026-01-01&to=2026-01-31" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"total_sent": 12500,
"total_delivered": 12300,
"total_opened": 5200,
"total_clicked": 1100,
"total_bounced": 150,
"total_complained": 5,
"delivery_rate": 98.4,
"open_rate": 42.3,
"click_rate": 8.9,
"bounce_rate": 1.2
}
}
Retrieve detailed analytics for a specific email campaign, including delivery, engagement, and bounce statistics.
The UUID of the campaign.
curl --request GET \
--get "https://send.exoclass.com/api/v1/analytics/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"campaign_id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"campaign_name": "January Newsletter",
"total_sent": 5000,
"total_delivered": 4950,
"total_opened": 2100,
"total_clicked": 450,
"total_bounced": 50,
"total_complained": 2,
"open_rate": 42.4,
"click_rate": 9.1,
"bounce_rate": 1,
"unsubscribe_rate": 0.3
}
}
Retrieve click-tracking data for all links in a campaign, sorted by total clicks. Shows which URLs were clicked and how many times.
The UUID of the campaign.
curl --request GET \
--get "https://send.exoclass.com/api/v1/analytics/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678/links" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": [
{
"url": "https://exosend.com/pricing",
"total_clicks": 230,
"unique_clicks": 180
},
{
"url": "https://exosend.com/docs",
"total_clicks": 145,
"unique_clicks": 120
}
]
}
Retrieve device and email client breakdown for a campaign. Shows which devices, operating systems, and email clients recipients used to open the campaign emails.
The UUID of the campaign.
curl --request GET \
--get "https://send.exoclass.com/api/v1/analytics/campaigns/9a7f2e5c-1234-5678-90ab-cdef12345678/devices" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"devices": [
{
"device": "Desktop",
"count": 1200,
"percentage": 57.1
},
{
"device": "Mobile",
"count": 750,
"percentage": 35.7
},
{
"device": "Tablet",
"count": 150,
"percentage": 7.1
}
],
"clients": [
{
"client": "Gmail",
"count": 900,
"percentage": 42.9
},
{
"client": "Apple Mail",
"count": 600,
"percentage": 28.6
},
{
"client": "Outlook",
"count": 350,
"percentage": 16.7
}
]
}
}
Retrieve the full event timeline for a specific email, including delivery, open, click, bounce, and complaint events in chronological order.
The UUID of the email.
curl --request GET \
--get "https://send.exoclass.com/api/v1/analytics/emails/9a7f2e5c-1234-5678-90ab-cdef12345678/events" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": [
{
"id": "9b8f3e6d-2345-6789-01bc-def123456789",
"email_id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"event_type": "delivered",
"occurred_at": "2026-01-15T10:30:05+00:00",
"metadata": {
"smtp_code": 250
}
},
{
"id": "9c9f4f7e-3456-7890-12cd-ef1234567890",
"email_id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"event_type": "opened",
"occurred_at": "2026-01-15T11:00:00+00:00",
"metadata": {
"user_agent": "Mozilla/5.0",
"ip": "192.168.1.1"
}
},
{
"id": "9d0f5g8f-4567-8901-23de-f12345678901",
"email_id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"event_type": "clicked",
"occurred_at": "2026-01-15T11:05:30+00:00",
"metadata": {
"url": "https://exosend.com/pricing",
"user_agent": "Mozilla/5.0"
}
}
]
}
APIs for managing your email suppression list. Suppressed email addresses will not receive any emails from your organization. Addresses can be suppressed manually, or automatically via bounces, complaints, and unsubscribes.
Retrieve a paginated list of all suppressed email addresses for your organization. Optionally filter by suppression reason.
Filter by suppression reason. Options: hard_bounce, soft_bounce, complaint, unsubscribed, manual, list_import.
Number of results per page (default 25).
curl --request GET \
--get "https://send.exoclass.com/api/v1/suppressions?reason=hard_bounce&per_page=50" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"data": [
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"email": "[email protected]",
"reason": "hard_bounce",
"details": "550 Mailbox not found",
"created_at": "2026-01-10T10:00:00+00:00"
},
{
"id": "9b8f3e6d-2345-6789-01bc-def123456789",
"email": "[email protected]",
"reason": "unsubscribed",
"details": null,
"created_at": "2026-01-12T15:30:00+00:00"
}
],
"pagination": {
"total": 25,
"per_page": 25,
"current_page": 1,
"last_page": 1
}
}
}
Add an email address to your organization's suppression list. Suppressed addresses will not receive any future emails. If the address is already suppressed, the existing suppression record is returned.
curl --request POST \
"https://send.exoclass.com/api/v1/suppressions" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"[email protected]\",
\"reason\": \"manual\",
\"details\": \"Requested removal via support ticket #1234\"
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"email": "[email protected]",
"reason": "manual",
"details": "Requested removal via support ticket #1234",
"created_at": "2026-01-15T10:00:00+00:00"
},
"message": "Email suppressed."
}
Remove an email address from your organization's suppression list, allowing future emails to be delivered to this address again.
curl --request DELETE \
"https://send.exoclass.com/api/v1/suppressions/[email protected]" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": null,
"message": "Email unsuppressed."
}
Check whether a specific email address is on your organization's suppression list. Returns a boolean indicating the suppression status.
curl --request GET \
--get "https://send.exoclass.com/api/v1/suppressions/check/[email protected]" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"email": "[email protected]",
"is_suppressed": true
}
}
APIs for managing your ExoSend account balance and credits.
Retrieve your organization's current credit balance. Credits are used to send SMS messages, with costs varying by destination country and message length.
curl --request GET \
--get "https://send.exoclass.com/api/v1/balance" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"balance": 99.965,
"currency": "EUR",
"organization": "ExoClass"
}
}
APIs for managing sender IDs (sender names that appear on SMS messages). Sender IDs must be approved by administrators and verified by providers before use.
Retrieve all sender IDs for your organization with optional status filtering. By default, only verified sender IDs are returned.
Filter by status. Options: verified, pending, approved, rejected, all. Default: verified.
curl --request GET \
--get "https://send.exoclass.com/api/v1/sender-ids?status=verified" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": [
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"sender_id": "EXOCLASS",
"admin_status": "approved",
"provider_status": "verified",
"is_verified": true,
"is_default": true,
"rejection_reason": null,
"message_count": 42,
"created_at": "2026-01-01T10:00:00+00:00",
"approved_at": "2026-01-01T12:00:00+00:00",
"verified_at": "2026-01-01T14:00:00+00:00"
},
{
"id": "9a7f2e5c-1234-5678-90ab-cdef12345679",
"sender_id": "EXOSMS",
"admin_status": "approved",
"provider_status": "verified",
"is_verified": true,
"is_default": false,
"rejection_reason": null,
"message_count": 15,
"created_at": "2026-01-02T10:00:00+00:00",
"approved_at": "2026-01-02T11:00:00+00:00",
"verified_at": "2026-01-02T13:00:00+00:00"
}
]
}
Submit a new sender ID request for approval. The sender ID will be created in pending status and must go through a two-stage approval process:
Only after both stages can the sender ID be used for sending messages.
curl --request POST \
"https://send.exoclass.com/api/v1/sender-ids" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"sender_id\": \"EXOCLASS\"
}"
{
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"sender_id": "EXOCLASS",
"admin_status": "pending",
"provider_status": "pending",
"is_verified": false,
"is_default": false,
"created_at": "2026-01-03T14:30:00+00:00"
},
"message": "Sender ID request submitted. Awaiting approval from administrator."
}
Set a verified sender ID as the default for your organization. Only verified sender IDs can be set as default. Automatically unsets any previously set default sender ID.
The UUID of the sender ID.
curl --request PATCH \
"https://send.exoclass.com/api/v1/sender-ids/9a7f2e5c-1234-5678-90ab-cdef12345678/default" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": {
"id": "9a7f2e5c-1234-5678-90ab-cdef12345678",
"sender_id": "EXOCLASS",
"is_verified": true,
"is_default": true
},
"message": "Sender ID set as default"
}
Delete a sender ID from your organization. Sender IDs with existing messages or set as default cannot be deleted.
The UUID of the sender ID.
curl --request DELETE \
"https://send.exoclass.com/api/v1/sender-ids/9a7f2e5c-1234-5678-90ab-cdef12345678" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" {
"success": true,
"data": null,
"message": "Sender ID deleted successfully"
}
APIs for creating, managing, and sending bulk SMS campaigns. Campaigns follow a lifecycle: draft -> sending/scheduled -> sent/completed/cancelled.
Create a new SMS campaign. The campaign will be in draft status unless scheduled_at is provided, in which case it will be set to scheduled status.
curl --request POST \
"https://send.exoclass.com/api/v1/sms/campaigns" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"message_content\": \"n\",
\"sender_id_id\": \"6b72fe4a-5b40-307c-bc24-f79acf9a1bb9\",
\"target_list_ids\": [
\"977e5426-8d13-3824-86aa-b092f8ae52c5\"
],
\"contact_ids\": [
\"d6fa562b-acd5-35ff-babb-d11194d3737b\"
],
\"manual_phones\": [
\"+36\"
],
\"scheduled_at\": \"2052-03-28\",
\"timezone\": \"Asia\\/Yekaterinburg\",
\"batch_size\": 22,
\"send_rate_per_minute\": 7
}"
Retrieve a paginated list of all SMS campaigns for your organization, sorted by newest first.
curl --request GET \
--get "https://send.exoclass.com/api/v1/sms/campaigns" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
{
"message": "Unauthenticated."
}
Retrieve full details of a specific SMS campaign including refreshed stats.
The ID of the smsCampaign.
curl --request GET \
--get "https://send.exoclass.com/api/v1/sms/campaigns/019ca407-ed12-71fa-8020-ed1b6fefc081" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
{
"message": "Unauthenticated."
}
Start sending a draft or scheduled campaign immediately.
The ID of the smsCampaign.
curl --request POST \
"https://send.exoclass.com/api/v1/sms/campaigns/019ca407-ed12-71fa-8020-ed1b6fefc081/send" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" Pause a campaign that is currently sending.
The ID of the smsCampaign.
curl --request POST \
"https://send.exoclass.com/api/v1/sms/campaigns/019ca407-ed12-71fa-8020-ed1b6fefc081/pause" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" Cancel a campaign that is sending, paused, or scheduled.
The ID of the smsCampaign.
curl --request POST \
"https://send.exoclass.com/api/v1/sms/campaigns/019ca407-ed12-71fa-8020-ed1b6fefc081/cancel" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"