API reference
Base URL https://api.inkpigeon.com/api/v1 · JSON in, JSON out.
Authentication
Every request carries your API key as a bearer token: Authorization: Bearer ink_live_…. Keys are created in Settings → API keys and scoped to your organization.
Sending
POST /api/v1/emails/send
Authorization: Bearer $INKPIGEON_API_KEY
Content-Type: application/json
{
"from": {"email": "no-reply@mail.yourcompany.com", "name": "Acme"},
"to": [{"email": "someone@example.com", "name": "Someone"}],
"reply_to": "support@yourcompany.com",
"subject": "Hello",
"html": "<p>Hi {{first_name}}</p>",
"text": "Hi {{first_name}}",
"template_id": null,
"variables": {"first_name": "Ada"},
"scheduled_at": null,
"headers": {"X-Campaign": "welcome"},
"tracking": {"opens": true, "clicks": true}
}Only from, to and subject plus one of html/text/template_id are required. {{variables}} are substituted per recipient. Set scheduled_at (ISO 8601) to send later. Add an Idempotency-Key header to make retries safe.
Endpoints
| POST | /emails/send | Send one email (up to 50 recipients) |
| POST | /emails/batch | Send up to 500 messages in one call |
| GET | /emails | List messages (filters: status, to, domain_id, dates) |
| GET | /emails/{id} | Message detail incl. delivery attempts |
| GET/POST | /contacts | List / create contacts |
| POST | /contacts/import | CSV import (multipart) |
| GET/POST | /lists | Contact lists; POST /lists/{id}/contacts adds members |
| GET/POST | /segments | Rule-based segments; POST /segments/preview counts |
| GET/POST | /templates | Versioned templates with variables |
| GET/POST | /campaigns | Bulk sends to lists/segments, A/B, scheduling |
| GET/POST | /webhooks | Signed event webhooks with retries |
| GET | /suppressions | Bounce/complaint/unsubscribe suppression list |
| GET | /analytics/summary | Delivery/open/click rollups |
List endpoints are paginated: ?page=1&per_page=50 → {data, page, per_page, total}.
Errors
Non-2xx responses use one envelope — a machine-readable code plus a human message (and extra fields where they help):
{
"error": {
"code": "plan_limit_reached",
"message": "Your plan allows at most 1 domains. Upgrade to add more.",
"limit": "domains",
"max": 1
}
}Rate limits
600 send requests/min and 300 other requests/min per organization. Responses include X-RateLimit-Remaining; a 429 carries Retry-After. Monthly email volume follows your plan.