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

# File management

> Upload, list, download, and delete files via the REST API. Works with any storage provider configured in App Services.

The REST API exposes a small set of endpoints for moving files in and out of your project. They work against whichever storage backend you've configured in [App Services → File Manager](/features/backend/app-services/file-manager) — Google Cloud Storage, Amazon S3, Azure Blob Storage, Filestack, or the built-in Archie Storage.

| Method   | Endpoint                   | Purpose             |
| -------- | -------------------------- | ------------------- |
| `POST`   | `/api/rest/files`          | Upload a file       |
| `GET`    | `/api/rest/files`          | List uploaded files |
| `GET`    | `/api/rest/files/{fileId}` | Download a file     |
| `DELETE` | `/api/rest/files/{fileId}` | Delete a file       |

## Upload a file

Send a `multipart/form-data` request. Don't set `Content-Type` manually — let curl (or your HTTP client) generate the boundary header.

```bash theme={null}
curl -X POST "https://your-gateway.example.com/gw/api/rest/files" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id" \
  -F "file=@/path/to/document.pdf" \
  -F "providerType=ARCHIE_STORAGE" \
  -F "filename=document.pdf" \
  -F "contentType=application/pdf"
```

| Form field     | Required | Description                                 |
| -------------- | -------- | ------------------------------------------- |
| `file`         | Yes      | The file binary.                            |
| `providerType` | Yes      | The storage provider to use.                |
| `filename`     | Yes      | Display name for the file.                  |
| `contentType`  | Yes      | MIME type — validated against an allowlist. |

### Provider types

| Value            | Backend                 |
| ---------------- | ----------------------- |
| `ARCHIE_STORAGE` | Built-in Archie storage |
| `GCS`            | Google Cloud Storage    |
| `S3`             | Amazon S3               |
| `AZURE`          | Azure Blob Storage      |
| `FILESTACK`      | Filestack               |

The provider must be configured in [App Services → File Manager](/features/backend/app-services/file-manager) before files can be uploaded to it.

### Response — 201

```json theme={null}
{
  "data": {
    "fileId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "url": "https://your-gateway.example.com/files?id=encrypted-token"
  }
}
```

The `url` is a signed, time-bounded URL. Persist the `fileId` if you need a stable reference; regenerate fresh URLs at read time when needed.

### Supported MIME types

The API accepts a broad allowlist by prefix:

| Category  | Examples                                                         |
| --------- | ---------------------------------------------------------------- |
| Images    | All `image/*` (jpeg, png, gif, webp, svg+xml, bmp, tiff, avif)   |
| Video     | All `video/*` (mp4, webm, quicktime)                             |
| Audio     | All `audio/*` (mpeg, wav, ogg)                                   |
| Text      | All `text/*` (plain, csv, html, xml)                             |
| Documents | `application/pdf`, `application/rtf`, MS Office, OpenXML formats |
| Archives  | `application/zip`, `application/gzip`, `application/x-tar`       |
| Data      | `application/json`, `application/xml`                            |
| Generic   | `application/octet-stream`                                       |

Unsupported types return `422 Unprocessable Entity`.

## List files

```bash theme={null}
curl -X GET "https://your-gateway.example.com/gw/api/rest/files?page=1&pageSize=20" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id"
```

| Parameter  | Default | Max |
| ---------- | ------- | --- |
| `page`     | 1       | —   |
| `pageSize` | 20      | 100 |

```json theme={null}
{
  "data": {
    "items": [
      {
        "fileId": "a1b2c3d4-...",
        "filename": "document.pdf",
        "mimetype": "application/pdf",
        "url": "https://your-gateway.example.com/files?id=encrypted-token"
      }
    ],
    "pagination": { "page": 1, "pageSize": 20, "total": 42 }
  }
}
```

## Download a file

```bash theme={null}
curl -X GET "https://your-gateway.example.com/gw/api/rest/files/a1b2c3d4-..." \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id" \
  -o downloaded-document.pdf
```

The response body is the raw file binary. Headers include the original `Content-Type`, a `Content-Disposition` with the filename, and a 1-year `Cache-Control` header.

## Delete a file

```bash theme={null}
curl -X DELETE "https://your-gateway.example.com/gw/api/rest/files/a1b2c3d4-..." \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id"
```

Returns `204 No Content` on success. The file is removed from the storage provider.

## Errors

| Status | Scenario                              |
| ------ | ------------------------------------- |
| 400    | Missing required form fields.         |
| 404    | File not found.                       |
| 413    | File exceeds the maximum upload size. |
| 422    | Unsupported MIME type.                |

For the full error format, see [Error handling](/features/backend/rest-api-explorer/error-handling).

## Permissions

File-management endpoints obey the same [Role-Based Access](/features/backend/app-services/role-based-access) rules as other endpoints. Configure who can upload, download, and delete in App Services. For finer-grained access (per-record file permissions), reference the file from a Data Model record and govern access via that table's permissions.

## FAQ

<AccordionGroup>
  <Accordion title="How do I store a file alongside a record?">
    Upload the file to get a `fileId`, then store the `fileId` (and any metadata you care about) on a JSONB or text field on your record. At read time, fetch the record and re-issue the file's signed URL through the download endpoint.
  </Accordion>

  <Accordion title="Are upload URLs cached?">
    The upload `url` is a signed token with an expiry. Don't persist it — persist the `fileId` and generate fresh URLs at read time. Downloads of the binary itself are cached for one year by default.
  </Accordion>

  <Accordion title="What's the maximum file size?">
    The default upload limit is enforced at the gateway. Exceeding it returns `413 Payload Too Large`. For very large files, use a direct-to-storage upload pattern through your provider's SDK and store only the resulting object key in Archie.
  </Accordion>

  <Accordion title="Can I switch storage providers later?">
    Yes — configure a new provider in [File Manager](/features/backend/app-services/file-manager) and point new uploads at it. Existing files stay where they were uploaded; migrate them with a script if you want to consolidate.
  </Accordion>

  <Accordion title="What happens if I delete a file that's referenced by a record?">
    The reference becomes a broken link. Archie doesn't enforce referential integrity between records and files — clean up references when you delete files, or add a server-side check before deletion.
  </Accordion>
</AccordionGroup>
