Send Email With HTTP API
Use the HTTP Send API when your application wants to send email over HTTPS instead of SMTP. Start with dryRun: true to validate the same payload without queueing an email.
What You Need
from address must use the domain attached to the Motor Block.mk_live_... key, not an Account API Key.info@yourdomain.com.:::tip Key distinction
POST /v1/send uses a Motor Block API Key: Authorization: ApiKey mk_live_....
Do not use a Public API bearer token or an Account API Key for sending. :::
1. Dry-Run the Payload
Dry run validates authentication, sender domain, DNS readiness, recipient shape, subject, and body size. It does not create an email log or queue delivery work.
- curl
- Node.js
- Python
- PHP
- Go
curl -X POST "https://api.motorical.com/v1/send" \
-H "Authorization: ApiKey $MK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Dry run check",
"text": "Validate this email without sending it.",
"html": "<p>Validate this email without sending it.</p>",
"dryRun": true
}'
const response = await fetch('https://api.motorical.com/v1/send', {
method: 'POST',
headers: {
Authorization: `ApiKey ${process.env.MK_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'sender@yourdomain.com',
to: ['recipient@example.com'],
subject: 'Dry run check',
text: 'Validate this email without sending it.',
html: '<p>Validate this email without sending it.</p>',
dryRun: true
})
});
console.log(await response.json());
import os
import requests
response = requests.post(
"https://api.motorical.com/v1/send",
headers={
"Authorization": f"ApiKey {os.environ['MK_API_KEY']}",
"Content-Type": "application/json",
},
json={
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Dry run check",
"text": "Validate this email without sending it.",
"html": "<p>Validate this email without sending it.</p>",
"dryRun": True,
},
timeout=30,
)
print(response.json())
<?php
$payload = [
"from" => "sender@yourdomain.com",
"to" => ["recipient@example.com"],
"subject" => "Dry run check",
"text" => "Validate this email without sending it.",
"html" => "<p>Validate this email without sending it.</p>",
"dryRun" => true,
];
$ch = curl_init("https://api.motorical.com/v1/send");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: ApiKey " . getenv("MK_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
curl_close($ch);
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload := map[string]any{
"from": "sender@yourdomain.com",
"to": []string{"recipient@example.com"},
"subject": "Dry run check",
"text": "Validate this email without sending it.",
"html": "<p>Validate this email without sending it.</p>",
"dryRun": true,
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.motorical.com/v1/send", bytes.NewReader(body))
req.Header.Set("Authorization", "ApiKey "+os.Getenv("MK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}
Expected dry-run response:
{
"success": true,
"dryRun": true,
"data": {
"status": "validated",
"domain": "yourdomain.com",
"recipientCount": 1,
"bodySize": 42
}
}
2. Send the Email
Remove dryRun or set it to false. Add an Idempotency-Key header if your application may retry the request.
curl -X POST "https://api.motorical.com/v1/send" \
-H "Authorization: ApiKey $MK_API_KEY" \
-H "Idempotency-Key: order-12345-welcome-email" \
-H "Content-Type: application/json" \
-d '{
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Welcome to our app",
"text": "Thanks for signing up.",
"html": "<p>Thanks for signing up.</p>"
}'
Successful sends return a messageId and status: "queued".
3. Check Delivery
Use the Public API to inspect logs and timeline events. These endpoints use a short-lived bearer token minted with an Account API Key.
curl -H "Authorization: Bearer $TOKEN" \
"https://api.motorical.com/api/public/v1/messages/$MESSAGE_ID/timeline"
For real-time automation, create a webhook for message.delivered, message.bounced, and message.complained.
Common Errors
| Error | What it means | Fix |
|---|---|---|
401 Invalid API key format | The key is missing, truncated, or the wrong type. | Use a full mk_live_... Motor Block API Key. |
403 From address domain does not match | Sender domain is not attached to the Motor Block. | Send from the verified Motor Block domain. |
403 Domain DNS setup incomplete | SPF or DKIM is not ready. | Complete domain DNS setup before sending. |
422 Validation error | Required fields or body content are missing. | Include from, to, subject, and at least one of text or html. |