> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getaptly.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send an email

> Sends an outbound email scoped to your company. Two usage patterns:

**From an existing draft** — provide `discussionId` and `uuid` returned by
`POST /api/email/create-draft`. The draft's stored recipients, subject, and body are
used.

**On-the-fly** — omit `uuid` and provide `userId`, `channelId`, recipients, subject,
and body. A draft is created automatically before sending. Supplying `discussionId`
(without `uuid`) sends the message as a reply into that existing thread — the
thread's subject is kept; omitting both `discussionId` and `uuid` starts a new thread.

### Adding attachments

Attachments apply to the **on-the-fly** pattern (for an existing draft, attach files
when you call `POST /api/email/create-draft`). Upload each file with the three-step
direct upload flow first — you cannot post file bytes to this endpoint:

1. **Get an upload URL** — `POST /api/files/upload-url` with `attachEntityType: "channel"`,
   `attachEntityId` set to the same `channelId` you're sending from, and the file's
   `name`, `extension`, `size`, and `contentType`. Returns `{ fileId, url, fields }`.
2. **Upload to S3** — `multipart/form-data` `POST` to `url`, all `fields` first then the
   file bytes last as a `file` field. S3 returns `204`.
3. **Mark complete** — `POST /api/files/upload-complete` with the `fileId`.

Then, on this request:
- **Regular attachment** — add the `fileId`(s) to `attachmentIds`.
- **Inline image** — embed an `<img>` in the HTML `body` whose `src` is the file's
  download URL (`.../cdn/storage/AptlyFiles/<fileId>/original/...`). Auto-detected and
  registered; do **not** also list it in `attachmentIds`.

Each `fileId` must reference a finished upload.




## OpenAPI

````yaml /openapi.yaml post /api/email/send
openapi: 3.0.3
info:
  title: Aptly API
  version: '1.0'
  description: >
    The Aptly API lets you read and write cards on any Aptly board from external
    systems.


    All requests require an API key passed as the `x-token` header.

    API keys are scoped to your company and work across all boards.
servers:
  - url: https://core-api.getaptly.com
    description: Production
security:
  - ApiKeyHeader: []
paths:
  /api/email/send:
    post:
      tags:
        - Email
      summary: Send an email
      description: >
        Sends an outbound email scoped to your company. Two usage patterns:


        **From an existing draft** — provide `discussionId` and `uuid` returned
        by

        `POST /api/email/create-draft`. The draft's stored recipients, subject,
        and body are

        used.


        **On-the-fly** — omit `uuid` and provide `userId`, `channelId`,
        recipients, subject,

        and body. A draft is created automatically before sending. Supplying
        `discussionId`

        (without `uuid`) sends the message as a reply into that existing thread
        — the

        thread's subject is kept; omitting both `discussionId` and `uuid` starts
        a new thread.


        ### Adding attachments


        Attachments apply to the **on-the-fly** pattern (for an existing draft,
        attach files

        when you call `POST /api/email/create-draft`). Upload each file with the
        three-step

        direct upload flow first — you cannot post file bytes to this endpoint:


        1. **Get an upload URL** — `POST /api/files/upload-url` with
        `attachEntityType: "channel"`,
           `attachEntityId` set to the same `channelId` you're sending from, and the file's
           `name`, `extension`, `size`, and `contentType`. Returns `{ fileId, url, fields }`.
        2. **Upload to S3** — `multipart/form-data` `POST` to `url`, all
        `fields` first then the
           file bytes last as a `file` field. S3 returns `204`.
        3. **Mark complete** — `POST /api/files/upload-complete` with the
        `fileId`.


        Then, on this request:

        - **Regular attachment** — add the `fileId`(s) to `attachmentIds`.

        - **Inline image** — embed an `<img>` in the HTML `body` whose `src` is
        the file's
          download URL (`.../cdn/storage/AptlyFiles/<fileId>/original/...`). Auto-detected and
          registered; do **not** also list it in `attachmentIds`.

        Each `fileId` must reference a finished upload.
      operationId: sendEmail
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                discussionId:
                  type: string
                  description: >
                    Stream ID from `POST /api/email/create-draft` (required if
                    `uuid` is set).

                    When supplied without `uuid`, the on-the-fly draft is
                    appended as a reply

                    into this existing thread (same company + channel) instead
                    of starting a

                    new discussion; the thread's subject is kept.
                uuid:
                  type: string
                  description: >-
                    Draft UUID from `POST /api/email/create-draft`. Required if
                    `discussionId` is set.
                failOnCreateNewThread:
                  type: boolean
                  default: true
                  description: >
                    If `true` (default), the send fails when the email would
                    create a new

                    discussion thread rather than reply to an existing one.
                userId:
                  type: string
                  description: Required when sending on-the-fly (no `discussionId`/`uuid`).
                channelId:
                  type: string
                  description: Required when sending on-the-fly.
                to:
                  type: array
                  items:
                    $ref: '#/components/schemas/EmailRecipient'
                cc:
                  type: array
                  items:
                    $ref: '#/components/schemas/EmailRecipient'
                bcc:
                  type: array
                  items:
                    $ref: '#/components/schemas/EmailRecipient'
                subject:
                  type: string
                body:
                  type: string
                  description: >
                    Email body (plain text or HTML). To embed an uploaded image
                    inline, add

                    an `<img>` whose `src` is the file's download URL from

                    `POST /api/files/upload-complete`

                    (`.../cdn/storage/AptlyFiles/<fileId>/original/...`). Inline
                    images are

                    auto-detected, tagged with `data-inline-image-id`, and
                    registered on the

                    draft — do not also list them in `attachmentIds`. Applies
                    when the draft

                    is created on-the-fly (no `discussionId`/`uuid`).
                attachmentIds:
                  type: array
                  items:
                    type: string
                  description: >
                    File ids to include as regular attachments (applies when the
                    draft is

                    created on-the-fly). Upload each file first (`POST
                    /api/files/upload-url`

                    with attachEntityType `channel` and the same channelId →
                    upload to S3 →

                    `POST /api/files/upload-complete`), then pass the resulting
                    `fileId`s here.

                    Each must reference a finished upload.
                aptletInstanceId:
                  type: string
                  description: >
                    Card to link the outbound to. Logs the email as an activity
                    on the

                    card and tags the discussion. Works whether the draft was
                    pre-created

                    or is created on-the-fly.
            examples:
              from_draft:
                summary: Send from an existing draft
                value:
                  discussionId: stream_abc
                  uuid: draft_xyz
              on_the_fly:
                summary: On-the-fly send
                value:
                  userId: user_abc
                  channelId: channel_abc
                  to:
                    - value: tenant@example.com
                  subject: Your lease renewal
                  body: Please review the attached renewal terms.
                  aptletInstanceId: card_abc
      responses:
        '200':
          description: Email sent successfully.
          content:
            application/json:
              schema:
                type: object
        '401':
          description: Invalid or missing API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - ApiKeyHeader: []
        - DelegateToken: []
        - PartnerBearer: []
components:
  schemas:
    EmailRecipient:
      type: object
      required:
        - value
      properties:
        value:
          type: string
          description: Email address.
        label:
          type: string
          description: Optional display name for the recipient.
    Error:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-token
    DelegateToken:
      type: apiKey
      in: header
      name: Authorization
      description: 'Delegate token issued by the platform. Format: `DelegateToken <token>`'
    PartnerBearer:
      type: http
      scheme: bearer
      description: 'Partner token. Format: `Authorization: Bearer <token>`'

````