REST API
The Nitrosend REST API works with any HTTP client. Use it to integrate email marketing into your app, connect to automation platforms like Zapier or n8n, or build custom tools in any programming language.
All plans, including free plans, have full access to Nitrosend MCP/API/CLI. REST API access is not restricted to paid plans; plan limits apply to usage volume and paid add-ons.
Base URL
https://api.nitrosend.com/v1/myAll endpoints are prefixed with /v1/my and scoped to your account.
Authentication
Every request requires a Bearer token in the Authorization header:
Authorization: Bearer <your-nitrosend-api-key>Get your API key from Brand > API Keys in the Nitrosend dashboard.
Quick examples
Send an email
curl -X POST https://api.nitrosend.com/v1/my/messages \
-H "Authorization: Bearer $NITROSEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "email",
"to": "user@example.com",
"subject": "Welcome to our platform",
"html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
"body": "Welcome! Thanks for signing up."
}'List campaigns
curl https://api.nitrosend.com/v1/my/campaigns \
-H "Authorization: Bearer $NITROSEND_API_KEY"Create a contact
curl -X POST https://api.nitrosend.com/v1/my/contacts \
-H "Authorization: Bearer $NITROSEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"opt_in": true
}'Get account status
curl https://api.nitrosend.com/v1/my/account \
-H "Authorization: Bearer $NITROSEND_API_KEY"Language examples
Python
import requests
API_KEY = "nskey_live_your_key_here"
BASE_URL = "https://api.nitrosend.com/v1/my"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Send an email
response = requests.post(f"{BASE_URL}/messages", headers=HEADERS, json={
"channel": "email",
"to": "user@example.com",
"subject": "Hello from Python",
"html": "<h1>Hi!</h1>",
"body": "Hi!"
})
print(response.json())
# List campaigns
campaigns = requests.get(f"{BASE_URL}/campaigns", headers=HEADERS)
print(campaigns.json())JavaScript / Node.js
const API_KEY = "nskey_live_your_key_here";
const BASE_URL = "https://api.nitrosend.com/v1/my";
const headers = {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
};
// Send an email
const response = await fetch(`${BASE_URL}/messages`, {
method: "POST",
headers,
body: JSON.stringify({
channel: "email",
to: "user@example.com",
subject: "Hello from Node.js",
html: "<h1>Hi!</h1>",
body: "Hi!",
}),
});
console.log(await response.json());
// List campaigns
const campaigns = await fetch(`${BASE_URL}/campaigns`, { headers });
console.log(await campaigns.json());Ruby
require "net/http"
require "json"
API_KEY = "nskey_live_your_key_here"
BASE_URL = "https://api.nitrosend.com/v1/my"
def nitrosend_request(method, path, body = nil)
uri = URI("#{BASE_URL}#{path}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = case method
when :get then Net::HTTP::Get.new(uri)
when :post then Net::HTTP::Post.new(uri)
end
request["Authorization"] = "Bearer #{API_KEY}"
request["Content-Type"] = "application/json"
request.body = body.to_json if body
JSON.parse(http.request(request).body)
end
# Send an email
result = nitrosend_request(:post, "/messages", {
channel: "email",
to: "user@example.com",
subject: "Hello from Ruby",
html: "<h1>Hi!</h1>",
body: "Hi!"
})
puts resultTransactional messages
POST /v1/my/messages queues a single transactional email or SMS and returns
the message resource. Delivery happens through Nitrosend's normal background
sender, so the response means "accepted for sending", not "delivered".
For email, pass channel: "email", to, subject, and one of html,
body, or template_id. body is plain text; HTML belongs in html.
Optional per-message delivery options are available for email only:
{
"channel": "email",
"from": "Acme <hello@example.com>",
"to": "user@example.com",
"subject": "Your receipt",
"html": "<p>Thanks for your purchase.</p>",
"body": "Thanks for your purchase.",
"reply_to": "support@example.com",
"headers": { "X-Entity-Ref-ID": "order_123" },
"tags": { "kind": "receipt", "plan": "pro" }
}from / from_email must resolve to a verified sender identity for the brand.
Reserved provider headers and reserved Nitrosend tag keys are rejected. System
tags such as account_id, brand_id, and message_id are always controlled by
Nitrosend.
Pass an Idempotency-Key header on retries. Reusing the same key with the same
payload returns the original message. Reusing the key with a different payload
returns 409 idempotency_conflict.
Suppressions
GET /v1/my/suppressions lists the account's active email suppressions by
default. Use it to inspect hard bounces, soft-bounce suppressions, complaints,
manual suppressions, and the bounded provider diagnostic text retained from the
source feedback event.
Common filters include email, reason, source_provider, and active=false
for expired suppressions.
Endpoint reference
| Action | Method | Endpoint |
|---|---|---|
| Messages | ||
| Send a message | POST | /messages |
| List messages | GET | /messages |
| Suppressions | ||
| List suppressions | GET | /suppressions |
| Campaigns | ||
| List campaigns | GET | /campaigns |
| Create campaign | POST | /campaigns |
| Get campaign | GET | /campaigns/{id} |
| Update campaign | PATCH | /campaigns/{id} |
| Send campaign | POST | /campaigns/{id}/send |
| Contacts | ||
| List contacts | GET | /contacts |
| Create contact | POST | /contacts |
| Bulk import contacts | POST | /imports |
| Poll import status | GET | /imports/{id} |
| Lists | ||
| List contact lists | GET | /lists |
| Create list | POST | /lists |
| Add/remove contacts by email | POST | /lists/{id}/contacts/bulk |
| Templates | ||
| List templates | GET | /templates |
| Create template | POST | /templates |
| Get template | GET | /templates/{id} |
| Update template | PATCH | /templates/{id} |
| Send test email | POST | /templates/{id}/send_test |
| Flows | ||
| List flows | GET | /flows |
| Create flow | POST | /flows |
| Segments | ||
| List segments | GET | /segments |
| Account | ||
| Get account info | GET | /account |
See the full API Reference for detailed request/response schemas.
Bulk imports
Use POST /v1/my/imports with multipart/form-data to upload a CSV. The
response includes an import id; poll GET /v1/my/imports/{id} for status,
row counts, and row-level errors. For contact imports, pass options with
list_ids so imported contacts are assigned to the target list:
curl -X POST https://api.nitrosend.com/v1/my/imports \
-H "Authorization: Bearer $NITROSEND_API_KEY" \
-F "file=@contacts.csv" \
-F "resource=contacts" \
-F 'options={"list_ids":[88]}'Pagination
List endpoints return paginated results. Pagination headers are included in the response:
| Header | Description |
|---|---|
X-Total-Count | Total number of records |
X-Total-Pages | Total number of pages |
X-Page-Number | Current page number |
Use ?page=2&limit=25 query parameters to navigate pages.
Error handling
Errors return JSON with a consistent structure:
{
"error": true,
"code": "validation_error",
"message": "Email is required",
"validation_errors": {
"email": ["can't be blank"]
}
}| Status code | Meaning |
|---|---|
200 | Success |
201 | Created |
401 | Invalid or missing API key |
404 | Resource not found |
422 | Validation error |
429 | Rate limited |
OpenAPI spec
The full API specification is available as OpenAPI 3.1 YAML:
https://api.nitrosend.com/openapi.yamlImport this into any tool that supports OpenAPI — Postman, Insomnia, Swagger UI, or API clients in any language.
