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

# Get presigned upload URL

> Get a presigned URL for uploading a file. This is the first step in a two-step upload flow.

**Upload Flow:**
1. Call this endpoint to get a presigned URL and metadata
2. PUT the file to the returned URL with the required headers

<Warning>
  The presigned URL is signed with specific metadata headers. You **must** include these headers when uploading or the request will fail with `SignatureDoesNotMatch`.
</Warning>

**Required headers for the PUT request:**
- `Content-Type`: Use `metadata.contentType` from the response
- `x-amz-meta-file-type`: Use `metadata.contentType` from the response
- `x-amz-meta-org-id`: Use `metadata.orgId` from the response
- `x-amz-meta-user-id`: Use `metadata.userId` from the response

Presigned URLs expire after 10 minutes.




## OpenAPI

````yaml /openapi.yaml post /upload/presigned
openapi: 3.1.0
info:
  title: AsterAgents API
  version: 1.0.0
  description: >
    API for AsterAgents platform operations.


    - **Admin endpoints** (`/admin/*`) require organization admin privileges
    (`org:admin` role)

    - **Agent endpoints** (`/agents`) require agent management permissions or
    `org:admin` role

    - **Knowledge base endpoints** (`/kb/*`) require standard authentication

    - **Skills endpoints** (`/skills/*`) require standard authentication

    - **File endpoints** (`/upload/*`, `/kb/files`, `/skills/files`) require
    standard authentication
  contact:
    name: AsterAgents Support
    url: https://asteragents.com/support
servers:
  - url: https://asteragents.com/api
    description: Production
  - url: http://localhost:3000/api
    description: Local development
security:
  - bearerAuth: []
tags:
  - name: Users
    description: Manage active organization users
  - name: Invitations
    description: Manage organization invitations
  - name: Files
    description: Upload and manage files
  - name: Knowledge Bases
    description: Manage knowledge bases and their files
  - name: Knowledge Base Management
    description: Create, update, and delete knowledge bases
  - name: Agents
    description: Create, update, and delete agents
  - name: Agent Tags
    description: Organize agents with tags
  - name: Tools
    description: Discover the tool catalog available to your organization
  - name: Skills
    description: Manage agent skills
  - name: Skill Files
    description: Manage bundled files for skills
  - name: Conversations
    description: Invoke agents and retrieve conversation history and messages
  - name: Scheduled Tasks
    description: Schedule agents to run automatically on a cron schedule
paths:
  /upload/presigned:
    post:
      tags:
        - Files
      summary: Get presigned upload URL
      description: >
        Get a presigned URL for uploading a file. This is the first step in a
        two-step upload flow.


        **Upload Flow:**

        1. Call this endpoint to get a presigned URL and metadata

        2. PUT the file to the returned URL with the required headers


        <Warning>
          The presigned URL is signed with specific metadata headers. You **must** include these headers when uploading or the request will fail with `SignatureDoesNotMatch`.
        </Warning>


        **Required headers for the PUT request:**

        - `Content-Type`: Use `metadata.contentType` from the response

        - `x-amz-meta-file-type`: Use `metadata.contentType` from the response

        - `x-amz-meta-org-id`: Use `metadata.orgId` from the response

        - `x-amz-meta-user-id`: Use `metadata.userId` from the response


        Presigned URLs expire after 10 minutes.
      operationId: getPresignedUploadUrl
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - filename
                - contentType
              properties:
                filename:
                  type: string
                  description: The name of the file being uploaded
                  example: report.pdf
                contentType:
                  type: string
                  description: The MIME type of the file
                  example: application/pdf
            examples:
              pdf:
                summary: PDF document
                value:
                  filename: quarterly-report.pdf
                  contentType: application/pdf
              image:
                summary: Image file
                value:
                  filename: screenshot.png
                  contentType: image/png
      responses:
        '200':
          description: Presigned URL generated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PresignedUploadResponse'
              examples:
                success:
                  value:
                    url: >-
                      https://account-id.r2.cloudflarestorage.com/bucket/org_xxx/uploads/file-uuid/report.pdf?X-Amz-Algorithm=...
                    method: PUT
                    fileId: 550e8400-e29b-41d4-a716-446655440000
                    key: >-
                      org_xxx/uploads/550e8400-e29b-41d4-a716-446655440000/report.pdf
                    contentKey: org_xxx/contents/550e8400-e29b-41d4-a716-446655440000.md
                    metadata:
                      contentType: application/pdf
                      orgId: org_xxx
                      userId: user_xxx
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          description: Unauthorized - Invalid or missing authentication
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Unauthorized
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    PresignedUploadResponse:
      type: object
      required:
        - url
        - method
        - fileId
        - key
        - contentKey
        - metadata
      properties:
        url:
          type: string
          format: uri
          description: The presigned URL to upload the file to
          example: https://account-id.r2.cloudflarestorage.com/bucket/...
        method:
          type: string
          description: The HTTP method to use (always PUT)
          enum:
            - PUT
          example: PUT
        fileId:
          type: string
          format: uuid
          description: Unique identifier for the uploaded file
          example: 550e8400-e29b-41d4-a716-446655440000
        key:
          type: string
          description: The storage key/path where the file will be stored
          example: org_xxx/uploads/550e8400-e29b-41d4-a716-446655440000/report.pdf
        contentKey:
          type: string
          description: The storage key for extracted text content (for documents)
          example: org_xxx/contents/550e8400-e29b-41d4-a716-446655440000.md
        metadata:
          type: object
          description: >-
            Values that MUST be included as headers when uploading to the
            presigned URL
          required:
            - contentType
            - orgId
            - userId
          properties:
            contentType:
              type: string
              description: Use as Content-Type and x-amz-meta-file-type headers
              example: application/pdf
            orgId:
              type: string
              description: Use as x-amz-meta-org-id header
              example: org_xxx
            userId:
              type: string
              description: Use as x-amz-meta-user-id header
              example: user_xxx
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          example: Bad Request
        details:
          type: array
          items:
            type: object
            additionalProperties: true
  responses:
    BadRequest:
      description: Bad Request - Invalid parameters or user not part of organization
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: User is not part of any organization
    InternalServerError:
      description: Internal Server Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Internal Server Error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        JWT token from Clerk authentication.

        Must be from a user with `org:admin` role.

````