POST /v1/brands/{brand_id}/emails/ai-compositions

Write a pitch with AI

Write a pitch email with AI (a backlink request, an inclusion in a list, a relationship, a follow-up) from what was learned about the cited page and the brand, and save it as a draft for review. Nothing is sent. Pricing: 1 credit per pitch, charged to the brand owner and refunded when the writing fails. Requires the editor role and the brand owner on Pro. A client seat cannot reach emails.

Path parameters

Query parameters

  • dry_run boolean optional

    Preview the call without executing it. Runs auth, scope, eligibility and body validation, then returns 200 with a dry_run object reporting the request-unit and credit cost plus a non-consuming quota snapshot. Nothing is debited, reserved, dispatched or mutated. An invalid body still returns 422.

    default: false

Header parameters

  • Idempotency-Key string required

    Required with an API key, else 400 idempotency_key_required: a new value per operation (a UUID works). A retry with the same key and body within 24 hours replays the first response instead of running again. Ignored with dry_run=true.

Request body

application/json required
Type: EmailComposition
  • recipient_email string required

    Recipient.

    min length: 1 · max length: 255

  • citation_url string (nullable) nullable

    The cited page the pitch is about; what was learned about it shapes the email.

  • custom_instructions string (nullable) nullable

    What to say or stress.

  • mailbox_id string (nullable) nullable

    The Gmail mailbox it should go out from.

  • recipient_name string (nullable) nullable

    The recipient's name.

  • request_backlink (default), request_inclusion, build_relationship, follow_up or pitch.

    default: `request_backlink`

  • tone enum

    professional (default), casual, friendly or formal.

    default: `professional`

Example payload
{
  "citation_url": "https://www.runnersworld.com/gear/a20865766/best-running-shoes/",
  "custom_instructions": "Mention the Tree Runner's merino upper.",
  "recipient_email": "alex.rivera@e2e.test",
  "recipient_name": "Alex Rivera",
  "template_type": "request_inclusion",
  "tone": "friendly"
}

Responses

Write a pitch with AI application/json
Type: Email
  • body string required

    HTML body.

  • brand_id string required

    Owning brand id.

  • follow_up_number integer required

    0 for the first email of a thread, then 1, 2...

    min: 0

  • id string required

    Email id.

  • recipient_email string required

    Recipient.

  • status enum required

    draft, scheduled (queued to go out), sent, opened, replied, bounced, failed or unsubscribed.

  • subject string required

    Subject.

  • tone enum required

    professional, casual, friendly or formal.

  • body_text string (nullable) nullable

    Plain-text body.

  • bounced_at string (nullable) nullable

    When it bounced.

    format: `date-time`

  • campaign_id string (nullable) nullable

    The campaign that created it.

  • citation_id string (nullable) nullable

    That page's id, when it is in Backlink outreach.

  • citation_url string (nullable) nullable

    The cited page the pitch is about.

  • contact_id string (nullable) nullable

    The contact it goes to.

  • created_at string (nullable) nullable

    When it was created.

    format: `date-time`

  • error_message string (nullable) nullable

    Why a failed email did not go out.

  • mailbox_id string (nullable) nullable

    The Gmail mailbox it goes out from.

  • object string

    default: `email`

  • opened_at string (nullable) nullable

    When it was first opened.

    format: `date-time`

  • parent_email_id string (nullable) nullable

    The thread's first email, for a follow-up or reply.

  • recipient_name string (nullable) nullable

    The recipient's name.

  • replied_at string (nullable) nullable

    When it got a reply.

    format: `date-time`

  • scheduled_for string (nullable) nullable

    When a queued email goes out.

    format: `date-time`

  • sent_at string (nullable) nullable

    When it went out.

    format: `date-time`

  • template_type enum (nullable) nullable

    What the email asks for.

  • updated_at string (nullable) nullable

    Last change.

    format: `date-time`

Example response
{
  "backlink_verified": false,
  "body": "<p>Hi Alex, the Allbirds Tree Runner fits your list.</p>",
  "body_text": "Hi Alex, the Allbirds Tree Runner fits your list.",
  "brand_id": "3f9c7e8a-1b6a-4d8e-92cf-7d9c8b1e2a04",
  "citation_id": "3c1f5a7e-8b2d-4e6f-9a0b-1c2d3e4f5a6b",
  "citation_url": "https://www.runnersworld.com/gear/a20865766/best-running-shoes/",
  "contact_id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
  "created_at": "2026-10-01T10:00:00+00:00",
  "follow_up_number": 0,
  "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "mailbox_id": "5e6f7081-92a3-4b4c-8d5e-6f708192a3b4",
  "object": "email",
  "recipient_email": "alex.rivera@e2e.test",
  "recipient_name": "Alex Rivera",
  "status": "draft",
  "subject": "A shoe for your best running shoes list",
  "template_type": "request_inclusion",
  "tone": "friendly",
  "updated_at": "2026-10-01T10:00:00+00:00"
}
Request validation failed application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Missing or invalid credentials application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid credentials"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Not enough credits to complete this operation application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits to complete this operation"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
You do not have permission to access this resource application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "forbidden",
    "message": "You do not have permission to access this resource"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Resource not found application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "not_found",
    "message": "Resource not found"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Resource conflict application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "conflict",
    "message": "Resource conflict"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Request body did not match the expected schema application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "body_validation_error",
    "message": "Request body did not match the expected schema"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Per-minute rate limit exceeded application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Per-minute rate limit exceeded"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
An unexpected error occurred application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Service temporarily unavailable, please retry application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "service_unavailable",
    "message": "Service temporarily unavailable, please retry"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}