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

# Get a file



## OpenAPI

````yaml api-reference/openapi.json GET /v1/files/{id}
openapi: 3.1.0
info:
  title: Spiral API
  version: '1'
  description: >-
    1. Retry automatically only on network errors and timeouts (same
    `Idempotency-Key`) and on the codes below. `retryable` and `x-should-retry`
    on the answer always win over this table (for example `RATE_LIMITED` is not
    retryable once the `day` policy is exhausted). Every other code needs a
    change before the request is sent again.


    | Code | HTTP | Retry | Wait |

    |---|---|---|---|

    | INSUFFICIENT_BALANCE | 402 | only when the problem says `retryable: true`,
    with the same `Idempotency-Key` | `Retry-After` (30 s by default) |

    | IDEMPOTENCY_IN_PROGRESS | 409 | yes, with the same `Idempotency-Key` |
    `Retry-After` (1 s by default) |

    | RATE_LIMITED | 429 | yes | `Retry-After` |

    | CONCURRENCY_LIMITED | 429 | yes | `Retry-After` (2 s by default) |

    | QUEUE_FULL | 429 | yes | `Retry-After` (2 s by default) |

    | INTERNAL_ERROR | 500 | yes, with the same `Idempotency-Key` | backoff
    (rule 2) |

    | BILLING_UNAVAILABLE | 503 | yes, with the same `Idempotency-Key` |
    `Retry-After` (5 s by default) |

    | SCHEMA_UNAVAILABLE | 503 | yes | `Retry-After` (10 s by default) |

    | PROVIDER_PAUSED | 503 | yes | `Retry-After` (60 s by default) |

    | MODEL_PAUSED | 503 | yes | `Retry-After` (60 s by default) |

    | SERVICE_UNAVAILABLE | 503 | yes, with the same `Idempotency-Key` |
    `Retry-After` (5 s by default) |


    2. Backoff: capped exponential with full jitter, `sleep = random(0, min(30
    s, 1 s × 2^attempt))`, at most 4 retries and about 2 minutes in total for a
    create.

    3. Retry-After is a floor: wait at least that long (add 0–20 % jitter).
    Magica never sends more than 60 s.

    4. Keys: send a UUIDv4 `Idempotency-Key` on every `POST /v1/runs` and store
    it with your task before sending. Reuse it for every retry of the same
    intent, including after a restart; a replay returns the original run with
    `Idempotent-Replayed: true`, never a second run or charge. Use a new key
    only to start a new run deliberately. A key is remembered for 3 days, then
    may start a new run.

    5. Unknown outcome of a create (timeout, connection reset): retry with the
    same key. Never switch to a new key until the first request is known not to
    have created a run.

    6. Failed runs: start at most one new run (new key), and only when
    `error.retryable` is true. `PROVIDER_OUTCOME_UNKNOWN` is not retryable:
    check your own results first, because the provider may have done the work.

    7. Polling: prefer webhooks. Otherwise use `GET
    /v1/runs/{id}?wait_seconds=30`, or poll by `Retry-After` on 202 and running
    responses; without it start at 1 s (search and scrape), 2 s (images), 5 s
    (video and audio), back off × 1.5 up to 30 s, and stop at a final status.
    Polling has its own rate-limit policy (`poll`), so it never consumes create
    quota.

    8. Webhooks: verify the signature over the raw body with your org's signing
    secret (any Standard Webhooks library; during a secret rotation the header
    carries two signatures and either verifies); answer 2xx fast and do the work
    afterwards (a delivery that takes over 10 s is re-sent); ignore event types
    you do not handle (types are added over time); dedupe on `webhook-id` for at
    least 7 days (every re-send carries the same one); on `truncated: true` read
    the run with `GET /v1/runs/{id}` (the body left out `output` to stay under
    receiver limits); ignore a delivery whose run `sequence` is lower than one
    already applied; download outputs within 24 hours. A webhook is sent right
    after the run is charged, so it usually carries the final charge (`sequence`
    4); when the provider's bill comes later it carries `cost.state: held`
    (`sequence` 3) and the final charge is on `GET /v1/runs/{id}` (`sequence`
    4). No separate billing event is sent.

    9. Runs cannot be canceled after submission. Poll the run or wait for its
    configured terminal webhook.
servers:
  - url: https://api.spiral.ai
security: []
paths:
  /v1/files/{id}:
    get:
      tags:
        - Files
      summary: Metadata of an uploaded file.
      operationId: get-file
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: The file.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  object:
                    type: string
                    const: file
                  filename:
                    type:
                      - string
                      - 'null'
                  mime_type:
                    type:
                      - string
                      - 'null'
                  size_bytes:
                    type: integer
                    minimum: -9007199254740991
                    maximum: 9007199254740991
                  created_at:
                    type: string
                    description: RFC 3339 timestamp
                  expires_at:
                    type: string
                    description: RFC 3339 timestamp
                required:
                  - id
                  - object
                  - filename
                  - mime_type
                  - size_bytes
                  - created_at
                  - expires_at
        '401':
          description: 'Problem: UNAUTHENTICATED, API_KEY_REVOKED, API_KEY_EXPIRED.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            x-should-retry:
              $ref: '#/components/headers/x-should-retry'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '403':
          description: 'Problem: ORG_SUSPENDED, PERMISSION_DENIED.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            x-should-retry:
              $ref: '#/components/headers/x-should-retry'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '404':
          description: 'Problem: FILE_NOT_FOUND.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            x-should-retry:
              $ref: '#/components/headers/x-should-retry'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '405':
          description: 'Problem: METHOD_NOT_ALLOWED.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            x-should-retry:
              $ref: '#/components/headers/x-should-retry'
            Allow:
              $ref: '#/components/headers/Allow'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '429':
          description: 'Problem: RATE_LIMITED.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            x-should-retry:
              $ref: '#/components/headers/x-should-retry'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '500':
          description: 'Problem: INTERNAL_ERROR.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            x-should-retry:
              $ref: '#/components/headers/x-should-retry'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '503':
          description: 'Problem: SERVICE_UNAVAILABLE.'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            x-should-retry:
              $ref: '#/components/headers/x-should-retry'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - bearer: []
components:
  headers:
    X-Request-Id:
      description: >-
        `req_<ULID>`; equals `request_id` in problems and the log context. Every
        response.
      schema:
        type: string
    RateLimit-Policy:
      description: >-
        IETF draft-11, e.g. `"minute";q=600;w=60, "day";q=200000;w=86400`.
        Authenticated responses.
      schema:
        type: string
    RateLimit:
      description: >-
        IETF draft-11, e.g. `"minute";r=12;t=41`. Authenticated responses;
        `Retry-After` wins.
      schema:
        type: string
    Cache-Control:
      description: '`no-store` on run, balance and file responses.'
      schema:
        type: string
    x-should-retry:
      description: '`true` or `false`, mirrors `retryable`. Every error response.'
      schema:
        type: string
    Allow:
      description: The allowed methods. Every 405.
      schema:
        type: string
    Retry-After:
      description: >-
        Delay-seconds, never more than 60: every 429 and 503, 409
        `IDEMPOTENCY_IN_PROGRESS`, 402 `INSUFFICIENT_BALANCE` while an auto
        top-up is expected, and the poll hint on a 202 or a running run.
      schema:
        type: string
  schemas:
    Problem:
      type: object
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        detail:
          type: string
        code:
          type: string
        retryable:
          type: boolean
        request_id:
          type: string
        errors:
          type: array
          items:
            type: object
            properties:
              pointer:
                type: string
              message:
                type: string
              reason:
                type: string
                enum:
                  - unknown_field
                  - missing_required
                  - wrong_type
                  - not_in_enum
                  - below_minimum
                  - above_maximum
                  - not_multiple_of
                  - too_short
                  - too_long
                  - too_few_items
                  - too_many_items
                  - pattern_mismatch
                  - invalid_format
                  - no_matching_variant
                  - invalid_combination
                  - control_field
                  - invalid_value
                  - file_too_large
                  - unsupported_media_type
                  - duration_too_long
                  - duration_too_short
                  - resolution_too_low
                  - resolution_too_high
                  - unreachable
                  - file_not_found
                  - content_policy
                  - provider_refused
              expected:
                anyOf:
                  - type: string
                  - type: number
                  - type: boolean
                  - type: 'null'
                  - type: object
                    propertyNames:
                      type: string
                    additionalProperties:
                      type:
                        - string
                        - number
                        - boolean
                        - 'null'
              received:
                anyOf:
                  - type: string
                  - type: number
                  - type: boolean
                  - type: 'null'
                  - type: object
                    propertyNames:
                      type: string
                    additionalProperties:
                      type:
                        - string
                        - number
                        - boolean
                        - 'null'
              allowed:
                type: array
                items:
                  type:
                    - string
                    - number
                    - boolean
                    - 'null'
            required:
              - pointer
              - message
            additionalProperties: false
        retry_after_seconds:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
      required:
        - type
        - title
        - status
        - detail
        - code
        - retryable
        - request_id
      additionalProperties: {}
  securitySchemes:
    bearer:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.