> ## 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](/docs/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](/docs/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](/docs/features/backend/rest-api-explorer/error-handling).

## Permissions

File-management endpoints obey the same [Role-Based Access](/docs/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](/docs/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>
