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

# Upload attachment

> Uploads a file and attaches it to the specified task.

Requires the `task:create` scope.



## OpenAPI

````yaml /api-reference/api.json post /{projectSlug}/tasks/{taskId}/attachments
openapi: 3.1.0
info:
  title: Elean Public API
  description: >-
    The Elean Public API allows external clients — scripts, AI agents, and
    integrations — to read and write tasks programmatically.


    > **Early Access:** This API is currently in beta. Endpoints,
    request/response shapes, and scopes may change before the stable release. We
    will communicate breaking changes in advance.
  version: 0.0.1
  contact:
    name: Elean Support
    url: https://elean.app
servers:
  - url: https://api.elean.app/v1/public
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Statuses
    description: List the custom task statuses configured for a project.
  - name: Labels
    description: List labels available in a project.
  - name: Members
    description: List members of a project.
  - name: Tasks
    description: Read and write tasks within a project.
  - name: Comments
    description: Read and write comments on tasks.
paths:
  /{projectSlug}/tasks/{taskId}/attachments:
    post:
      tags:
        - Tasks
      summary: Upload attachment
      description: |-
        Uploads a file and attaches it to the specified task.

        Requires the `task:create` scope.
      operationId: uploadAttachment
      parameters:
        - name: projectSlug
          in: path
          required: true
          description: The slug of the project.
          schema:
            type: string
            example: my-project
        - name: taskId
          in: path
          required: true
          description: UUID of the task, or its external ID (e.g. `PROJ-42`).
          schema:
            type: string
            example: 018e1b2c-3d4e-5f6a-7b8c-9d0e1f2a3b4c
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: The file to upload. Maximum size is 10 MB.
      responses:
        '201':
          description: Attachment uploaded successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AttachmentSummary'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
components:
  schemas:
    AttachmentSummary:
      type: object
      description: A file attached to a task.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the attachment.
          example: 018e1b2c-aaaa-bbbb-cccc-000000000001
        filename:
          type: string
          description: Original filename of the uploaded file.
          example: screenshot.png
        url:
          type: string
          format: uri
          description: >-
            Presigned URL to download the attachment. Valid for 1 hour from the
            time of the request.
          example: >-
            https://elean-attachments.example.r2.cloudflarestorage.com/workspace-id/task-id/file-id.png?X-Amz-Expires=3600&...
        mimeType:
          type: string
          description: MIME type of the file.
          example: image/png
        size:
          type: integer
          description: File size in bytes.
          example: 204800
        createdAt:
          type: string
          format: date-time
          description: ISO 8601 timestamp of when the attachment was uploaded.
          example: '2026-03-01T12:00:00.000Z'
    ApiError:
      type: object
      properties:
        statusCode:
          type: integer
          example: 401
        message:
          type: string
          example: Invalid API key
  responses:
    BadRequest:
      description: The request body is missing required fields or contains invalid values.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            statusCode: 400
            message: title must be longer than or equal to 1 characters
    Unauthorized:
      description: The API key is missing, invalid, or expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            statusCode: 401
            message: Invalid API key
    Forbidden:
      description: >-
        The API key does not have the required scope, or the project is outside
        the key's allowed scope.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            statusCode: 403
            message: 'Missing required scope: task:create'
    NotFound:
      description: The project or task was not found within the key's workspace.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            statusCode: 404
            message: Task not found
    TooManyRequests:
      description: >-
        The rate limit for this API key has been exceeded. Retry after the
        indicated delay.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            statusCode: 429
            message: Too many requests
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: el_<token>
      description: >-
        API key created in **Workspace Settings → API Keys**. Pass it in the
        `Authorization` header as a Bearer token, or in the `X-API-Key` header.


        Format: `el_` followed by 40 hex characters.

````