Email API Documentation
Email management endpoints for creating, updating, previewing, and managing email content, templates, and attachments.
Create an Email
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.create |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.create",
"SessionID": "your-session-id"
}'{
"Success": true,
"ErrorCode": 0,
"EmailID": 12345
}{
"Success": false,
"ErrorCode": [1, 2, 3]
}0: SuccessGet Email Details
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.get |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID to retrieve |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.get",
"SessionID": "your-session-id",
"EmailID": 12345
}'{
"Success": true,
"ErrorCode": 0,
"EmailInformation": {
"EmailID": 12345,
"EmailName": "Newsletter",
"Subject": "Monthly Update",
"HTMLContent": "<html>...</html>",
"PlainContent": "...",
"FromName": "Company Name",
"FromEmail": "info@company.com"
}
}{
"Success": false,
"ErrorCode": [1, 2]
}0: Success
1: Missing required parameter EmailID
2: Email not found or access deniedGet Emails (List or Bulk by IDs)
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
This endpoint operates in two modes:
- Legacy list mode (no
EmailIDsparameter): returns every email the calling user owns. Per-row shape is the raw database row:Optionsis a JSON string, noAttachmentskey. Default order:EmailName ASC. - Bulk-by-IDs mode (with
EmailIDsparameter): returns only the requested rows that the calling user owns. Per-row shape mirrorsemail.get:Optionsis JSON-decoded into an object, andAttachmentsis attached when the full shape is requested OR whenAttachmentsis explicitly listed inFields. Soft-deleted rows are excluded. Response order is not guaranteed. Re-key byEmailIDif order matters. Non-owned and non-existent IDs are silently dropped (compare input length vs. response length to detect drops).
The optional Fields parameter is honored in both modes, additive projection that restricts which keys appear on each returned row.
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: emails.get |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailIDs | String | No | Comma-separated list of email IDs (e.g. 9101,9102,9103). When omitted, returns all emails owned by the user (legacy mode). When set, switches to bulk-by-IDs mode: blank/non-numeric entries are silently dropped, hard-capped at 100 valid IDs per call. |
| Fields | String | No | Comma-separated allow-list of fields to project per row. Possible values: EmailID, RelUserID, EmailName, FromName, FromEmail, ReplyToName, ReplyToEmail, ContentType, Mode, FetchURL, FetchPlainURL, Subject, PlainContent, HTMLContent, ExtraContent1, ExtraContent2, ImageEmbedding, RelTemplateID, PreHeaderText, Options, IsEmailTemplate, CreatedAt, UpdatedAt, DeletedAt, Attachments. Unknown field names are silently dropped. EmailID is always re-added so callers can re-key. |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "emails.get",
"SessionID": "your-session-id"
}'curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "emails.get",
"SessionID": "your-session-id",
"EmailIDs": "9101,9102,9103",
"Fields": "EmailID,Subject,Mode,ContentType,UpdatedAt"
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": "",
"TotalEmailCount": 2,
"Emails": [
{
"EmailID": 9101,
"Subject": "Welcome aboard",
"Mode": "Editor",
"ContentType": "Both",
"UpdatedAt": "2026-05-02 18:11:07"
},
{
"EmailID": 9102,
"Subject": "Day-3 tips",
"Mode": "Stripo",
"ContentType": "Both",
"UpdatedAt": "2026-05-03 09:12:14"
}
]
}{
"Success": false,
"ErrorCode": [3],
"ErrorText": ["Too many ids; max 100"]
}0: Success
1: EmailIDs was provided but contained no valid (numeric, non-blank) entries
3: EmailIDs contained more than 100 valid entries (cap exceeded)Update an Email
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.update |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID to update |
| ValidateScope | String | Yes | Validation scope: OptIn, Campaign, or AutoResponder |
| EmailName | String | No | Email name |
| Subject | String | No | Email subject |
| PreHeaderText | String | No | Email preheader text |
| FromName | String | No | Sender name |
| FromEmail | String | No | Sender email address. With ValidateScope=Campaign it must be a full address, a value carrying a merge tag such as %MFROMDomain%, or, when the user group has SenderDomainManagement=Enabled, a local part with a sender domain (the SenderDomain parameter or the one already stored on the email). Any other value without @ is refused with error 21. |
| ReplyToName | String | No | Reply-to name |
| ReplyToEmail | String | No | Reply-to email address |
| HTMLContent | String | No | HTML email content |
| PlainContent | String | No | Plain text email content |
| Mode | String | No | Editor mode: Unlayer, Stripo, Editor, Empty, Template, Import |
| FetchURL | String | No | URL to fetch HTML content from (for Import mode) |
| FetchPlainURL | String | No | URL to fetch plain content from (for Import mode) |
| ImageEmbedding | String | No | Image embedding setting |
| SenderDomain | String | No | Sender domain. Only enforced when ValidateScope=Campaign and the user's group has SenderDomainManagement=Enabled; ignored for OptIn and AutoResponder scopes (transactional traffic). |
| OpenTracking | Boolean | No | Enable open tracking. true, 1, "true" and "1" (case-insensitive) turn it on. Any other value, including false, 0, "false" and "0", turns it off. Omit the parameter or send null to keep the default (true). |
| LinkTracking | Boolean | No | Enable link tracking. Accepts the same values as OpenTracking. Omit the parameter or send null to keep the default (true). |
| UTMTracking | Boolean | No | Enable UTM tracking |
| UTMSource | String | Conditional | UTM source (required if UTMTracking is true) |
| UTMMedium | String | Conditional | UTM medium (required if UTMTracking is true) |
| UTMCampaign | String | Conditional | UTM campaign (required if UTMTracking is true) |
| UTMTerm | String | No | UTM term parameter |
| UTMContent | String | No | UTM content parameter |
| UTMMergeTags | Boolean | No | Use merge tags in UTM parameters |
| RelTemplateID | Integer | Conditional | Template ID (required if Mode is Template) |
| IsEmailTemplate | Integer | No | Mark as email template (0 or 1) |
| ExtraContent1 | String | No | Extra content field 1 (for Stripo/Unlayer) |
| ExtraContent2 | String | No | Extra content field 2 (for Stripo/Unlayer) |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.update",
"SessionID": "your-session-id",
"EmailID": 12345,
"ValidateScope": "Campaign",
"EmailName": "Updated Newsletter",
"Subject": "New Monthly Update",
"HTMLContent": "<html><body>Updated content</body></html>",
"PlainContent": "Updated content",
"FromName": "Company Name",
"FromEmail": "info@company.com",
"OpenTracking": true,
"LinkTracking": true
}'{
"Success": true,
"ErrorCode": 0
}{
"Success": false,
"ErrorCode": [1, 3, 4, 8, 9, 10, 11, 12, 17, 18, 19, 20, 21]
}0: Success
1: Missing required parameter EmailID
3: Email not found or access denied
4: Invalid Mode parameter
8: Email content cannot be empty
9: Missing required parameter ValidateScope
10: Invalid ValidateScope parameter (must be OptIn, Campaign, or AutoResponder)
11: Missing unsubscribe link in HTML content (only when the user group has Force Unsubscription Link enabled and ValidateScope is Campaign or AutoResponder; %Link:Unsubscribe% or {{ Link:Unsubscribe }} in the content or in the user group HTML header or footer, including inside an unsubscribe fallback block, satisfies it)
12: Missing unsubscribe link in plain content (same rule, for the plain content and the user group plain header or footer)
17: Invalid sender domain (only raised when ValidateScope=Campaign; OptIn and AutoResponder scopes bypass this check)
18: Missing UTMSource parameter (required when UTMTracking is enabled)
19: Missing UTMMedium parameter (required when UTMTracking is enabled)
20: Missing UTMCampaign parameter (required when UTMTracking is enabled)
21: FromEmail cannot be sent: it has no domain and no sender domain is set (only raised when ValidateScope=Campaign; OptIn and AutoResponder scopes bypass this check). The email is not changed.FromEmail without a domain
With ValidateScope=Campaign, email.update refuses a FromEmail that has no @ and no merge tag unless a sender domain applies: the SenderDomain parameter, or the sender domain already stored on the email, and only when the user group has SenderDomainManagement=Enabled. The response is {"Success": false, "ErrorCode": 21, "ErrorText": "..."} and the email is left unchanged. The check is skipped when the user group's marketing delivery server enforces a From address. Before v6.0.1 the value was stored and every recipient of the campaign failed at send time.
Delete an Email
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.delete |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID to delete |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.delete",
"SessionID": "your-session-id",
"EmailID": 12345
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": ""
}{
"Success": false,
"ErrorCode": [1]
}0: Success
1: Missing required parameter EmailIDDuplicate an Email
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.duplicate |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID to duplicate |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.duplicate",
"SessionID": "your-session-id",
"EmailID": 12345
}'{
"Success": true,
"ErrorCode": 0,
"EmailID": 12346,
"EmailName": "Copy of Newsletter"
}{
"Success": false,
"ErrorCode": [1, 2]
}0: Success
1: Missing required parameter EmailID
2: Email not found or access deniedSend Email Preview
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.emailpreview |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Conditional | Email ID to preview (or provide HTMLContent/PlainContent) |
| EmailAddress | String | Conditional | Recipient email address (required if SubscriberID not provided) |
| SubscriberID | Integer | No | Subscriber ID to use for personalization |
| ListID | Integer | No | List ID for subscriber lookup |
| CampaignID | Integer | No | Campaign ID for context |
| HTMLContent | String | Conditional | HTML content (if EmailID not provided) |
| PlainTextContent | String | Conditional | Plain text content (if EmailID not provided) |
| FromName | String | No | Override sender name |
| FromEmailAddress | String | No | Override sender email |
| Subject | String | No | Override email subject |
| PreHeaderText | String | No | Override preheader text |
| ReplyToName | String | No | Override reply-to name |
| ReplyToEmail | String | No | Override reply-to email |
| SenderDomain | String | No | Override sender domain |
| AddUserGroupHeaderFooter | Boolean | No | Add user group header/footer (default: true) |
| EmailType | String | No | Email type: optinconfirmation or regular (default) |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.emailpreview",
"SessionID": "your-session-id",
"EmailID": 12345,
"EmailAddress": "test@example.com",
"ListID": 100
}'{
"Success": true,
"ErrorCode": 0
}{
"Success": false,
"ErrorCode": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}0: Success
1: Missing required parameter EmailID
2: Missing required parameter EmailAddress
3: Email not found
4: Invalid email address format
5: Subscriber not found
6: List not found
7: Campaign not found
8: Email delivery failed or sender domain not found
9: Missing required parameter HTMLContent or PlainTextContent
10: Missing required parameter PlainTextContent
20: Preview/test-send rate limit exceeded for this account (see EMAIL_PREVIEW_RATE_LIMIT). Response includes a RetryAfter (seconds) field
21: Recipient address is on the suppression list (globally opted out) and cannot receive preview emailsTest Email Delivery Settings
POST/api/v1/email.delivery.testAPI Usage Notes
- Authentication required: Admin API Key
- Not available in demo mode
- v1 REST alias:
POST /api/v1/email.delivery.test. Legacy access via/api.phpis also supported
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.delivery.test |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.delivery.test",
"SessionID": "admin-session-id"
}'{
"Success": true
}{
"Success": false,
"ErrorCode": "NOT AVAILABLE IN DEMO MODE."
}1: Email delivery test failedTest Email Against Spam Filters
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Required permissions:
Email.SpamTest - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.spamtest |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID to test |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.spamtest",
"SessionID": "your-session-id",
"EmailID": 12345
}'{
"Success": true,
"ErrorCode": 0,
"TestResults": {
"score": 2.5,
"tests": [
{
"name": "BAYES_00",
"score": -1.9,
"description": "Bayes spam probability is 0 to 1%"
}
]
}
}{
"Success": false,
"ErrorCode": [1, 2, 3]
}0: Success
1: Missing required parameter EmailID
2: Email not found
3: Spam test service errorRender Email in Browser
GET/api/v1/email.renderAPI Usage Notes
- Authentication required: User API Key
- Rate limit: 10000 requests per 60 seconds
- Legacy endpoint access via
/api.phpis also supported
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.render |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| UserID | Integer | Yes | User ID |
| ListID | Integer | Yes | List ID |
| SubscriberID | Integer | Yes | Subscriber ID |
| CampaignID | Integer | Yes | Campaign ID |
| AutoResponderID | Integer | Yes | AutoResponder ID |
| EmailID | Integer | Yes | Email ID |
| QueueRowID | Integer | Yes | Email Gateway queue row ID |
| IsPreview | Boolean | Yes | Preview mode flag (1 or 0) |
| DisablePersonalization | Boolean | Yes | Disable personalization (1 or 0) |
curl -X GET "https://example.com/api/v1/email.render?UserID=100&ListID=50&SubscriberID=1000&CampaignID=200&EmailID=300&IsPreview=0&DisablePersonalization=0" \
-H "Content-Type: application/json"{
"Subject": "Monthly Newsletter",
"EmailContent": "<html><body>Personalized content...</body></html>"
}{
"Errors": [
{
"Code": 1,
"Message": "Missing UserID parameter"
}
]
}1: Missing UserID parameter
2: Missing ListID parameter
3: Missing SubscriberID parameter
4: Missing CampaignID parameter
5: Missing AutoResponderID parameter
6: Missing EmailID parameter
7: Missing QueueRowID parameter
8: Missing IsPreview parameter
9: Missing DisablePersonalization parameter
10: Invalid UserID parameter
11: Invalid ListID parameter
12: Invalid SubscriberID parameter
13: Invalid CampaignID parameter
14: Invalid AutoResponderID parameter
15: Invalid EmailID parameter
16: Invalid QueueRowID parameterRender Email for SMTP Delivery
POST/api/v1/email.smtp.renderAPI Usage Notes
- Authentication required: User API Key or Admin API Key
- Rate limit: 10000 requests per 60 seconds
- Legacy endpoint access via
/api.phpis also supported
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.smtp.render |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| UserID | Integer | No | User ID (auto-inferred from session or AdminAPIKey required) |
| CampaignID | Integer | No | Campaign ID (auto-infers EmailID and ListID) |
| AutoResponderID | Integer | No | AutoResponder ID (auto-infers EmailID and ListID) |
| EmailID | Integer | No | Email ID (auto-inferred from Campaign/AutoResponder) |
| ListID | Integer | No | List ID (auto-inferred from Campaign) |
| SubscriberID | Integer | No | Subscriber ID (random subscriber selected if not provided) |
| IsPreview | Boolean | No | Preview mode flag (accepts: 1/true/on/yes or 0/false/off/no) |
curl -X POST https://example.com/api/v1/email.smtp.render \
-H "Content-Type: application/json" \
-d '{
"Command": "email.smtp.render",
"SessionID": "your-session-id",
"CampaignID": 200
}'{
"Subject": "Monthly Newsletter",
"PreHeader": "Check out our latest updates",
"HTMLBody": "<html><body>...</body></html>",
"PlainBody": "Plain text version...",
"SMTPHeaders": "From: sender@example.com\r\nTo: recipient@example.com\r\n...",
"SMTPBody": "MIME encoded body with boundaries...",
"EmailSizeBytes": 45678,
"EmailSizeKB": 44.61,
"EmailSizeMB": 0.04,
"AttachmentCount": 2,
"ContentType": "MultiPart",
"HasHTMLContent": true,
"HasPlainContent": true,
"ImageEmbeddingEnabled": true,
"FromEmail": "sender@example.com",
"FromName": "Company Name",
"ReplyToEmail": "reply@example.com",
"ReplyToName": "Support Team",
"MFROMDomain": "return.example.com",
"TrackingDomain": "track.example.com"
}{
"Errors": [
{
"Code": 1,
"Message": "Missing or invalid UserID parameter"
}
]
}1: Missing or invalid UserID parameter
2: Invalid CampaignID parameter
3: Invalid AutoResponderID parameter
4: Missing or invalid EmailID parameter
5: Missing or invalid ListID parameter
6: Missing or invalid SubscriberID parameterGet Personalization Tags
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.personalizationtags |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| Scope | Array | Yes | Tag scopes: Subscriber, CampaignLinks, OptLinks, ListLinks, AllLinks, User |
| ListID | Integer | Conditional | List ID (required if Scope contains Subscriber) |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.personalizationtags",
"SessionID": "your-session-id",
"Scope": ["Subscriber", "CampaignLinks", "User"],
"ListID": 100
}'{
"Success": true,
"ErrorCode": 0,
"PersonalizationTags": [
{
"Tag": "%EmailAddress%",
"Description": "Subscriber email address",
"Category": "Subscriber"
},
{
"Tag": "%Link:Unsubscribe%",
"Description": "Unsubscribe link",
"Category": "Links"
}
]
}{
"Success": false,
"ErrorCode": [1, 2]
}0: Success
1: Missing required parameter Scope
2: Missing required parameter ListID (when Subscriber scope is included)Get Stripo Editor Settings
GET/api/v1/stripo.editor.getAPI Usage Notes
- Authentication required: User API Key or user session
- Legacy endpoint access via
/api.phpis also supported - Returns no Stripo credential. The Plugin ID and Secret Key stay in Octeth's settings (Admin > Settings > Integrations).
Tells a client whether the Stripo drag-and-drop builder is available on this installation, and which Stripo emailId its editor must send for the authenticated user. The emailId scopes the user's uploaded images on Stripo's CDN and is the same value the legacy builder sends, so both interfaces show the same image library. When STRIPO_BASE_USERID is set to a user ID, every user receives that user's emailId and shares one library.
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: stripo.editor.get |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
Response Fields:
| Field | Type | Description |
|---|---|---|
| Configured | Boolean | true when both the Stripo Plugin ID and Secret Key are saved in Octeth |
| EmailId | String | Stripo emailId for the authenticated user (32 hexadecimal characters) |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "stripo.editor.get",
"SessionID": "your-session-id"
}'{
"Success": true,
"ErrorCode": 0,
"Configured": true,
"EmailId": "65c18e4d9b80ea5e950e8fb3d8675c39"
}{
"Success": false,
"ErrorCode": 99998,
"ErrorText": "Authentication failure or session expired"
}0: Success
99998: Authentication failure or session expiredGet Stripo Editor Token
POST/api/v1/stripo.authAPI Usage Notes
- Authentication required: User API Key or user session
- Legacy endpoint access via
/api.phpis also supported - Rate limit: 120 requests per 60 seconds
- Octeth performs the Stripo plugin handshake with the credentials saved in Admin > Settings > Integrations and returns only the editor token. The Secret Key is never returned.
Returns a short-lived token for the Stripo embedded editor, for use in the editor's getAuthToken callback. This is the API form of the legacy user area's Stripo auth action.
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: stripo.auth |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
Response Fields:
| Field | Type | Description |
|---|---|---|
| Token | String | Stripo editor token issued by Stripo |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "stripo.auth",
"SessionID": "your-session-id"
}'{
"Success": true,
"ErrorCode": 0,
"Token": "eyJhbGciOiJIUzI1NiJ9..."
}{
"Success": false,
"ErrorCode": 1,
"ErrorText": "Stripo is not configured. An administrator can add the Stripo credentials in Admin > Settings > Integrations."
}0: Success
1: Stripo is not configured (Plugin ID or Secret Key not saved)
4: Stripo did not return an editor token (rejected credentials or Stripo unreachable)
99998: Authentication failure or session expiredCreate Email Template
POST/api/v1/email.template.createAPI Usage Notes
- Authentication required: User API Key or Admin API Key
- Required permissions:
EmailTemplates.Manage - v1 REST alias:
POST /api/v1/email.template.create. Legacy access via/api.phpis also supported
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.template.create |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| TemplateName | String | Yes | Template name |
| TemplateDescription | String | No | Template description |
| TemplateSubject | String | No | Default subject line |
| TemplateHTMLContent | String | Conditional | HTML template content (at least one required) |
| TemplatePlainContent | String | Conditional | Plain text template content (at least one required) |
| TemplateThumbnailPath | String | No | Bare file name returned by email.template.thumbnail.upload. Any value containing a path separator or .. is ignored |
| RelOwnerUserID | Integer | No | Owner user ID (admin only) |
| IsCreatedByAdmin | Boolean | No | Admin auth only. When passed, stored as given. When omitted the historical derivation applies: 1 if no RelOwnerUserID was named, else 0. Before v5.9.6 the parameter was ignored |
| AccessType | String | No | Access type setting |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.template.create",
"SessionID": "your-session-id",
"TemplateName": "Newsletter Template",
"TemplateDescription": "Monthly newsletter design",
"TemplateSubject": "Newsletter",
"TemplateHTMLContent": "<html><body>Template content</body></html>"
}'{
"Success": true,
"ErrorCode": 0,
"TemplateID": 500
}{
"Success": false,
"ErrorCode": [1, 2]
}0: Success
1: Missing required parameter TemplateName
2: At least one of TemplateHTMLContent or TemplatePlainContent must be providedGet Email Template
GET/api/v1/email.template.getAPI Usage Notes
- Authentication required: User API Key or Admin API Key
- Required permissions:
EmailTemplates.Manage - v1 REST alias:
GET /api/v1/email.template.get. Legacy access via/api.phpis also supported
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.template.get |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| TemplateID | Integer | Yes | Template ID to retrieve |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.template.get",
"SessionID": "your-session-id",
"TemplateID": 500
}'{
"Success": true,
"ErrorCode": 0,
"Template": {
"TemplateID": 500,
"TemplateName": "Newsletter Template",
"TemplateDescription": "Monthly newsletter design",
"TemplateSubject": "Newsletter",
"TemplateHTMLContent": "<html><body>Template content</body></html>",
"TemplatePlainContent": "Template content",
"RelOwnerUserID": 100
}
}{
"Success": false,
"ErrorCode": [1, 2, 3]
}0: Success
1: Missing required parameter TemplateID
2: Template not found
3: Access denied to templateGet Email Templates List
GET/api/v1/email.templates.getAPI Usage Notes
- Authentication required: User API Key or Admin API Key
- Required permissions:
EmailTemplates.Manage - v1 REST alias:
GET /api/v1/email.templates.get. Legacy access via/api.phpis also supported
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.templates.get |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.templates.get",
"SessionID": "your-session-id"
}'{
"Success": true,
"ErrorCode": 0,
"TotalTemplateCount": 5,
"Templates": [
{
"TemplateID": 500,
"TemplateName": "Newsletter Template",
"TemplateSubject": "Newsletter",
"TemplateHTMLContent": "<html>...</html>",
"TemplatePlainContent": "..."
}
]
}{
"Success": false,
"ErrorCode": []
}0: SuccessUpdate Email Template
POST/api/v1/email.template.updateAPI Usage Notes
- Authentication required: User API Key or Admin API Key
- Required permissions:
EmailTemplates.Manage - v1 REST alias:
POST /api/v1/email.template.update. Legacy access via/api.phpis also supported
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.template.update |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| TemplateID | Integer | Yes | Template ID to update |
| TemplateName | String | No | Template name |
| TemplateDescription | String | No | Template description |
| TemplateSubject | String | No | Default subject line |
| TemplateHTMLContent | String | No | HTML template content |
| TemplatePlainContent | String | No | Plain text template content |
| TemplateThumbnailPath | String | No | Bare file name returned by email.template.thumbnail.upload. The temp file is deleted after it is read |
| RelOwnerUserID | Integer | No | Owner user ID (admin only) |
| AccessType | String | No | Access type setting (admin only) |
| ClearFields | String | No | Comma-separated list of fields to empty: TemplateDescription, TemplateSubject, TemplateHTMLContent, TemplatePlainContent, TemplateThumbnail (also clears TemplateThumbnailType). Applied after the value parameters, so a field named in both is cleared. Sending an empty value without ClearFields still leaves the field unchanged (historical behaviour) |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.template.update",
"SessionID": "your-session-id",
"TemplateID": 500,
"TemplateName": "Updated Newsletter Template",
"TemplateHTMLContent": "<html><body>Updated content</body></html>"
}'{
"Success": true,
"ErrorCode": 0
}{
"Success": false,
"ErrorCode": [1, 2]
}0: Success
1: Missing required parameter TemplateID
2: Template not found or access denied
3: Invalid ClearFields entry
4: ClearFields would leave the template with neither an HTML nor a plain contentDelete Email Template
POST/api/v1/email.template.deleteAPI Usage Notes
- Authentication required: User API Key or Admin API Key
- Required permissions:
EmailTemplates.Manage - Not available in demo mode
- v1 REST alias:
POST /api/v1/email.template.delete. Legacy access via/api.phpis also supported
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.template.delete |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| Templates | String | Yes | Comma-separated template IDs to delete (e.g., "500,501,502") |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.template.delete",
"SessionID": "your-session-id",
"Templates": "500,501,502"
}'{
"Success": true,
"ErrorCode": 0
}{
"Success": false,
"ErrorCode": [1, 2]
}0: Success
1: Missing required parameter Templates
2: No templates found or access denied for deletionUpload an Email Template Thumbnail
POST/api/v1/email.template.thumbnail.uploadAPI Usage Notes
- Authentication required: Admin API Key or User API Key
- Required user permission:
EmailTemplates.Manage; required admin privilege:Settings - v1 REST alias:
POST /api/v1/email.template.thumbnail.upload. Legacy access via/api.phpis also supported - The returned
TemplateThumbnailPathis consumed byemail.template.createoremail.template.update(their existingTemplateThumbnailPathparameter). The temp file is deleted when it is consumed. Files that are never consumed stay indata/tmp/. - The image type is detected from the bytes and must be gif, png or jpeg (the same allow-list as the admin form).
ThumbnailTypemust agree with the detected type. - Size cap:
TEMPLATE_THUMBNAIL_MAX_FILESIZE(default 2 MB, decoded bytes).
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.template.thumbnail.upload |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| ThumbnailData | String | Yes | Base64-encoded image bytes. A data:image/png;base64, prefix is accepted and stripped |
| ThumbnailType | String | Yes | Declared type: gif, png, jpg or jpeg |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.template.thumbnail.upload",
"AdminAPIKey": "your-admin-api-key",
"ThumbnailData": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
"ThumbnailType": "png"
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": "",
"TemplateThumbnailPath": "templatethumbnail_3f0c1c8e9d0b4a2f8e7d6c5b4a3f2e1d",
"ThumbnailType": "image/png",
"ThumbnailSize": 68,
"Width": 1,
"Height": 1
}{
"Success": false,
"ErrorCode": [6],
"ErrorText": ["ThumbnailData is not a gif, png or jpeg image, or does not match ThumbnailType"]
}0: Success
1: Missing ThumbnailData
2: Missing ThumbnailType
3: Invalid ThumbnailType (gif, png, jpg, jpeg)
4: ThumbnailData is not valid base64
5: Thumbnail exceeds TEMPLATE_THUMBNAIL_MAX_FILESIZE bytes
6: ThumbnailData is not a gif, png or jpeg image, or does not match ThumbnailType
7: Thumbnail could not be written to the temp directorySearch Email Templates (Admin)
POST/api/v1/email.templates.searchAPI Usage Notes
- Authentication required: Admin API Key
- Required admin privilege:
Settings - v1 REST alias:
POST /api/v1/email.templates.search. Legacy access via/api.phpis also supported - Metadata only: the HTML and plain bodies and the base64 thumbnail are not returned. Fetch a single template with
email.template.getfor those. email.templates.getis unchanged (five columns, unpaged, bodies included). Third-party admin UIs should list with this command.RelOwnerUserIDfollows the ownership convention of the admin screen:0= all users, a negative value-<UserGroupID>= one user group, a positiveUserID= one user.
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.templates.search |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| RelOwnerUserID | Integer | No | Exact owner filter (0, negative group id or user id). Omit for all owners |
| IsCreatedByAdmin | Boolean | No | true = admin-created templates only, false = user-created only |
| SearchKeyword | String | No | Case-insensitive substring match on TemplateName, TemplateDescription and TemplateSubject |
| OrderField | String | No | TemplateID, TemplateName (default), RelOwnerUserID, IsCreatedByAdmin |
| OrderType | String | No | ASC (default) or DESC |
| RecordsFrom | Integer | No | Offset (default 0) |
| RecordsPerRequest | Integer | No | Page size (default 25, max 1000) |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.templates.search",
"AdminAPIKey": "your-admin-api-key",
"RelOwnerUserID": 0,
"SearchKeyword": "newsletter",
"OrderField": "TemplateName",
"OrderType": "ASC",
"RecordsFrom": 0,
"RecordsPerRequest": 25
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": "",
"TotalTemplateCount": 42,
"RecordsFrom": 0,
"RecordsPerRequest": 25,
"OrderField": "TemplateName",
"OrderType": "ASC",
"Templates": [
{
"TemplateID": "500",
"TemplateName": "Monthly Newsletter",
"TemplateDescription": "Two column layout",
"TemplateSubject": "Newsletter",
"RelOwnerUserID": "0",
"IsCreatedByAdmin": "1",
"Options": {"AccessType": "Public"},
"TemplateThumbnailType": "image/png",
"HasThumbnail": true,
"TemplateMD5ID": "...",
"AccessType": "Public"
}
]
}{
"Success": false,
"ErrorCode": [1],
"ErrorText": ["Invalid RelOwnerUserID"]
}0: Success
1: Invalid RelOwnerUserID (must be numeric)Create Design Preview (Deprecated)
DEPRECATED POST/api.phpDeprecated Endpoint
This endpoint is deprecated with no replacement or alternative. It was used for PreviewMyEmail.com integration which is no longer supported.
API Usage Notes
- Authentication required: User API Key
- Required permissions:
Email.DesignPreview - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.designpreview.create |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID to preview |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.designpreview.create",
"SessionID": "your-session-id",
"EmailID": 12345
}'{
"Success": true,
"ErrorCode": 0,
"JobID": 1000,
"PreviewMyEmailJobID": "abc123"
}{
"Success": false,
"ErrorCode": [1, 2, 3, 4, 5]
}0: Success
1: Missing required parameter EmailID
2: Email not found
3: Preview service connection error
4: Out of admin credits
5: Out of user creditsDelete Design Preview (Deprecated)
DEPRECATED POST/api.phpDeprecated Endpoint
This endpoint is deprecated with no replacement or alternative. It was used for PreviewMyEmail.com integration which is no longer supported.
API Usage Notes
- Authentication required: User API Key
- Required permissions:
Email.DesignPreview - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.designpreview.delete |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID |
| JobID | Integer | Yes | Preview job ID |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.designpreview.delete",
"SessionID": "your-session-id",
"EmailID": 12345,
"JobID": 1000
}'{
"Success": true,
"ErrorCode": 0
}{
"Success": false,
"ErrorCode": [1, 2, 3, 4, 5]
}0: Success
1: Missing required parameter EmailID
2: Missing required parameter JobID
3: Email not found
4: Preview job not found
5: Preview service connection errorGet Design Preview Details (Deprecated)
DEPRECATED POST/api.phpDeprecated Endpoint
This endpoint is deprecated with no replacement or alternative. It was used for PreviewMyEmail.com integration which is no longer supported.
API Usage Notes
- Authentication required: User API Key
- Required permissions:
Email.DesignPreview - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.designpreview.details |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID |
| JobID | Integer | Yes | Preview job ID |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.designpreview.details",
"SessionID": "your-session-id",
"EmailID": 12345,
"JobID": 1000
}'{
"Success": true,
"ErrorCode": 0,
"PreviewRequest": {
"JobID": 1000,
"PreviewMyEmailJobID": "abc123",
"Status": "Complete",
"PreviewResults": [
{
"ClientCode": "outlook2019",
"ImagesOnURL": "https://...",
"ImagesOffURL": "https://...",
"ThumbnailURL": "https://..."
}
]
}
}{
"Success": false,
"ErrorCode": [1, 2, 3, 4, 5]
}0: Success
1: Missing required parameter EmailID
2: Email not found
3: Missing required parameter JobID
4: Preview job not found
5: Preview service connection errorGet Design Preview List (Deprecated)
DEPRECATED POST/api.phpDeprecated Endpoint
This endpoint is deprecated with no replacement or alternative. It was used for PreviewMyEmail.com integration which is no longer supported.
API Usage Notes
- Authentication required: User API Key
- Required permissions:
Email.DesignPreview - Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.designpreview.getlist |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| EmailID | Integer | Yes | Email ID |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "email.designpreview.getlist",
"SessionID": "your-session-id",
"EmailID": 12345
}'{
"Success": true,
"ErrorCode": 0,
"PreviewList": [
{
"JobID": 1000,
"PreviewMyEmailJobID": "abc123",
"Status": "Complete",
"SubmitDate": "2024-01-15 10:30:00"
}
]
}{
"Success": false,
"ErrorCode": [1, 2]
}0: Success
1: Missing required parameter EmailID
2: Email not foundDelete Attachment
POST/api.phpAPI Usage Notes
- Authentication required: User API Key
- Legacy endpoint access via
/api.phponly (no v1 REST alias configured)
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: attachment.delete |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| AttachmentID | Integer | Yes | Attachment ID to delete |
curl -X POST https://example.com/api.php \
-H "Content-Type: application/json" \
-d '{
"Command": "attachment.delete",
"SessionID": "your-session-id",
"AttachmentID": 789
}'{
"Success": true,
"ErrorCode": 0,
"ErrorText": ""
}{
"Success": false,
"ErrorCode": [1]
}0: Success
1: Missing required parameter AttachmentIDConvert HTML to Plain Text
POST/api/v1/email.html2textAPI Usage Notes
- Authentication required: User API Key
- Rate limit: 1000 requests per 60 seconds
- Legacy endpoint access via
/api.phpis also supported
Stateless utility endpoint that converts an HTML email body into its plain-text equivalent. Useful when generating the PlainContent variant of a campaign email programmatically, for example during automated campaign creation or before sending through email.render.
Internally calls the same Soundasleep\Html2Text library used by the campaign-create UI's "Generate plain text from HTML" button, the email model's auto-conversion (when PlainContentAutoConvert is enabled), and the queue worker. Conversion options are hard-coded to match the UI verbatim (ignore_errors=true, drop_links=false), so the output is byte-for-byte identical to what users see in the in-app editor.
Behavior details:
- Link URLs are preserved inline (e.g.
<a href="https://example.com">Click</a>becomesClick [https://example.com]). - Merge tags such as
[SUBSCRIBER_FIRSTNAME]are preserved verbatim: the library only strips HTML markup, and merge tags live in text nodes. - Malformed HTML is tolerated; the library returns partial output rather than throwing.
- An empty
HTMLContentvalue returns an emptyPlainContent. - Character encoding is auto-detected via
mb_detect_encoding; UTF-8 is handled safely. - The endpoint performs no database access and has no per-user resource ownership. It is purely a stateless transform of the request payload.
Request Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Command | String | Yes | API command: email.html2text |
| SessionID | String | No | Session ID obtained from login |
| APIKey | String | No | API key for authentication |
| HTMLContent | String | Yes | The HTML to convert. Empty string is allowed and returns an empty PlainContent. |
curl -X POST https://example.com/api/v1/email.html2text \
-H "Content-Type: application/json" \
-d '{
"Command": "email.html2text",
"APIKey": "your-api-key",
"HTMLContent": "<h1>Hello</h1><p>Visit <a href=\"https://example.com\">our site</a> for details.</p>"
}'{
"Success": true,
"PlainContent": "HELLO\n\nVisit our site [https://example.com] for details."
}{
"Errors": [
{
"Code": 1,
"Message": "Missing HTMLContent parameter"
}
]
}1: Missing HTMLContent parameter (returned with HTTP 422)
2: HTML conversion failed (returned with HTTP 500, a defensive catch for the rare case the library throws despite ignore_errors=true)
