Skip to main content

API Authentication

Motorical exposes more than one customer-facing API surface. Use the authentication method that matches the endpoint you are calling.

API surfaceBase URLAuth mechanismPrimary use
Public Analytics APIhttps://api.motorical.com/api/public/v1Short-lived bearer tokenLogs, analytics, configuration, webhooks, exports, SSE
Token minting APIhttps://api.motorical.com/api/publicAccount API Key or dashboard JWTCreate short-lived public API bearer tokens
HTTP Send APIhttps://api.motorical.com/v1/sendMotor Block API KeySend production email over HTTPS
Email validationhttps://api.motorical.com/api/email/validateNo auth for single validationValidate email address syntax/domain

Public Analytics API tokens are scoped, bound to a single Motor Block, and expire after 5 minutes by default.

Getting a Public API Bearer Token

Use a bearer token for endpoints under https://api.motorical.com/api/public/v1.

For server-to-server integrations, use a full Account API Key to mint short-lived public API tokens. The raw key value has this shape:

ak_live_<prefix>_<secret>

Copy the full key when you create it. A masked dashboard display value or key label is not usable for API calls.

curl -X POST https://api.motorical.com/api/public/token/account-key \
-H "Authorization: ApiKey ak_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"motorBlockId": "YOUR_MOTOR_BLOCK_ID",
"scopes": ["logs.read", "analytics.read", "usage.read"],
"ttlSeconds": 300
}'

You can also pass the same account key as X-Api-Key: ak_live_<prefix>_<secret>. Create account API keys in Settings -> Account API Keys in your dashboard. Scopes granted by the token are intersected with the scopes allowed on the key itself.

::::caution Account keys and Motor Block keys are different Use AK_API_KEY=ak_live_... only for token minting. Use MK_API_KEY=mk_live_... only for the HTTP Send API (/v1/send). A mk_live_... key will fail on /api/public/token/account-key, and an ak_live_... key will fail on /v1/send. ::::

Dashboard JWT Flow

If you already have a dashboard session JWT, you can mint a token with POST /api/public/token:

curl -X POST https://api.motorical.com/api/public/token \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"motorBlockId": "YOUR_MOTOR_BLOCK_ID",
"scopes": ["logs.read", "analytics.read", "usage.read"],
"ttlSeconds": 300
}'

This flow is mainly used by the Motorical dashboard and trusted internal tools. Customer server integrations should prefer the Account API Key flow above so they do not depend on a user login session.

Via the Dashboard

  1. Go to Settings -> API Access in your Motorical dashboard
  2. Select a Motor Block
  3. Check the permissions you need
  4. Generate a short-lived token

Using the Token

Include the token in the Authorization header of every request:

Authorization: Bearer <TOKEN>

For browser-friendly Server-Sent Events only, GET /events/stream also accepts ?token= or ?access_token= query parameters. Prefer the Authorization header everywhere else.

HTTP Send API Authentication

POST https://api.motorical.com/v1/send does not use the public bearer token or the Account API Key. It uses a full Motor Block API Key tied to the sending Motor Block:

mk_live_<prefix>_<secret>
curl -X POST https://api.motorical.com/v1/send \
-H "Authorization: ApiKey mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Hello from Motorical",
"text": "Plain text body"
}'

The send endpoint also accepts X-Api-Key: mk_live_YOUR_KEY. The from domain must match the Motor Block's verified domain and must have SPF and DKIM configured.

For production tests and examples, use a real sender address on your verified domain. Do not rely on placeholder senders such as test@yourdomain.com unless that is an intentional, monitored address for your account.

Permission Scopes

ScopeAccess
logs.readSearch and read email delivery logs
analytics.readAccess metrics, providers, error codes, daily summaries
usage.readView rate limits and usage counters
config.readRead motor block configuration and domain health
logs.piiAccess unmasked recipient email addresses in logs
webhooks.manageCreate, update, and delete webhook endpoints
tip

For most integrations, start with logs.read, analytics.read, and usage.read. Add config.read if you need domain health or configuration endpoints.

Token Format

Tokens are signed HS256 JWTs containing:

  • Motor Block ID binding
  • Granted scopes
  • User and client identifiers
  • Expiration timestamp (60–900 seconds)
  • Issuer: auth.motorical.com
  • Audience: smtp.motorical.com

Common Errors

StatusMeaningFix
401 UnauthorizedToken missing, invalid, or expiredGenerate a new token
403 ForbiddenToken lacks the required scopeRegenerate with the needed scope
403 ForbiddenMotor Block ID mismatchToken is bound to a different Motor Block
401 UnauthorizedAPI key format is invalidUse an ak_live_... account key for token minting or an mk_live_... Motor Block key for sending
403 ForbiddenSend domain mismatch or DNS incompleteSend from the verified domain attached to the Motor Block and complete SPF/DKIM setup