- © 2026 Mailsoftly Inc. The name "Mailsoftly" and the Mailsoftly logo are registered trademarks of Mailsoftly Inc.
This API provides a comprehensive interface for managing contacts, contact lists, and tags associated with firms. It is designed to support seamless integration for external systems or clients who need to interact with firm-related data.
All requests and responses use the JSON format. For POST and GET requests, ensure the request body adheres to the expected structure outlined for each endpoint. Responses include appropriate HTTP status codes, along with detailed messages in case of errors or validation failures.
As long as there is an Authorization header in your requests, you can use the examples under each method as well as send parameters as JSON. In both cases, as long as the parameters can be retrieved, the API will continue to respond. However, for cleaner operation, we recommend sending parameters as JSON in the body of the requests.
All API requests must be sent to the following endpoint;
https://app.mailsoftly.com/api/v3/
This is the base URL for all interactions with the API. Ensure that your requests are formatted correctly and sent to the appropriate endpoint depending on the operation (e.g., creating, updating, or retrieving data). Always include an Authorization header to authenticate your requests.
In case of an error, the API will return a JSON response in the following format:
{
"status": "error",
"error": "Error message"
}
Common error types include:
The Authentication is used to validate the API key provided in the request headers. It ensures that the API request is coming from an authorized source by verifying the API key associated with a specific firm. Upon successful authentication, this endpoint returns basic information about the firm, including the firm ID, firm name, and the name of the admin user.
This endpoint is typically called at the start of a session or interaction to verify that the API key is valid before proceeding with any further operations. If the API key is invalid or missing, the request will be denied, and an authentication error will be returned.
Example usage of the authentication might include:
/authentication
Authenticate the firm using an API key.
Headers:Authorization: API key of the firm.
Response:
{
"status": "success",
"firm_id": firm_id,
"firm_name": firm_name,
"admin_name": admin_name
}
The following example demonstrates how to authenticate using your API key:
curl -X POST "https://app.mailsoftly.com/api/v3/authentication" \
-H "Authorization: YOUR_API_KEY"
GET /get_contact_fields
Fetch all the contact fields available for a firm, excluding hidden columns.
[
{
"name": "field_name",
"type": "Field Type"
},
...
]
Use this example to get the available fields for contacts:
curl -X GET "https://app.mailsoftly.com/api/v3/get_contact_fields" \
-H "Authorization: YOUR_API_KEY"
GET /get_contacts
Retrieve a list of all contacts associated with the authenticated firm.
[
{
"id": contact_id,
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email"
},
...
]
This example demonstrates how to fetch all contacts for the authenticated firm:
curl -X GET "https://app.mailsoftly.com/api/v3/get_contacts" \
-H "Authorization: YOUR_API_KEY"
GET /get_contact
Fetch details for a specific contact based on the provided contact_id. You can choose between a basic or detailed view using the type parameter.
Parameters:contact_id: ID of the contact to fetch.type: ‘detailed’ for detailed information, omit or use any other value for basic information.
Response:
{
"id": contact_id,
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email"
}
The following example shows how to retrieve a specific contact’s information:
curl -X GET "https://app.mailsoftly.com/api/v3/get_contact?contact_id=123&type=detailed" \
-H "Authorization: YOUR_API_KEY"
POST /create_contact
Create a new contact for the authenticated firm.
Body Parameters:first_name: First name of the contact.last_name: Last name of the contact.email: Email address of the contact.
Response:
{
"id": contact_id,
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email"
}
The following example shows how to create a new contact:
curl -X POST "https://app.mailsoftly.com/api/v3/create_contact" \
-H "Authorization: YOUR_API_KEY" \
-d "first_name=John&last_name=Doe&email=johndoe@example.com"
POST /update_contact
Update the details of an existing contact.
Parameters:contact_id: ID of the contact to update.
Body Parameters:first_name, last_name, email: Updated contact details.
Response:
{
"id": contact_id,
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email"
}
This example demonstrates how to update an existing contact’s information:
curl -X POST "https://app.mailsoftly.com/api/v3/update_contact?contact_id=123" \
-H "Authorization: YOUR_API_KEY" \
-d "first_name=Jane&last_name=Doe&email=janedoe@example.com"
POST /create_or_update_contact
Create a new contact or update an existing one for the authenticated firm.
Parameters:contact_id: ID of the contact to update or nothing to create.
Body Parameters:first_name, last_name, email: or ther fields to create or update.
Response:
{
"status": "success",
"message": "Contact created/updated",
"contact": {
"id": contact_id,
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email"
}
}
This example demonstrates how to update an existing contact’s information or create new one:
curl -X POST "https://app.mailsoftly.com/api/v3/create_or_update_contact" \
-H "Authorization: YOUR_API_KEY" \
-d "first_name=John&last_name=Doe&email=johndoe@example.com&contact_id=123"
GET /search_contacts
Retrieve contacts based on the specified search criteria.
{
"status": "success",
"message": "Contacts found",
"contacts": [
{
"id": contact_id,
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email",
"source": "Source Info"
},
...
]
}
This example demonstrates how to search contact or contacts:
curl -X GET "https://app.mailsoftly.com/api/v3/search_contacts?first_name=John&email=johndoe@example.com" \
-H "Authorization: YOUR_API_KEY"
Contact Fields
Each of the following fields, except for the created_at and updated_at fields, is editable both when creating and updating a contact. Be sure to include the fields in your JSON request as "field_name": "field_value".
Below are the names and types of these fields.
{
"name": "first_name",
"type": "Character Varying"
},
{
"name": "last_name",
"type": "Character Varying"
},
{
"name": "job_title",
"type": "Character Varying"
},
{
"name": "email",
"type": "Character Varying"
},
{
"name": "address",
"type": "Text"
},
{
"name": "note",
"type": "Text"
},
{
"name": "created_at",
"type": "Timestamp Without Time Zone"
},
{
"name": "updated_at",
"type": "Timestamp Without Time Zone"
},
{
"name": "date_of_birth",
"type": "Date"
},
{
"name": "gender",
"type": "Integer"
},
{
"name": "country",
"type": "Character Varying"
},
{
"name": "city",
"type": "Character Varying"
},
{
"name": "mobile_phone",
"type": "Character Varying"
},
{
"name": "work_phone",
"type": "Character Varying"
},
{
"name": "industry",
"type": "Character Varying"
},
{
"name": "company",
"type": "Character Varying"
},
{
"name": "website",
"type": "Character Varying"
},
{
"name": "address_line_1",
"type": "Character Varying"
},
{
"name": "address_line_2",
"type": "Character Varying"
},
{
"name": "state",
"type": "Character Varying"
},
{
"name": "zip_code",
"type": "Character Varying"
},
{
"name": "new_custom_fields",
"type": "Jsonb"
},
{
"name": "source",
"type": "Character Varying"
},
{
"name": "opt_in_date",
"type": "Character Varying"
}
Custom Fields:
Custom fields are fields used to store information that falls outside the standard structure of a contact, such as first name and last name. They allow for the addition of custom information relevant to the contact.
Tags:
Tags are data points that can be used to group contacts or segment them based on specific types, categories, or events. They enable the organization of contacts for better management and targeting.
POST /add_custom_field_to_contact
Add a custom field to an existing contact for the authenticated firm.
{
"status": "success",
"custom_field_name": {
"type": "string",
"value": "Custom Field Value"
}
}
The following example shows how to add a custom field to a contact:
curl -X POST "https://app.mailsoftly.com/api/v3/add_custom_field_to_contact" \
-H "Authorization: YOUR_API_KEY" \
-d "contact_id=123&custom_field_name=Favorite Color&custom_field_value=Blue"
GET /get_custom_fields
Retrieve the custom fields associated with contacts for the authenticated firm.
{
"field_name": {
"type": "string",
"value": "Field Value"
},
...
}
The following example shows how to retrieve the custom fields for contacts:
curl -X GET "https://app.mailsoftly.com/api/v3/get_custom_fields" \
-H "Authorization: YOUR_API_KEY"
POST /assign_tag_to_contact
Assign a tag to an existing contact.
Parameters:contact_id: ID of the contact to tag.
Body Parameters:tag_id: ID of the tag to assign (optional if tag_name is provided).tag_name: Name of the tag to assign or create (optional if tag_id is provided).
Response:
{
"status": "success",
"info": "Tag name was successfully added to contact contact_id"
}
Use this example to assign a tag to a specific contact:
curl -X POST "https://app.mailsoftly.com/api/v3/assign_tag_to_contact?contact_id=123" \
-H "Authorization: YOUR_API_KEY" \
-d "tag_name=NewTag&tag_color=#00FF00"
POST /assign_tags_to_contact
Assign multiple tags to an existing contact at once. (Skips tags if they are already assigned to contact)
Parameters:contact_id: ID of the contact to tag.
Body Parameters:tags: JSON array of tags containing tag name and tag color
Response:
{
"status":"success",
"added_tags":["test"],
"skipped_tags":["Test Tag 2233","Important"]
}
Use this example to assign a tag to a specific contact:
curl -X POST "https://app.mailsoftly.com/api/v3/assign_tags_to_contact?contact_id=123" \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tags": [
{
"tag_name": "New Tag 1",
"tag_color": "#00FF00"
},
{
"tag_name": "New Tag 2",
"tag_color": "#00FF00"
}
]
}'
GET /get_contact_lists
Retrieve a list of all contact lists associated with the authenticated firm.
[
{
"id": contact_list_id,
"name": "Contact List Name",
"contact_count": contact_count
},
...
]
This example shows how to retrieve all contact lists for the authenticated firm:
curl -X GET "https://app.mailsoftly.com/api/v3/get_contact_lists" \
-H "Authorization: YOUR_API_KEY"
GET /get_contact_list
Fetch details of a specific contact list based on the provided contact_list_id.
Parameters:contact_list_id: ID of the contact list to fetch.
Response:
{
"id": contact_list_id,
"name": "Contact List Name",
"contacts_count": contact_count
}
Use this example to get details of a specific contact list:
curl -X GET "https://app.mailsoftly.com/api/v3/get_contact_list?contact_list_id=456" \
-H "Authorization: YOUR_API_KEY"
GET /get_contact_list_contacts
Retrieve all contacts within a specific contact list.
Parameters:contact_list_id: ID of the contact list to fetch.
Response:
[
{
"id": contact_id,
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email"
},
...
]
The following example demonstrates how to fetch all contacts in a specific contact list:
curl -X GET "https://app.mailsoftly.com/api/v3/get_contact_list_contacts?contact_list_id=456" \
-H "Authorization: YOUR_API_KEY"
POST /create_contact_list
Create a new contact list for the authenticated firm.
Body Parameters:name: Name of the contact list.
Response:
{
"id": contact_list_id,
"name": "Contact List Name"
}
This example shows how to create a new contact list:
curl -X POST "https://app.mailsoftly.com/api/v3/create_contact_list" \
-H "Authorization: YOUR_API_KEY" \
-d "name=New Contact List"
POST /add_contact_to_contact_list
Add an existing contact to a specific contact list.
Parameters:contact_list_id: ID of the contact list to modify.contact_id: ID of the contact to add.
Response:
{
"status": "success",
"info": "Contact contact_id was successfully added to Contact List contact_list_id"
}
Use this example to add a contact to a specific contact list:
curl -X POST "https://app.mailsoftly.com/api/v3/add_contact_to_contact_list?contact_list_id=456&contact_id=123" \
-H "Authorization: YOUR_API_KEY"
POST /add_contacts_to_contact_list
Add one or more contacts to a specific contact list.
If a contact with the given email does not exist, it will be created. If it exists, it will be reused.
Parameters:contact_list_id: ID of the contact list to modify.contacts: Array of contact objects to add. Each object must include at least an email address.
Response:
{
"status": "success",
"added_count": 2,
"errors": [
{
"contact": {
"email": "",
"first_name": "Jane"
},
"error": "Email is required"
}
]
}
Use this example to add multiple contacts to a specific contact list:
curl -X POST "https://app.mailsoftly.com/api/v3/add_contacts_to_contact_list" \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_KEY" \
-d '{
"contact_list_id": 456,
"contacts": [
{
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe"
},
{
"email": "jane@example.com"
}
]
}'
POST /create_emails
Creates one or more email drafts associated with contact lists. If contact_list_id is not provided, the system will create a contact list using the provided recipients.
⚠️ Attachments must be public URLs. The system does not download from private/protected links.
{
"status": "success",
"drafts": [
{
"id": 101,
"email_subject": "Update A",
"contact_list_id": 123
},
{
"id": 102,
"email_subject": "Update B",
"contact_list_id": 124
}
],
"errors": []
}
This endpoint accepts either a single email object or an array of emails via the mailLists key.
Each email object supports the following fields:
| Field | Type | Required? | Description |
|---|---|---|---|
subject | string | ✅ Yes | Subject line of the email draft. Cannot be blank. |
body | string (HTML) | ✅ Yes | HTML content of the email body. Can be empty but should be present. |
contact_list_id | integer | ❌ No | ID of an existing contact list in your firm. Either this or recipients must be provided. |
recipients | array of objects | ❌ No | Used to create a contact list on-the-fly if contact_list_id is not given. Each recipient must include at least email. |
sender_id | integer | ❌ No | ID of an active employee user in your firm to be used as the sender. If omitted, defaults will be used. |
reply_to | string (email) | ❌ No | Email address for replies. Defaults to the first user in the firm if not provided. |
attaches | array of objects | ❌ No | Publicly accessible URLs to files you want to attach. Each object must include a url, and optionally a filename. |
name | string | ❌ No | A custom name for the email draft. If not given, a default name is auto-generated. |
contact_list_id or recipients must be provided.recipients, each object must include:email (required)first_name (optional)last_name (optional)attaches) must be valid public URLs.url (required, must be a valid public URL)filename (optional)Use this example to one or more emails:
contact_list_id
curl -X POST "https://app.mailsoftly.com/api/v3/create_emails" \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_TOKEN" \
-d '{
"contact_list_id": 123,
"subject": "Monthly Newsletter",
"body": "Hello everyone, here is our monthly update.
",
"sender_id": 42,
"reply_to": "team@yourcompany.com",
"attaches": [
{ "url": "https://your-bucket.s3.amazonaws.com/docs/newsletter.pdf", "filename": "newsletter.pdf" }
],
"name": "July Newsletter"
}
'
recipients (no contact_list_id)
curl -X POST "https://app.mailsoftly.com/api/v3/create_emails" \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_TOKEN" \
-d '{
"subject": "Special Offer",
"body": "Check out our latest promotion!
",
"recipients": [
{ "email": "john@example.com", "first_name": "John", "last_name": "Doe" },
{ "email": "jane@example.com", "first_name": "Jane" }
],
"name": "Promo Email"
}'
mailLists)
curl -X POST "https://app.mailsoftly.com/api/v3/create_emails" \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_TOKEN" \
-d '{
"mailLists": [
{
"subject": "Welcome Series",
"body": "Thanks for signing up!
",
"recipients": [
{ "email": "alice@example.com", "first_name": "Alice" }
],
"attaches": [
{ "url": "https://cdn.domain.com/files/welcome-guide.pdf" }
]
},
{
"contact_list_id": 456,
"subject": "Product Update",
"body": "We just launched something new.
"
}
]
}
'
GET /email_status
Fetches the status of a specific email draft by its ID. Returns whether the draft is ready to send and the current status.
{
"id": 101,
"ready_to_send": true,
"status": "Draft"
}
{
"id": 102,
"ready_to_send": false,
"status": "Draft"
}
curl -X GET "https://app.mailsoftly.com/api/v3/email_status?id=101" \
-H "Authorization: YOUR_API_TOKEN"
POST /send_email
Sends an existing email draft if it is marked as ready.
{
"status": "success",
"message": "Email sent successfully,
"id": 101
}
curl -X POST "https://app.mailsoftly.com/api/v3/send_email" \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_TOKEN" \
-d '{
"id": 101
}'
GET /get_tags
Retrieve a list of all tags associated with the authenticated firm.
[
{
"id": tag_id,
"name": "Tag Name",
"color": "#00B0FF"
},
...
]
This example demonstrates how to retrieve all tags associated with contacts:
curl -X GET "https://app.mailsoftly.com/api/v3/get_tags" \
-H "Authorization: YOUR_API_KEY"
Authentication
Authenticates a request using a provided access token.
/authenticateGETapi_key (string, required) – The API Key for authentication.Response:
200 OK – Successful authentication.
{
"status": "success",
"firm": 123,
"firm_name": "Example Firm"
}
401 Unauthorized – Invalid access token or unauthorized request.
{
"status": "error",
"error": "Unauthorized",
"firm": null
}
Retrieves a list of email campaigns.
/campaign_meta_dataGETapi_key (string, required) – The API key for authentication.Response:
200 OK – Successful request.
[
{
"id": 123,
"name": "Campaign 1"
},
{
"id": 124,
"name": "Campaign 2"
},
...
]
Retrieves a list of contact lists.
/contact_list_meta_dataGETapi_key (string, required) – The API key for authentication.Response:
200 OK – Successful request.
[
{
"id": 123,
"name": "Contact List 1"
},
{
"id": 124,
"name": "Contact List 2"
},
...
]
Adds a contact to a specified contact list.
/handle_add_to_listPOSTapi_key (string, required) – The API key for authentication.Request Body:
{
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"contact_list": "List 1"
}
Response:
201 Created – Contact successfully added to the list.
{
"id": 123,
"name": "List 1"
}
401 Unauthorized – Invalid API key.
{
"error": "Wrong Api Key"
}
422 Unprocessable Entity – Unable to find the specified contact list.
{
"error": "Unable to find list"
}
Creates a new contact.
/handle_contact_createPOSTapi_key (string, required) – The API key for authentication.Request Body:
{
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com"
}
Response:
201 Created – Contact successfully created.
{
"id": 123,
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com"
}
401 Unauthorized – Invalid API key.
{
"error": "Wrong Api Key"
}
422 Unprocessable Entity – Error occurred during contact creation.
{
"error": "Unprocessable Entitiy"
}