> ## 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.

# Create an email draft

> Creates a new outbound email discussion (stream) with a single draft entry, scoped to
your company. Returns the `streamId` and `draftUuid` needed to send via
`POST /api/email/send`.

Recipient fields (`to`, `cc`, `bcc`) accept an array of `{ value, label? }` objects
where `value` is the email address.

### Adding attachments

Attachments must be uploaded to storage **before** you reference them here — you
cannot post file bytes to this endpoint. Upload each file with the three-step direct
upload flow, then attach it:

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

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/...`, returned by step 3).
  It is auto-detected and registered; do **not** also list it in `attachmentIds`.

Repeat steps 1–3 per file. Each `fileId` must reference a finished upload or the
request is rejected.




## OpenAPI

````yaml /openapi.yaml post /api/email/create-draft
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/create-draft:
    post:
      tags:
        - Email
      summary: Create an email draft
      description: >
        Creates a new outbound email discussion (stream) with a single draft
        entry, scoped to

        your company. Returns the `streamId` and `draftUuid` needed to send via

        `POST /api/email/send`.


        Recipient fields (`to`, `cc`, `bcc`) accept an array of `{ value, label?
        }` objects

        where `value` is the email address.


        ### Adding attachments


        Attachments must be uploaded to storage **before** you reference them
        here — you

        cannot post file bytes to this endpoint. Upload each file with the
        three-step direct

        upload flow, then attach it:


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


        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/...`, returned by step 3).
          It is auto-detected and registered; do **not** also list it in `attachmentIds`.

        Repeat steps 1–3 per file. Each `fileId` must reference a finished
        upload or the

        request is rejected.
      operationId: createEmailDraft
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - userId
                - channelId
              properties:
                userId:
                  type: string
                  description: User to record as the draft creator/sender.
                channelId:
                  type: string
                  description: '`channel.meta.id` of the outbound email channel.'
                discussionId:
                  type: string
                  description: >
                    When set, append the draft as a reply to this existing
                    thread (stream

                    ID) instead of starting a new discussion. The thread must
                    belong to the

                    same company and channel. The thread's subject is kept and
                    the draft is

                    threaded onto the thread's last message.
                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`.
                attachmentIds:
                  type: array
                  items:
                    type: string
                  description: >
                    File ids to include as regular attachments. 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. When set, sending the draft
                    logs the

                    email as an activity on the card and tags the discussion
                    with it.
            example:
              userId: user_abc
              channelId: channel_abc
              to:
                - value: tenant@example.com
                  label: Jane Tenant
              subject: Your lease renewal
              body: Please review the attached renewal terms.
              aptletInstanceId: card_abc
      responses:
        '200':
          description: Draft stream created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  streamId:
                    type: string
                    description: Discussion/stream ID to pass to `POST /api/email/send`.
                  draftUuid:
                    type: string
                    description: Draft UUID to pass to `POST /api/email/send`.
        '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>`'

````