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:

CodeWhen
401Missing or invalid X-API-Key
400Project has no SMTP config; or missing to/subject; or no final HTML/text content
403BLOCK_OUTBOUND_EMAILS=true (staging); API access not in your plan (Free → upgrade); quota exceeded
404templateId doesn't belong to this project
409Idempotency-Key reused with a different body
429Rate 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:

  1. Create a task via the dashboard or the tasks API (POST /api/email-tasks with project, template, rate limit, and recipients).
  2. Run verification, review invalid reasons, and start with Skip invalid (see the recipients guide).
  3. 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-Key with a different body. Send a new key for a new payload; reuse the same key only for a verbatim retry.
  • templateId 404 — 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.