Documentation
/domains or /api-keys go to the dashboard and require signing in. For common questions, see the FAQ; for policies, see Legal.ZidiMail is a transactional email platform: verify your domain, create API keys, send mail over HTTPS, and receive delivery webhooks. This page describes the customer dashboard and the public HTTP API your applications call.
https://api.zidimails.com·Versioned prefix:/v1Overview
The stack has two surfaces you care about: the dashboard (browser UI at your app URL) for domains, keys, billing, and logs; and the REST API at https://api.zidimails.com/v1 for sending and querying from servers.
- Sending uses an API key (
POST /v1/emails) so only backend services hold secrets. - Dashboard session uses a JWT stored in the
zm_tokencookie after login; many read endpoints accept either JWT or API key via the sameAuthorization: Bearerheader. - Inbound provider hooks (
/inbound/ses,/inbound/mailgun) are internal — not for customer use.
Quick start
- Create an account and confirm your email if prompted.
- Open Domains, add your sending domain, and add the DNS records shown (SPF, DKIM, DMARC as applicable). Use Verify until the domain is verified.
- Open API Keys, create a key, and copy the full secret once — it is shown only at creation time.
- Call
POST https://api.zidimails.com/v1/emailsfrom your server withAuthorization: Bearer <full key>. - Optionally configure Webhooks for delivery events.
Dashboard areas
Searchable log of sent messages, statuses, and per-email detail.
Add domains, copy DNS records, run verification, remove domains.
Create and revoke keys. Full key secret is shown only once.
Register HTTPS endpoints, choose events, copy signing secret once.
Charts and delivery metrics driven by /v1/emails/stats.
Plan upgrades (PayPal subscription flow) and quota context.
Organization and account preferences; account deactivation flows.
Operators with admin privileges also see an Admin entry for internal tooling (JWT required, separate from API keys).
Authentication
Send Authorization: Bearer <token> on every request to /v1/*.
API key (server-to-server)
Keys look like zm_live_<id>_<secret>. Use them for automation and for POST /v1/emails (sending always requires an API key). Store keys in environment variables or a secrets manager — never in frontend code.
curl https://api.zidimails.com/v1/emails \ -H "Authorization: Bearer zm_live_<keyId>_<secret>"
Session JWT (dashboard)
After login, the UI stores a JWT in the zm_token cookie. The same token can be passed as Bearer for endpoints that use requireAuth (JWT or API key). Endpoints that require requireJwt accept only the dashboard JWT — for example creating API keys and managing PayPal billing.
APP_URL on the API. Call the REST API from your backend, or from the dashboard origin as the app already does.Send an email
Requires an API key (not JWT alone). The from address must use a domain that is verified for your organization.
Request body
fromrequiredtorequiredsubjectrequiredhtmlhtml or text is required.textccbccreply_toheaderstagsExample
curl -X POST https://api.zidimails.com/v1/emails \
-H "Authorization: Bearer zm_live_your_full_key" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@yourdomain.com",
"to": "user@example.com",
"subject": "Welcome",
"html": "<p>Thanks for signing up.</p>",
"text": "Thanks for signing up."
}'Response
{
"id": "<nanoid>",
"warning": "Optional — some recipients skipped (suppression list)"
}List & get emails
List recent messages for the organization. Accepts JWT or API key.
limitpagesearchcurl "https://api.zidimails.com/v1/emails?limit=20&page=1" \ -H "Authorization: Bearer <jwt_or_api_key>"
Get one email
Returns the email row plus related delivery events when present.
curl https://api.zidimails.com/v1/emails/<id> \ -H "Authorization: Bearer <jwt_or_api_key>"
Analytics & stats
Aggregates sent volume and rates for the org. Accepts JWT or API key.
daysResponse includes totals, counts by status, daily buckets, and computed delivery / bounce / complaint rates. The dashboard Analytics page consumes this endpoint.
curl "https://api.zidimails.com/v1/emails/stats?days=30" \ -H "Authorization: Bearer <jwt_or_api_key>"
Domains API
All routes require JWT or API key via Bearer auth.
Add domain
domainrequiredmail.example.com or example.com.Returns id, domain, and dns_records for SPF/DKIM/DMARC and Mailgun-aligned records.
List domains
Get domain
Includes merged DNS guidance and verification flags after checks.
Verify DNS
Re-runs SPF/DKIM (and related) checks and updates stored verification. Response includes checks and verified when SPF and DKIM pass.
Remove domain
API keys API
Creating and revoking keys requires a JWT (dashboard session), not an API key alone — so compromised automation keys cannot mint new keys.
Create key
namerequiredResponse includes key once: zm_live_<id>_<secret>. Save it immediately; only the prefix is listed afterward.
List keys
Revoke key
Webhooks API
Register HTTPS URLs to receive JSON notifications when delivery events occur. Requires JWT or API key for management routes.
Create webhook
urlrequiredeventsrequiredemail.sent, email.delivered, email.bounced, email.complained, email.opened, email.clicked.Response returns secret once (prefix whsec_) — used to verify ZidiMail-Signature on deliveries.
List webhooks
Secrets are omitted from list responses.
Delete webhook
Webhook signatures
Each delivery is a POST with body signed using HMAC-SHA256 and the webhook secret.
- Header
ZidiMail-Signature: sha256=<hex>— HMAC of the raw JSON body. - Header
ZidiMail-Event— same string astypein the JSON payload.
Payload shape
{
"type": "email.delivered",
"created_at": "2026-05-13T12:00:00.000Z",
"data": {
"email_id": "...",
"to": ["user@example.com"],
"from": "hello@yourdomain.com",
"subject": "Welcome"
}
}Verify by recomputing HMAC-SHA256 of the exact request body bytes with your webhook secret and comparing to the header (constant-time compare recommended).
Sandbox mode & ZidiGuard
Sandbox
Organizations in sandbox mode may only send to the org owner's registered email. Attempts to reach other recipients return 403 with guidance to contact support for production activation.
ZidiGuard (suppressions)
Addresses that hard-bounced or complained are suppressed. If every recipient in a send is suppressed, the API returns 422 and does not consume quota for those recipients. Partial suppression adds a warning in the send response.
Billing & plans
The dashboard Billing flow uses PayPal subscriptions (/billing/subscribe and related routes) with JWT auth. Plan tiers adjust monthly and daily sending limits (see table below).
Exact PayPal plan IDs and webhook verification are server-side; integrate billing only through the dashboard unless you are extending the API intentionally.
HTTP errors
Errors return JSON with at least error and often message and action for remediation.
401Unauthorized
Missing/invalid Bearer token or malformed API key.
403Forbidden
Sandbox restriction, or account suspended.
404Not found
Unknown email or domain id.
409Conflict
e.g. domain already added.
413Payload too large
Global body limit 2 MB (appeals endpoint allows more).
422Unprocessable
Validation, unverified domain, or all recipients suppressed.
429Rate limited
Burst, daily, monthly, warm-up, or IP limits.
500Server error
Unexpected failure — retry with backoff or contact support.
Example body
{
"error": "Domain \"example.com\" is not verified.",
"message": "Your sending domain must pass SPF/DKIM verification...",
"action": "Visit your ZidiMail dashboard → Domains → verify your DNS records."
}Rate limits
Multiple layers apply: per-IP limits on the API (e.g. login/register stricter than global traffic), per-org burst and “slow start” for new accounts, and plan daily/monthly quotas.
| Limit | Free | Pro | Scale |
|---|---|---|---|
| Monthly emails | 3,000 | 30,000 | 65,000 |
| Daily emails | 250 | Unlimited | Unlimited |
| Burst rate | 2/sec | Unlimited | Unlimited |
| Overage | Hard stop | $1.50 / 1k | $1.60 / 1k |
Monthly quota resets on the 1st of each month (UTC). When blocked, expect 429 with an explanatory message.
Security notes
- API keys and webhook secrets are high-privilege — rotate if leaked.
- The API sets strict security headers (HSTS, frame denial, nosniff, referrer policy).
- JWTs gate dashboard operations; sending requires API keys so browser extensions cannot steal send capability from cookies alone if keys stay server-side.
- Verify webhook signatures before trusting events; reject replayed or tampered bodies.