Home
API Integrations

REST API

Use the Nitrosend REST API from any language, tool, or automation platform

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.

Info

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/my

All 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 result

Transactional 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

ActionMethodEndpoint
Messages
Send a messagePOST/messages
List messagesGET/messages
Suppressions
List suppressionsGET/suppressions
Campaigns
List campaignsGET/campaigns
Create campaignPOST/campaigns
Get campaignGET/campaigns/{id}
Update campaignPATCH/campaigns/{id}
Send campaignPOST/campaigns/{id}/send
Contacts
List contactsGET/contacts
Create contactPOST/contacts
Bulk import contactsPOST/imports
Poll import statusGET/imports/{id}
Lists
List contact listsGET/lists
Create listPOST/lists
Add/remove contacts by emailPOST/lists/{id}/contacts/bulk
Templates
List templatesGET/templates
Create templatePOST/templates
Get templateGET/templates/{id}
Update templatePATCH/templates/{id}
Send test emailPOST/templates/{id}/send_test
Flows
List flowsGET/flows
Create flowPOST/flows
Segments
List segmentsGET/segments
Account
Get account infoGET/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:

HeaderDescription
X-Total-CountTotal number of records
X-Total-PagesTotal number of pages
X-Page-NumberCurrent 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 codeMeaning
200Success
201Created
401Invalid or missing API key
404Resource not found
422Validation error
429Rate limited

OpenAPI spec

The full API specification is available as OpenAPI 3.1 YAML:

https://api.nitrosend.com/openapi.yaml

Import this into any tool that supports OpenAPI — Postman, Insomnia, Swagger UI, or API clients in any language.