Skip to main content

Overview

The Migma.ai API provides programmatic access to our AI Email Engine that creates pixel-perfect, on-brand emails in 30 seconds. Build custom integrations, automate email creation workflows, track customer events, export to platforms like Mailchimp and HubSpot, and manage your entire email marketing infrastructure programmatically. Generate emails 200x faster and 95% cheaper with AI that learns your brand voice, fetches live content, and creates cross-client compatible HTML.

Base URL

All API requests should be made to:

Authentication

All API endpoints require authentication using API keys. Include your API key in the Authorization header:

Authentication Guide

Learn how to create and manage API keys

API structure

The Migma.ai API is organized around REST principles:
  • Predictable resource-oriented URLs
  • Standard HTTP response codes
  • JSON request and response bodies
  • Bearer token authentication

Request format

All POST, PATCH, and PUT requests should use JSON format:
Example request:

Response format

All API responses follow a consistent structure:

Success response

Error response

HTTP status codes

The API uses standard HTTP status codes:

Rate limiting

API requests are rate limited based on your plan: Rate limit information is included in response headers:
When rate limited (429 response), wait for the time specified in X-RateLimit-Reset before retrying. Enterprise agreements may use different limits — contact sales@migma.ai.

Pagination

List endpoints support pagination using limit and offset parameters:
Response includes pagination metadata:

Idempotency

POST endpoints accept an optional Idempotency-Key request header so you can safely retry a request after a network error or timeout without doing the work twice. It is opt-in: a request without the header is processed normally.
The header is a string up to 100 characters. Keys are scoped per API key, so the same key used by two different keys never collides.

Replay behavior

Within a 24 hour window, the first request with a given key runs normally and its response is cached. After that:
  • Same key and same body returns the original cached response, with the same status and body. The replay carries the response header Idempotent-Replayed: true, so you can tell a replay from a fresh execution.
  • Same key but a different body returns 409 with error code IDEMPOTENCY_CONFLICT. Mint a fresh key whenever the request genuinely changes.
  • A key longer than 100 characters is rejected with 400 and code IDEMPOTENCY_KEY_INVALID.
429 (rate limited) and 5xx (server) responses are not cached, so a retry with the same key runs again. This is what makes a retry after a transient failure safe. Use a deterministic key derived from the logical operation, so the same retry always produces the same key:

Anti-patterns

  • Never use a random value such as uuid() or a per-attempt timestamp like Date.now(). A new value on each attempt defeats deduplication across retries and process restarts, which is exactly the case the key exists for.
  • Don’t hash the request body and use that as the key. The body is already part of the conflict check, and a body hash makes every distinct payload its own key rather than identifying one logical operation.
The header is honored on the endpoints where a duplicate call is costly: sending an email (POST /v1/sending), sending or scheduling a campaign (POST /v1/campaigns/{id}/send and POST /v1/campaigns/{id}/schedule), and the contact write endpoints (POST /v1/contacts, POST /v1/contacts/bulk, and POST /v1/contacts/bulk-delete).

Brand / project scoping

An API key is scoped to your account, not to a single brand. Most resources (contacts, campaigns, segments, emails) live inside a project, so pass projectId on the requests that operate on them. Call GET /v1/projects first to discover the project IDs available to your key. A resource that belongs to a different project than the one you reference returns 404, the same as a resource that does not exist. The API does not reveal that a resource exists in a project you did not name.

Events & Webhooks

Use webhooks to receive supported Migma API and contact events in your own app, queue, or automation tool:

Events & Webhooks

Learn how to set up event notifications

API endpoints

Projects

Manage brand projects and imports:
  • GET /v1/projects - List all projects
  • GET /v1/projects/{projectId} - Get project details
  • POST /v1/projects/import - Import a new brand

Project editing

Edit project content including knowledge base, images, and logos:
  • GET /v1/projects/{projectId}/knowledge-base - List knowledge base entries
  • POST /v1/projects/{projectId}/knowledge-base - Add knowledge base entry
  • PUT /v1/projects/{projectId}/knowledge-base/{entryId} - Update entry
  • DELETE /v1/projects/{projectId}/knowledge-base/{entryId} - Remove entry
  • POST /v1/projects/{projectId}/images - Add image (URL-only)
  • PUT /v1/projects/{projectId}/images - Update image metadata
  • DELETE /v1/projects/{projectId}/images - Remove image
  • PUT /v1/projects/{projectId}/logos - Update logos
Project editing endpoints require the project:write permission.

Email generation

Generate AI-powered, on-brand emails with async processing:
  • POST /v1/projects/emails/generate - Generate an email (async)
  • GET /v1/projects/emails/{conversationId}/status - Check generation status and get result.emails[] with emailId, HTML, screenshots, and series order
  • GET /v1/emails/{emailId} - Fetch one generated email by ID
  • POST /v1/emails/{emailId}/edit - Prompt Migma to edit one generated email

Email validation

Comprehensive email testing and quality analysis:
  • POST /v1/emails/validate/compatibility - Compatibility report for major webmail, desktop, and mobile clients
  • POST /v1/emails/validate/links - Check all links for validity
  • POST /v1/emails/validate/spelling - AI-powered spell/grammar check
  • POST /v1/emails/validate/deliverability - Predict inbox placement
  • POST /v1/emails/validate/all - Run all validation checks

Email validation API

Learn about email compatibility testing, link analysis, and deliverability prediction

Email previews

Generate screenshots on real devices and email clients:
  • POST /v1/emails/previews - Create device previews
  • GET /v1/emails/previews/{previewId} - Get preview status & results
  • GET /v1/emails/devices/supported - List supported preview device IDs (web, desktop, mobile)

Email preview API

See the auto-generated preview endpoint docs in the API reference

Contacts

Manage your contacts via API:
  • GET /v1/contacts - List contacts
  • POST /v1/contacts - Add a contact
  • POST /v1/contacts/bulk - Bulk import contacts
  • POST /v1/contacts/bulk-delete - Batch delete contacts by email
  • POST /v1/contacts/status - Change contact status

Campaigns

Create and manage named marketing campaigns with lifecycle tracking:
  • GET /v1/campaigns - List campaigns
  • POST /v1/campaigns - Create a campaign from a generated email
  • GET /v1/campaigns/{id} - Get campaign details
  • POST /v1/campaigns/{id}/send - Send immediately
  • POST /v1/campaigns/{id}/schedule - Schedule for future delivery
  • POST /v1/campaigns/{id}/cancel - Cancel a scheduled campaign
  • POST /v1/campaigns/{id}/archive - Archive a campaign
  • POST /v1/campaigns/{id}/unarchive - Restore an archived campaign
  • GET /v1/campaigns/{id}/stats - Engagement stats
  • GET /v1/campaigns/{id}/logs - Per-recipient delivery logs

Exports

Export generated emails to files or platforms:
  • GET /v1/export/html/{conversationId} - Export as production HTML
  • GET /v1/export/mjml/{conversationId} - Export as MJML
  • GET /v1/export/pdf/{conversationId} - Export as PDF
  • GET /v1/export/klaviyo/{conversationId} - Export for Klaviyo
  • GET /v1/export/mailchimp/{conversationId} - Export for Mailchimp
  • POST /v1/export/hubspot - Export for HubSpot
  • GET /v1/export/status/{conversationId} - Poll export status

Error handling

Failed requests return the matching HTTP status code with this body:
The response does not include a separate machine-readable code field. Branch on the HTTP status code for programmatic handling, and treat error as a human-readable message for logging and display. For example, a missing scope returns HTTP 403 with error: "Insufficient permissions".

Environments

Use different API keys for different environments:

Production

Development/Testing

Test keys are separate from production keys and don’t affect your production data or rate limits.

SDKs & libraries

Node.js / TypeScript (available now)

SDK Documentation

Full SDK guide — configuration, error handling, polling helpers, and all 14 resources

CLI (available now)

CLI Documentation

Full CLI guide — all commands, workflows, and configuration

Need help?

Quickstart

Get started in under 5 minutes

Events & Webhooks

Set up event notifications

Authentication

Learn about API keys and security

Join Discord

Connect with developers and get support