API
GQ CRM Send API: Quickstart with X-API-Key
Send email from your own software in one request: authenticate with a per-project X-API-Key, use templates and variables, and understand quotas, rate limits, and error codes.
Published August 21, 2026
The Send API lets you fire emails from your own software — CRMs, scripts, automations, webhooks — using the same infrastructure as the dashboard: your project's SMTP, templates, tracking, and quota. This guide covers the one-request quickstart, template usage, and every error code you'll meet.
1. Authentication: X-API-Key
Every project has its own API key. Authenticate with a header:
X-API-Key: <your-project-api-key>
The key uniquely identifies the project — you don't need to pass a project ID. Find or rotate it under Dashboard → API Keys (rotation requires edit permission and invalidates the old key immediately; see the projects guide).
Keep keys per project. The per-project model means a leaked key exposes only one domain's sending, and you can rotate it without touching other projects.
2. The minimal send
curl -X POST https://your-domain.com/api/send \
-H "X-API-Key: YOUR_PROJECT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "[email protected]",
"subject": "Quick question",
"text": "Hi, would a 15-minute walkthrough help? — Alex"
}'
Success returns:
{ "success": true, "data": { "messageId": "..." } }
to accepts a single address or an array for batch sends. html/text are both supported (cc/bcc optional).
3. Templates and variables
Pass templateId to send a saved project template — the template's subject/html/text override the request content:
curl -X POST https://your-domain.com/api/send \
-H "X-API-Key: YOUR_PROJECT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": ["[email protected]", "[email protected]"],
"templateId": "your-template-id",
"variables": {
"[email protected]": { "name": "Sarah", "company": "Acme" },
"[email protected]": { "name": "Ken", "company": "Beta Inc" }
}
}'
Variables fill {{placeholder}} tokens per recipient (see the templates guide). If a variable is missing, the placeholder is left as-is.
4. Tracking
When the final content is HTML and your plan has tracking enabled (Starter/Pro; Free has none), GQ CRM injects an open pixel and rewrites absolute http(s) links for click tracking — each recipient gets their own tracking ID, and opens/clicks appear in project logs and analytics. No per-request opt-out: tracking is decided by the plan.
5. Quotas, rate limits, and error codes
The API enforces the same rules as the dashboard, in this order:
| Code | When |
|---|---|
| 401 | Missing or invalid X-API-Key |
| 400 | Project has no SMTP config; or missing to/subject; or no final HTML/text content |
| 403 | BLOCK_OUTBOUND_EMAILS=true (staging); API access not in your plan (Free → upgrade); quota exceeded |
| 404 | templateId doesn't belong to this project |
| 409 | Idempotency-Key reused with a different body |
| 429 | Rate limited — your plan's per-minute recipient limit (Free 60 / Starter 300 / Pro 1,000; a self-hosted install can override it with SEND_RATE_LIMIT_PER_MINUTE) |
Quota responses include data.quota = { current, limit, requested }; limit === -1 means the plan doesn't support sending. Successful sends increment your workspace usage (one-time credits are consumed before plan quota).
6. Beyond /api/send
For campaign-style sending with recipient verification, use the Email Tasks flow instead:
- Create a task via the dashboard or the tasks API (
POST /api/email-taskswith project, template, rate limit, and recipients). - Run verification, review invalid reasons, and start with Skip invalid (see the recipients guide).
- Track results in the task's recipient table and analytics.
Use /api/send for transactional and programmatic sends; use Email Tasks for campaigns that need verification and pacing.
Troubleshooting
- 401 — wrong key or a rotated key; regenerate from Dashboard → API Keys and update your integration.
- 403 with
feature_not_available— API access is Starter/Pro; the Free plan can't call the API (upgrade, or use the dashboard tasks flow). - 429 — you're over your plan's per-minute recipient limit (Free 60 / Starter 300 / Pro 1,000 per minute); batch or throttle your integration.
- 409 — you reused an
Idempotency-Keywith a different body. Send a new key for a new payload; reuse the same key only for a verbatim retry. templateId404 — the template belongs to a different project; templates are per-workspace, keys are per-project — keep them aligned.
That's the whole API: one header, one endpoint, and the same rules the dashboard follows. For the full request/response schema, see the API reference.