← Back to Senderkit

API Documentation

Send transactional emails from your app in 5 minutes.

Quick Start

Send your first email in 3 steps:

1. Get your API key

Go to Settings → API Keys and create a new key. Copy it — you'll only see it once.

2. Verify your domain

Add your sending domain in Settings → Domains and configure the DNS records.

3. Send an email

curl -X POST https://senderkit.hatched.digital/api/v1/email \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "hello@yourdomain.com",
    "to": "user@example.com",
    "subject": "Hello from Senderkit!",
    "html": "<h1>Welcome, {{name}}!</h1><p>Your account is ready.</p>",
    "variables": {
      "name": "Alex"
    }
  }'

Response:

{
  "id": "msg_a1b2c3d4-...",
  "status": "queued"
}

Authentication

All API requests require a valid API key sent in the Authorization header.

Authorization: Bearer sk_live_your_api_key_here

Security: Keep your API key secret. Never expose it in client-side code, public repositories, or browser requests. Use environment variables on your server.

Send Email

POST/api/v1/email

Send a single transactional email. Supports HTML, plain text, templates, and merge variables.

ParameterTypeRequiredDescription
fromstringYesSender email address (must be a verified domain)
tostring | string[]YesRecipient email(s), max 50
subjectstringYesEmail subject line
htmlstringNoHTML body content
textstringNoPlain text fallback
template_idstringNoUse a saved template by UUID
variablesobjectNoMerge variables for {{variable}} substitution
reply_tostringNoReply-to email address
tagsstring[]NoTags for filtering in analytics (max 10)
track_opensbooleanNoTrack email opens (default: true)
track_clicksbooleanNoTrack link clicks (default: true)

Example: Simple email

curl -X POST https://senderkit.hatched.digital/api/v1/email \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "from": "noreply@yourdomain.com",
    "to": "user@example.com",
    "subject": "Your password reset code",
    "html": "<p>Your code is: <strong>{{code}}</strong></p>",
    "variables": { "code": "483921" },
    "tags": ["password-reset"]
  }'

Example: Using a template

curl -X POST https://senderkit.hatched.digital/api/v1/email \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "from": "orders@yourdomain.com",
    "to": "customer@example.com",
    "subject": "Order #{{order_id}} confirmed",
    "template_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "variables": {
      "name": "Sarah",
      "order_id": "SK-1234",
      "total": "$49.99"
    }
  }'

Batch Send

POST/api/v1/email/batch

Send up to 100 emails in a single API call. Each message can have different recipients, subjects, and variables.

curl -X POST https://senderkit.hatched.digital/api/v1/email/batch \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "from": "noreply@yourdomain.com",
        "to": "alice@example.com",
        "subject": "Welcome, Alice!",
        "html": "<h1>Welcome, {{name}}!</h1>",
        "variables": { "name": "Alice" }
      },
      {
        "from": "noreply@yourdomain.com",
        "to": "bob@example.com",
        "subject": "Welcome, Bob!",
        "html": "<h1>Welcome, {{name}}!</h1>",
        "variables": { "name": "Bob" }
      }
    ]
  }'

Templates

Create email templates in the Senderkit dashboard using the drag-and-drop builder, then reference them in API calls with template_id.

Templates support {{variable}} merge variables that get replaced at send time.

Tip: Design your transactional templates in the Senderkit builder, then use them via API. Your brand colors, logo, and fonts are applied automatically.

Merge Variables

Use double curly braces to insert dynamic content:

<!-- In your HTML or template -->
<h1>Hello, {{name}}!</h1>
<p>Your order #{{order_id}} has shipped.</p>
<p>Track at: {{tracking_url}}</p>

<!-- API call -->
{
  "variables": {
    "name": "Sarah",
    "order_id": "1234",
    "tracking_url": "https://track.example.com/1234"
  }
}

Webhooks

Senderkit tracks email events automatically. View them in the Analytics dashboard or the Activity log.

Events tracked:

Sent
Delivered
Opened
Clicked
Bounced
Unsubscribed
Complained

Rate Limits

PlanEmails/monthRate
Trial (7 days)200 emails50/min
Starter5,00050/min
Growth50,000200/min
Business200,000500/min
Scale500,0001,000/min

Error Codes

StatusTypeDescription
400validation_errorInvalid request body (check error.errors for details)
401authentication_errorMissing or invalid API key
403permission_errorAPI key lacks required permission
404not_foundResource not found (e.g. template_id)
429rate_limit_errorToo many requests — slow down
500server_errorInternal server error — contact support

Error response format:

{
  "error": {
    "type": "validation_error",
    "message": ""to" must be a valid email address",
    "errors": [...]
  }
}

SDKs & Examples

Node.js

const response = await fetch("https://senderkit.hatched.digital/api/v1/email", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SENDERKIT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    from: "noreply@yourdomain.com",
    to: "user@example.com",
    subject: "Welcome!",
    html: "<h1>Hello, {{name}}!</h1>",
    variables: { name: "World" },
  }),
});

const { id, status } = await response.json();
console.log(`Email ${id}: ${status}`);

Python

import requests
import os

response = requests.post(
    "https://senderkit.hatched.digital/api/v1/email",
    headers={
        "Authorization": f"Bearer {os.environ['SENDERKIT_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "from": "noreply@yourdomain.com",
        "to": "user@example.com",
        "subject": "Welcome!",
        "html": "<h1>Hello, {{name}}!</h1>",
        "variables": {"name": "World"},
    },
)

data = response.json()
print(f"Email {data['id']}: {data['status']}")

PHP

$ch = curl_init("https://senderkit.hatched.digital/api/v1/email");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer " . getenv("SENDERKIT_API_KEY"),
    "Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "from" => "noreply@yourdomain.com",
    "to" => "user@example.com",
    "subject" => "Welcome!",
    "html" => "<h1>Hello, {{name}}!</h1>",
    "variables" => ["name" => "World"],
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = json_decode(curl_exec($ch), true);
echo "Email {$response['id']}: {$response['status']}";

Ruby

require "net/http"
require "json"

uri = URI("https://senderkit.hatched.digital/api/v1/email")
req = Net::HTTP::Post.new(uri.path, {
  "Authorization" => "Bearer #{ENV['SENDERKIT_API_KEY']}",
  "Content-Type" => "application/json"
})
req.body = {
  from: "noreply@yourdomain.com",
  to: "user@example.com",
  subject: "Welcome!",
  html: "<h1>Hello, {{name}}!</h1>",
  variables: { name: "World" }
}.to_json

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
puts "Email #{data['id']}: #{data['status']}"

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
    "os"
)

func main() {
    payload, _ := json.Marshal(map[string]interface{}{
        "from":      "noreply@yourdomain.com",
        "to":        "user@example.com",
        "subject":   "Welcome!",
        "html":      "<h1>Hello, {{name}}!</h1>",
        "variables": map[string]string{"name": "World"},
    })

    req, _ := http.NewRequest("POST",
        "https://senderkit.hatched.digital/api/v1/email",
        bytes.NewBuffer(payload))
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SENDERKIT_API_KEY"))
    req.Header.Set("Content-Type", "application/json")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()

    var result map[string]string
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Printf("Email %s: %s\n", result["id"], result["status"])
}

Questions? Email support@senderkit.com