REST API Reference

The TrackPost REST API allows you to send emails, manage templates, and track analytics from any programming language.

Table of Contents

Base URL

https://api.trackpost.de/v1

Authentication

All API requests require authentication using your API key in the Authorization header.

Header Format

Authorization: Bearer {your_api_key}

Example

curl https://api.trackpost.de/v1/emails \
  -H "Authorization: Bearer tp_live_your_api_key"

Warning

Security Warning: Never expose your API keys in client-side code, public repositories, or browser applications. Use environment variables or secret management systems.

API Key Types

TypePrefixPurposeRate Limits
Testtp_test_Development and testingSame as live
Livetp_live_Production emailsBased on your plan

Response Format

All responses are returned as JSON.

Success Response

{
  "success": true,
  "data": {
    // Response data here
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Error Response

{
  "success": false,
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please retry after 60 seconds.",
    "status": 429
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Rate Limiting

API requests are rate-limited based on your plan:

PlanRequests/MinuteMonthly Emails
Free601,000
Indie12010,000
Startup30050,000
Growth600250,000
Enterprise1,200Custom

Rate Limit Headers

Every response includes rate limit information:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1705323000

Handling Rate Limits

When you hit the rate limit, you’ll receive a 429 status code. Implement exponential backoff:

// Example retry logic
async function sendWithRetry(emailData, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await sendEmail(emailData);
    } catch (error) {
      if (error.status === 429) {
        const delay = Math.pow(2, i) * 1000;
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}

Emails

Send Email

Send a new email to one or more recipients.

Endpoint: POST /emails

Request Body:

{
  "to": "[email protected]",
  "from": "[email protected]",
  "subject": "Welcome!",
  "html": "<h1>Welcome!</h1>",
  "text": "Welcome!",
  "cc": ["[email protected]"],
  "bcc": ["[email protected]"],
  "reply_to": "[email protected]",
  "attachments": [
    {
      "filename": "document.pdf",
      "content": "base64_encoded_content",
      "contentType": "application/pdf"
    }
  ],
  "template_id": "welcome_email",
  "variables": {
    "user_name": "John Doe"
  },
  "tags": ["onboarding", "welcome"],
  "track_opens": true,
  "track_clicks": true,
  "scheduled_at": "2025-01-20T10:00:00Z"
}

Parameters:

FieldTypeRequiredDescription
tostring | arrayYesRecipient email(s)
fromstringYesSender email address
subjectstringConditional*Email subject
htmlstringConditional*HTML content
textstringNoPlain text content
ccstring | arrayNoCC recipients
bccstring | arrayNoBCC recipients
reply_tostringNoReply-to address
attachmentsarrayNoFile attachments
template_idstringConditional*Template ID to use
variablesobjectNoTemplate variables
tagsarrayNoTags for analytics
track_opensbooleanNoEnable open tracking (default: true)
track_clicksbooleanNoEnable click tracking (default: true)
scheduled_atstringNoISO 8601 datetime for scheduled send

* Either html or template_id is required. If using template_id, subject can come from the template.

Response:

{
  "success": true,
  "data": {
    "id": "msg_abc123def456",
    "to": "[email protected]",
    "from": "[email protected]",
    "subject": "Welcome!",
    "status": "sent",
    "created_at": "2025-01-15T10:30:00Z",
    "scheduled_at": null,
    "tags": ["onboarding", "welcome"]
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Example:

curl -X POST https://api.trackpost.de/v1/emails \
  -H "Authorization: Bearer tp_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "[email protected]",
    "from": "[email protected]",
    "subject": "Welcome!",
    "html": "<h1>Welcome!</h1>"
  }'

List Emails

Retrieve a list of emails with optional filtering.

Endpoint: GET /emails

Query Parameters:

ParameterTypeDescription
limitintegerNumber of results (1-100, default: 20)
offsetintegerPagination offset
statusstringFilter by status: sent, delivered, bounced, complained
from_datestringFilter by date (ISO 8601)
to_datestringFilter by date (ISO 8601)
tostringFilter by recipient email
fromstringFilter by sender email
tagsstringComma-separated list of tags

Response:

{
  "success": true,
  "data": {
    "emails": [
      {
        "id": "msg_abc123",
        "to": "[email protected]",
        "from": "[email protected]",
        "subject": "Welcome!",
        "status": "delivered",
        "created_at": "2025-01-15T10:30:00Z",
        "delivered_at": "2025-01-15T10:30:02Z"
      }
    ],
    "pagination": {
      "total": 150,
      "limit": 20,
      "offset": 0,
      "has_more": true
    }
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Example:

curl "https://api.trackpost.de/v1/emails?limit=10&status=delivered" \
  -H "Authorization: Bearer tp_live_your_key"

Get Email

Retrieve details of a specific email.

Endpoint: GET /emails/{id}

Response:

{
  "success": true,
  "data": {
    "id": "msg_abc123",
    "to": "[email protected]",
    "from": "[email protected]",
    "subject": "Welcome!",
    "html": "<h1>Welcome!</h1>",
    "text": "Welcome!",
    "status": "delivered",
    "created_at": "2025-01-15T10:30:00Z",
    "sent_at": "2025-01-15T10:30:01Z",
    "delivered_at": "2025-01-15T10:30:02Z",
    "opened_at": "2025-01-15T10:35:00Z",
    "opens_count": 2,
    "clicks_count": 1,
    "tags": ["onboarding"],
    "bounce_reason": null,
    "template_id": null,
    "variables": null
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Cancel Scheduled Email

Cancel an email that hasn’t been sent yet.

Endpoint: DELETE /emails/{id}

Response:

{
  "success": true,
  "data": {
    "id": "msg_abc123",
    "status": "cancelled"
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Templates

Create Template

Create a new email template.

Endpoint: POST /templates

Request Body:

{
  "name": "welcome_email",
  "subject": "Welcome to {{company}}, {{user_name}}!",
  "html": "<h1>Welcome, {{user_name}}!</h1><p>We're excited to have you at {{company}}.</p>",
  "text": "Welcome {{user_name}}! We're excited to have you at {{company}}."
}

Response:

{
  "success": true,
  "data": {
    "id": "tpl_abc123",
    "name": "welcome_email",
    "subject": "Welcome to {{company}}, {{user_name}}!",
    "html": "<h1>Welcome, {{user_name}}!</h1>...",
    "text": "Welcome {{user_name}}!...",
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-15T10:30:00Z"
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

List Templates

Endpoint: GET /templates

Query Parameters:

ParameterTypeDescription
limitintegerNumber of results (1-100, default: 20)
offsetintegerPagination offset

Get Template

Endpoint: GET /templates/{id}

Update Template

Endpoint: PATCH /templates/{id}

Request Body: (all fields optional)

{
  "name": "welcome_email_v2",
  "subject": "Welcome!",
  "html": "<h1>Welcome!</h1>",
  "text": "Welcome!"
}

Delete Template

Endpoint: DELETE /templates/{id}

Render Template (Preview)

Render a template with variables to preview the output.

Endpoint: POST /templates/{id}/render

Request Body:

{
  "variables": {
    "user_name": "Test User",
    "company": "Test Company"
  }
}

Response:

{
  "success": true,
  "data": {
    "subject": "Welcome to Test Company, Test User!",
    "html": "<h1>Welcome, Test User!</h1><p>We're excited to have you at Test Company.</p>",
    "text": "Welcome Test User! We're excited to have you at Test Company."
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Domains

List Domains

Endpoint: GET /domains

Response:

{
  "success": true,
  "data": {
    "domains": [
      {
        "domain": "yourapp.com",
        "status": "verified",
        "dkim_verified": true,
        "spf_verified": true,
        "dmarc_verified": true,
        "created_at": "2025-01-15T10:30:00Z"
      }
    ]
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Add Domain

Endpoint: POST /domains

Request Body:

{
  "domain": "yourapp.com"
}

Response: Includes DNS records to add:

{
  "success": true,
  "data": {
    "domain": "yourapp.com",
    "status": "pending",
    "dns_records": [
      {
        "type": "TXT",
        "name": "_amazonses.yourapp.com",
        "value": "token_abc123",
        "purpose": "verification"
      },
      {
        "type": "TXT",
        "name": "yourapp.com",
        "value": "v=spf1 include:amazonses.com ~all",
        "purpose": "spf"
      },
      {
        "type": "TXT",
        "name": "selector1._domainkey.yourapp.com",
        "value": "DKIM_key_1",
        "purpose": "dkim"
      }
    ]
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Verify Domain

Endpoint: POST /domains/{domain}/verify

Get Domain

Endpoint: GET /domains/{domain}

Delete Domain

Endpoint: DELETE /domains/{domain}

API Keys

List API Keys

Endpoint: GET /api-keys

Create API Key

Endpoint: POST /api-keys

Request Body:

{
  "name": "Production API Key",
  "environment": "live",
  "rate_limit": 60
}

Response:

{
  "success": true,
  "data": {
    "id": "key_abc123",
    "name": "Production API Key",
    "key": "tp_live_abc123def456", // Only shown once!
    "environment": "live",
    "rate_limit": 60,
    "created_at": "2025-01-15T10:30:00Z"
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Revoke API Key

Endpoint: DELETE /api-keys/{id}

Webhooks

List Webhooks

Endpoint: GET /webhooks

Create Webhook

Endpoint: POST /webhooks

Request Body:

{
  "url": "https://yourapp.com/webhooks/trackpost",
  "events": ["email.delivered", "email.bounced", "email.opened"],
  "secret": "your_webhook_secret" // optional, for signature verification
}

Update Webhook

Endpoint: PATCH /webhooks/{id}

Delete Webhook

Endpoint: DELETE /webhooks/{id}

Analytics

Get Email Stats

Endpoint: GET /analytics/emails

Query Parameters:

ParameterTypeDescription
from_datestringStart date (ISO 8601)
to_datestringEnd date (ISO 8601)
group_bystringGroup by: day, week, month

Response:

{
  "success": true,
  "data": {
    "total": {
      "sent": 1000,
      "delivered": 980,
      "bounced": 15,
      "complained": 5,
      "opened": 450,
      "clicked": 120
    },
    "by_date": [
      {
        "date": "2025-01-15",
        "sent": 100,
        "delivered": 98,
        "bounced": 2
      }
    ]
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-01-15T10:30:00Z"
  }
}

Error Codes

HTTP Status Codes

CodeMeaningDescription
200OKRequest successful
201CreatedResource created successfully
204No ContentRequest successful, no body
400Bad RequestInvalid request parameters
401UnauthorizedInvalid or missing API key
403ForbiddenInsufficient permissions
404Not FoundResource not found
409ConflictResource conflict (e.g., duplicate)
422UnprocessableValidation error
429Too Many RequestsRate limit exceeded
500Server ErrorInternal server error

Error Codes

CodeDescription
authentication_errorAPI key is invalid or expired
authorization_errorInsufficient permissions
validation_errorRequest validation failed
not_foundResource doesn’t exist
rate_limit_exceededRate limit reached
domain_not_verifiedSending domain not verified
template_not_foundTemplate ID doesn’t exist
invalid_variablesTemplate variables missing or invalid
aws_errorAWS SES error
internal_errorServer error

SDKs and Libraries

While you can use the REST API directly, we recommend our official SDKs:

  • Node.js SDK
  • Python SDK (Coming Q1 2026)
  • Go SDK (Coming Q2 2026)

Next Steps