API Endpoints
All endpoints are relative to the base URL:
https://api.motorical.com/api/public/v1
For interactive testing, use the Swagger UI.
Motor Blocks
GET /motor-blocks
Lists all motor blocks you have access to. Use this first to discover your block IDs.
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks"
Response: Array of motor blocks with names, IDs, and basic info.
GET /motor-blocks/{id}/overview
One-call overview with totals, rates, reputation, rate limits, anomalies, and top domains.
Scopes: analytics.read, usage.read
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/overview"
Ideal for dashboards, health checks, and monitoring UIs that need a compact summary.
GET /motor-blocks/{id}/daily-summary
Daily rollups over a recent window (sent, delivered, bounced, complained + rates).
Parameters:
| Parameter | Description |
|---|---|
days | Number of days to include (up to your retention window) |
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/daily-summary?days=30"
GET /motor-blocks/{id}/rate-limits
Current usage vs your plan limits.
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/rate-limits"
Response: Current usage counts, limits, and reset times for burst/hour/day periods.
GET /motor-blocks/{id}/metrics
Email performance data (sent, delivered, bounced, complained) with time-series breakdowns.
Parameters:
| Parameter | Description |
|---|---|
interval | hour or day (required) |
from | Start time (ISO 8601) |
to | End time (ISO 8601) |
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/metrics?interval=hour&from=2024-01-15T00:00:00Z&to=2024-01-16T00:00:00Z"
GET /motor-blocks/{id}/logs
Search individual email events and records.
Parameters:
| Parameter | Description |
|---|---|
query | Search filter (see query syntax below) |
status | sent, delivered, bounced, complained, deferred, failed |
from | Start time (ISO 8601) |
to | End time (ISO 8601) |
limit | Max results (1–1000, default 100) |
cursor | For pagination (use nextCursor from response) |
Query Syntax:
recipient:user@example.com— specific email addressdomain:gmail.com— all emails to Gmailstatus:bounced— only bounced emailsmetadata.campaign_id:newsletter-2024— by campaign metadata
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/logs?query=domain:gmail.com&status=bounced&limit=50"
GET /motor-blocks/{id}/providers
Aggregate performance by mailbox provider (gmail, outlook, yahoo, other).
Parameters:
| Parameter | Description |
|---|---|
from | Start time (ISO 8601) |
to | End time (ISO 8601) |
limit | Max providers to return (default 20) |
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/providers?from=2024-01-01T00:00:00Z&to=2024-01-08T00:00:00Z"
GET /motor-blocks/{id}/error-codes
Summarize SMTP response codes with human-friendly categories and hints.
Parameters: from, to, limit (default 50)
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/error-codes?from=2024-01-01T00:00:00Z&to=2024-01-08T00:00:00Z"
GET /motor-blocks/{id}/config
Read-only snapshot of a motor block's non-sensitive configuration and domain status.
Scopes: config.read
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/config"
GET /motor-blocks/{id}/domain-health
Summarized SPF/DKIM/DMARC and verification status for the attached domain.
Scopes: config.read
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/domain-health"
GET /motor-blocks/{id}/deliverability
Deliverability matrix broken down by recipient domain. Shows delivery, bounce, complaint, and failure rates per domain.
Scopes: analytics.read
Parameters:
| Parameter | Description |
|---|---|
from | Start time (ISO 8601) |
to | End time (ISO 8601) |
limit | Max domains to return (1–200, default 50) |
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/deliverability?from=2024-01-01T00:00:00Z&to=2024-01-08T00:00:00Z&limit=20"
Response: Array of domains with total, delivered, bounced, complained, failed, and deliveryRate per domain.
GET /motor-blocks/{id}/reputation
Reputation score (0–100) calculated from bounce, complaint, and failure rates over your retention window.
Scopes: analytics.read
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/reputation"
Response: score (0–100), windowDays, totals (total, delivered, bounced, complained, failed), and rates (bounceRate, complaintRate, failRate as percentages).
GET /motor-blocks/{id}/anomalies
Bounce spike detection over a 14-day window. Flags anomalies when today's bounce rate exceeds 2× the historical average by more than 2 percentage points.
Scopes: analytics.read
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/anomalies"
Response: anomalies array (empty if none detected; each entry has type, todayRate, avgRate), and windowDays.
Messages
GET /messages/{messageId}
Look up a single message by its message ID.
Scopes: logs.read
Parameters:
| Parameter | Description |
|---|---|
includePII | true/false (requires logs.pii scope for unmasked recipients) |
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/messages/$MESSAGE_ID"
Response: Message details including messageId, recipient, status, smtpCode, and queuedAt.
GET /messages/{messageId}/timeline
Synthetic lifecycle view for a single message (queued → final result).
Scopes: logs.read
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/messages/$MESSAGE_ID/timeline"
Response: Full message details plus an events array showing the lifecycle (e.g. queued → delivered/bounced).
Use the messageId from your own logs or from /logs responses.
Webhooks
Full webhook CRUD is available. See the Webhooks reference for detailed examples including signature verification.
Scopes: All webhook endpoints require webhooks.manage.
GET /motor-blocks/{id}/webhooks
List all webhook endpoints for a motor block.
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/webhooks"
POST /motor-blocks/{id}/webhooks
Create a new webhook endpoint.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/webhook","events":["message.delivered"]}' \
"$BASE_URL/motor-blocks/$BLOCK_ID/webhooks"
PUT /motor-blocks/{id}/webhooks/{webhookId}
Update an existing webhook (url, events, or enabled status).
DELETE /motor-blocks/{id}/webhooks/{webhookId}
Delete a webhook endpoint.
POST /motor-blocks/{id}/webhooks/{webhookId}/test
Queue a test delivery to verify your endpoint is working.
GET /motor-blocks/{id}/webhooks/{webhookId}/deliveries
View recent delivery attempts for a webhook.
Parameters: limit (1–200, default 50)
GET /motor-blocks/{id}/webhooks/{webhookId}/stats
High-level stats for webhook delivery (delivered, failed, queued, failure rate, latency).
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/webhooks/$WEBHOOK_ID/stats?hours=24"
Parameters: hours (1–168, default 24)
Exports
See the Data Exports guide for a complete walkthrough.
GET /motor-blocks/{id}/exports/preview
Lightweight preview of recent logs without creating a background export job.
Scopes: analytics.read, logs.read
Parameters:
| Parameter | Description |
|---|---|
limit | Max records to return (default 100, max 500) |
includePII | true/false (requires logs.pii scope for unmasked recipients) |
curl -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/exports/preview?limit=100"
POST /motor-blocks/{id}/exports
Create a background export job. Returns 202 Accepted with the job ID.
Scopes: analytics.read
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"jobType":"logs"}' \
"$BASE_URL/motor-blocks/$BLOCK_ID/exports"
GET /motor-blocks/{id}/exports
List recent export jobs (up to 50) for this motor block.
Scopes: analytics.read
GET /exports/{jobId}
Check the status of an export job. When complete, includes a download_url with a 15-minute download token.
Scopes: analytics.read
GET /exports/{jobId}/download
Download a completed export as NDJSON. Requires the token query parameter from the job status response.
curl -o export.ndjson \
"$BASE_URL/exports/$JOB_ID/download?token=$DOWNLOAD_TOKEN"
Email Sending (HTTP API)
These endpoints use a different base URL and authentication from the Public API v1 endpoints above.
Base URL: https://api.motorical.com
Authentication: Motor Block API Key via Authorization: ApiKey mk_live_... or X-Api-Key: mk_live_... header.
POST /v1/send
Send an email via the HTTP API. Requires a Motor Block API key with a verified domain and valid DNS setup (SPF + DKIM).
curl -X POST https://api.motorical.com/v1/send \
-H "Authorization: ApiKey mk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Hello from Motorical",
"text": "Plain text body",
"html": "<p>HTML body</p>",
"dryRun": false
}'
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Sender address (must match motor block's verified domain) |
to | string or string[] | Yes | Recipient address(es) |
subject | string | Yes | Email subject |
text | string | One of text/html | Plain text body |
html | string | One of text/html | HTML body |
headers | object | No | Custom email headers (see Custom headers below) |
dryRun | boolean | No | Validate the send request without queueing mail or writing an email log. |
Response:
{
"success": true,
"data": {
"messageId": "uuid",
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Hello from Motorical",
"status": "queued",
"timestamp": "2026-04-10T12:00:00.000Z"
}
}
Domain Validation: The from address domain must match the motor block's assigned domain. The domain must be verified with DKIM and SPF configured.
Custom headers
The optional headers object sets additional message headers, which are applied to the outgoing message and DKIM-signed — for example In-Reply-To and References (to thread a reply into an existing conversation), Reply-To, List-Unsubscribe, or any custom X-* header.
For safety, reserved and spoofable headers are rejected with 400 (code: DISALLOWED_HEADERS):
From, Sender, Return-Path, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Content-*, DKIM-Signature, Received, Authentication-Results, ARC-*, and X-Motorical-*.
Use the from, to, and subject fields for those instead. Header values containing line breaks (CR/LF) are also rejected.
{
"from": "sender@yourdomain.com",
"to": "recipient@example.com",
"subject": "Re: Your question",
"text": "Thanks for reaching out…",
"headers": {
"In-Reply-To": "<CABc123@mail.gmail.com>",
"References": "<CABc123@mail.gmail.com>",
"List-Unsubscribe": "<mailto:unsubscribe@yourdomain.com>"
}
}
Use dryRun: true before a production send to verify authentication, sender domain, DNS setup, recipient shape, subject, and body size without creating a queued message:
curl -X POST https://api.motorical.com/v1/send \
-H "Authorization: ApiKey mk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Dry run check",
"text": "This validates only.",
"dryRun": true
}'
Dry-run responses return status: "validated" and include metadata such as sender domain, recipient count, and body size. They do not include a messageId because nothing was queued.
GET /v1/status
Check the API status.
curl https://api.motorical.com/v1/status
POST /v1/test-email
Validate SMTP setup parameters for customer setup flows. This endpoint uses the same Motor Block API Key authentication as /v1/send.
curl -X POST https://api.motorical.com/v1/test-email \
-H "Authorization: ApiKey mk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"method": "starttls",
"host": "mail.motorical.com",
"port": 2587,
"username": "your_motor_block_username",
"password": "your_motor_block_password",
"to": "recipient@example.com",
"subject": "Motorical SMTP setup test",
"requireTLS": true
}'
Email Validation
POST /api/email/validate
Validate a single email address. No authentication required (rate limited).
Base URL: https://api.motorical.com
curl -X POST https://api.motorical.com/api/email/validate \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
POST /api/email/validate/batch
Validate multiple email addresses at once. Requires authentication.
curl -X POST https://api.motorical.com/api/email/validate/batch \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"emails": ["user1@example.com", "user2@example.com"]}'
Events (Server-Sent Events)
GET /motor-blocks/{id}/events/stream
Real-time event stream of email delivery events.
Scopes: logs.read
curl -N -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/motor-blocks/$BLOCK_ID/events/stream"
The token can also be passed via ?token= or ?access_token= query parameters for browser-friendly SSE connections.
Events are delivered as SSE with types: ready, keepalive, and message. Maximum 3 concurrent SSE connections per token.