---
title: "Request a send approval"
method: POST
path: "/v1/send-approvals"
tags: ["Emails"]
---

# Request a send approval

`POST /v1/send-approvals`

## Request

- Base URL: `https://api.migma.ai`
- URL: `https://api.migma.ai/v1/send-approvals`
- Auth: API key in header `Authorization`

Holds a direct send, campaign send, or schedule for the account owner's approval in Migma and sends nothing. Migma checks the send as it would go out now and returns a summary with an approval link. The owner sends, schedules, or declines it on migma.ai; Migma checks it again then and refuses it if anything that decides who gets it, from whom, or when changed. Direct sends are marketing unless `transactional` is true, which is refused for tag and segment sends and needs a verified transactional sending identity. Requires API key with email:send (send_email) or campaign:write (campaign actions).

## Headers

- `Idempotency-Key` string

## Request body

- union: The send to hold for the account owner's approval. `send_email` takes the same body as POST /v1/sending.
  - object
    - `action` 'send_email', required
    - `send` SendEmailRequest, required
      - `recipientType` 'email' | 'audience' | 'segment' | 'tag', required: Type of recipient. 'email' for single send, 'audience' or 'segment' for segment-based batch sends, 'tag' for tag-based batch sends.
      - `recipientId` string: Required for audience/segment/tag sends. The segment or tag ID.
      - `recipientEmail` string, email: Required for single email sends.
      - `from` string, email, required: Sender email address (must be from a verified domain)
      - `fromName` string, required: Sender display name
      - `replyTo` string, email
      - `subject` string, required
      - `variables` object: Template variables for personalization
      - `providerType` 'ses' | 'resend' | 'sendgrid' | 'mailgun' | 'migma': Sending provider for Migma-managed email: migma, ses, resend, sendgrid, or mailgun. Defaults to Migma's built-in sending. Connect a provider in Settings → Integrations → Sending providers. Brand marketing-platform connections are separate Publish destinations.
      - `projectId` string: Project ID. Optional when emailId or conversationId resolves the project automatically.
      - `conversationId` string: Conversation ID from a generated email. Works for single-email conversations. For series, use emailId.
      - `transactional` boolean: Controls whether the email is treated as transactional (order confirmations, password resets) or marketing. Defaults to true for single sends (recipientType 'email') and false for batch sends (recipientType 'audience', 'segment', 'tag'). Transactional emails bypass subscription status and topic preference filters, and omit List-Unsubscribe headers. Bounced and invalid addresses are always excluded. Set explicitly to override the default.
      - `emailId` string: Generated email ID from result.emails[].emailId. Recommended for all generated emails and required for series slots.
  - object
    - `action` 'send_campaign', required
    - `campaignId` string, required
  - object
    - `action` 'schedule_campaign', required
    - `campaignId` string, required
    - `scheduledAt` string, date-time, required
    - `scheduledTimezone` string: IANA timezone. Omit to keep the campaign's.
    - `localTimeDelivery` boolean

## Response `201`

Approval created

- object
  - `success` boolean, required
  - `data` object, nullable
    - `id` string
    - `action` 'send_email' | 'send_campaign' | 'schedule_campaign'
    - `status` 'pending' | 'approving' | 'sent' | 'scheduled' | 'declined' | 'expired' | 'failed': `pending` waits for the owner; `expired` after 24 hours without a decision; `failed` carries `error`.
    - `summary` object: What the owner approves: audience (names and type), estimated recipients, from, fromName, subject, sendAt (null sends on approval), timezone, localTimeDelivery, and warnings.
    - `approvalUrl` string, uri: Page on migma.ai where the signed-in owner sends, schedules, or declines.
    - `editUrl` string, uri
    - `result` object
    - `error` string
    - `createdAt` string, date-time
    - `expiresAt` string, date-time
    - `decidedAt` string, date-time
  - `error` string, nullable

## Other responses

- `400`: Invalid request, or a send that cannot go out (for example an unverified sender)
- `401`: Invalid API key
- `403`: Missing permission
- `404`: Email, campaign, list, or segment not found
- `409`: Campaign cannot be sent in its current status
- `422`: Transactional send without a verified transactional identity

## Changes

- **2026-10-30** `61cd1df94cfd`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/migma/apis/migma-ai-api-v1/changes/v1/send-approvals/post.md)

---

[API](https://skmtc.dev/migma/apis/migma-ai-api-v1.md) - [All operations](https://skmtc.dev/migma/apis/migma-ai-api-v1/llms.txt) - [OpenAPI document](https://skmtc.dev/migma/apis/migma-ai-api-v1/revisions/61cd1df94cfd?raw)
