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

# Download a file

> Files an automation produced: PDFs, photographs, spreadsheets.

`~file` is not a folder. It is a marker the platform reads and removes before passing the rest of the path to your workspace, so `/~file/api/reports/x.pdf` and `/api/reports/x.pdf` reach the same handler. The difference is who carries the bytes.

With `~file`, the platform wakes the workspace if it is asleep and then **redirects** you to it, so the download goes straight from the workspace to you. Without it, the file is relayed through the platform and is capped at 4MB.

Follow the redirect. Every HTTP client does by default.

The only endpoint that needs no API key. A file link is made to be clicked, and a browser following a link cannot be asked to set a header — so the unguessable URL is the whole credential here. Treat a file link like the file itself.



## OpenAPI

````yaml /openapi.json get /~file/{filePath}
openapi: 3.1.0
info:
  title: Workspace API
  version: 1.0.0
  description: >-
    Every workspace answers these endpoints. Nothing is registered and nothing
    is switched on: an automation that appears in your Automations tab is
    already readable here.


    The base URL is your workspace's own. Ask the agent for it, or find it under
    Settings → API on the workspace. It is stable and never changes.


    Every call carries your workspace's API key, as `Authorization: Bearer
    <key>` or in the `x-desert-api-key` header. The key is on the same settings
    page as the URL, and generating a new one there revokes the old one
    immediately.
servers:
  - url: https://www.rundesert.com/p/{workspaceId}
    description: Your workspace's public API
    variables:
      workspaceId:
        default: px_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        description: >-
          The id in your workspace's public URL. It is the address, not the
          credential — the API key is what authorises the call.
security:
  - bearerAuth: []
  - apiKeyHeader: []
tags:
  - name: Automations
    description: What this workspace can do.
  - name: Runs
    description: What it has done, and what came out.
  - name: Files
    description: Downloading what an automation produced.
  - name: Custom endpoints
    description: Anything else your agent wrote.
paths:
  /~file/{filePath}:
    get:
      tags:
        - Files
      summary: Download a file
      description: >-
        Files an automation produced: PDFs, photographs, spreadsheets.


        `~file` is not a folder. It is a marker the platform reads and removes
        before passing the rest of the path to your workspace, so
        `/~file/api/reports/x.pdf` and `/api/reports/x.pdf` reach the same
        handler. The difference is who carries the bytes.


        With `~file`, the platform wakes the workspace if it is asleep and then
        **redirects** you to it, so the download goes straight from the
        workspace to you. Without it, the file is relayed through the platform
        and is capped at 4MB.


        Follow the redirect. Every HTTP client does by default.


        The only endpoint that needs no API key. A file link is made to be
        clicked, and a browser following a link cannot be asked to set a header
        — so the unguessable URL is the whole credential here. Treat a file link
        like the file itself.
      operationId: downloadFile
      parameters:
        - name: filePath
          in: path
          required: true
          description: >-
            The path your workspace serves the file at, slashes and all, for
            example `api/reports/report-2026-08-20.pdf`.
          schema:
            type: string
          example: api/reports/report-2026-08-20.pdf
      responses:
        '302':
          description: Follow the `Location` header to the workspace, which is now awake.
          headers:
            Location:
              description: Where the file actually is.
              schema:
                type: string
                format: uri
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          description: The workspace could not be started.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security: []
components:
  responses:
    RateLimited:
      description: >-
        600 requests a minute across the whole workspace, shared with anyone
        loading its pages. Wait and try again.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: rate limited
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
        detail:
          type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your workspace's API key, from Settings → API. Sent as `Authorization:
        Bearer dk_...`.
    apiKeyHeader:
      type: apiKey
      in: header
      name: x-desert-api-key
      description: >-
        The same key, for callers whose `Authorization` header is already spoken
        for by their own auth. Send one form or the other, not both.

````