# Repository · Files

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## POST /repository/file/append

**Append to a file**

`operationId: RepositoryController_append`

Appends content to the end of an existing file, without reading and rewriting the whole thing.

#### Signature

```http
POST /repository/file/append (body) -> The updated file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/prepend`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to append, and where.

```json
{
  "location": "logs/import.log",
  "content": "row 412 imported\n"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/prepend

**Prepend to a file**

`operationId: RepositoryController_prepend`

Inserts content at the start of an existing file.

#### Signature

```http
POST /repository/file/prepend (body) -> The updated file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/append`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to prepend, and where.

```json
{
  "location": "logs/import.log",
  "content": "# import started\n"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/copy

**Copy a file**

`operationId: RepositoryController_copy`

Copies a file to another location, leaving the original in place.

#### Signature

```http
POST /repository/file/copy (body) -> The copied file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/move`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Source and destination.

```json
{
  "from": "products/cola.jpg",
  "to": "archive/cola.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The copied file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/move

**Move a file**

`operationId: RepositoryController_move`

Moves a file to another location. Any URL already pointing at the old path stops resolving, so update references before moving a file that is in use.

#### Signature

```http
POST /repository/file/move (body) -> The moved file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Breaks existing links to the old path.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/copy`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Source and destination.

```json
{
  "from": "products/cola.jpg",
  "to": "archive/cola.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The moved file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/delete

**Delete a file**

`operationId: RepositoryController_delete`

Deletes a file from storage. Permanent — there is no trash for files as there is for records.

#### Signature

```http
POST /repository/file/delete (body) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Irreversible. Records still referencing the file keep a URL that no longer resolves.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/exists`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to delete.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /repository/file/driver

**Get the storage driver**

`operationId: RepositoryController_driver`

Reports which storage backend the org uses. Useful when behaviour differs between drivers — folder semantics and signed-URL support in particular.

#### Signature

```http
GET /repository/file/driver () -> The active storage driver
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The active storage driver |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/exists

**Check whether a file exists**

`operationId: RepositoryController_exists`

Reports whether a file is present at a location, without fetching it.

#### Signature

```http
POST /repository/file/exists (body) -> Whether the file exists
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/stat`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The location to check.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Whether the file exists |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file

**Write a file**

`operationId: RepositoryController_getFile`

Writes file content directly, without a multipart upload — for generated content such as an exported CSV or a rendered template.

#### Signature

```http
POST /repository/file (body) -> The stored file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/append`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to write.

```json
{
  "location": "exports/report.csv",
  "content": "sku,title\nDRK-COLA-330,Cola 330ml"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The stored file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/create_favicon

**Create a favicon**

`operationId: RepositoryController_createFavicon`

Generates `favicon.ico` and `favicon.png` at the org bucket root from a source image, and returns `{ ico: { signedUrl, path }, png: { signedUrl, path } }`.

Give it a **square** source, at least 512×512, with the mark filling the frame. The generator resizes but does not crop, so a wide wordmark becomes illegible at 16×16.

#### Signature

```http
POST /repository/file/create_favicon (body) -> The generated favicons
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- `location` must NOT include the org prefix. An upload returns `<org>/brand/logo.png`; pass `brand/logo.png`. Passing the full path scopes it twice and the source is not found.
- Generating the files is not enough to change the icon a browser shows. Write the URL to the site record as `site.data.favicon`, and it MUST be a plain string — an object is silently ignored and the site keeps the platform default. (`site.data.logo` may be an object; the two are not symmetrical.)
- Page-level `<link rel="icon">` tags in page HTML are deliberately stripped by the renderer, so a page cannot set its own favicon. The site record is the only mechanism.
- The generated files are private — an unsigned GET returns 403. Use the returned signed URLs.
- Every generated `.ico` is the same byte length, because it is a multi-resolution container. Compare hashes, not sizes, to tell two apart.
- Verify on the rendered page, not the record: `curl -s https://your-site/ | grep -oE '<link rel="icon" href="[^"]{0,80}'`. Seeing `/favicon.ico` means your value was ignored.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/thumbnails`
- `POST /repository/file/upload`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The source image, as a path WITHOUT the org prefix.

```json
{
  "location": "brand/logo.png"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The generated favicons |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/get_asset

**Get an asset file**

`operationId: RepositoryController_getFileAsset`

Retrieves a file as an asset record, with its metadata alongside the content.

#### Signature

```http
POST /repository/file/get_asset (body) -> The asset
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/stat`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The asset to fetch.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The asset |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/buffer

**Get file contents as a buffer**

`operationId: RepositoryController_getFileBuffer`

Returns the raw bytes of a file. Use `signurl` instead for anything large — this loads the whole file into memory.

#### Signature

```http
POST /repository/file/buffer (body) -> The file contents
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Loads the entire file. Prefer a signed URL for large files.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/signurl`
- `POST /repository/file/stream`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to read.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The file contents |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/signurl

**Get a signed URL for a file**

`operationId: RepositoryController_getSignedUrl`

Returns a time-limited URL that grants direct access to a private file, so a browser can fetch it without the request passing through the platform.

The URL carries its own authorization — anyone holding it has access until it expires. Do not log or cache it.

#### Signature

```http
POST /repository/file/signurl (body) -> The signed URL
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- The URL is a bearer credential. Treat it as a secret for its lifetime.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/make-private`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to sign.

```json
{
  "location": "private/contract.pdf",
  "expiresIn": 3600
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The signed URL |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/stat

**Get file metadata**

`operationId: RepositoryController_getStat`

Returns size, content type and timestamps for a file without downloading it.

#### Signature

```http
POST /repository/file/stat (body) -> File metadata
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/exists`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to inspect.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | File metadata |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/index

**Index files**

`operationId: RepositoryController_indexFileLocation`

Rebuilds the searchable index over stored files. An administrative operation — run it after a bulk import that bypassed normal upload.

#### Signature

```http
POST /repository/file/index (body) -> Indexing result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to index.

```json
{}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Indexing result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/stream

**Stream a file**

`operationId: RepositoryController_getStream`

Streams a file rather than buffering it — the right choice for large files and for passing content straight through to a client.

#### Signature

```http
POST /repository/file/stream (body) -> The file stream
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/buffer`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to stream.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The file stream |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/url

**Get a file URL**

`operationId: RepositoryController_getUrl`

Returns the public URL for a file. For a private file, use `signurl` instead — a public URL will not resolve.

#### Signature

```http
POST /repository/file/url (body) -> The file URL
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/signurl`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to resolve.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The file URL |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/make-private

**Make a file private**

`operationId: RepositoryController_makePrivate`

Removes public access from a file. Existing public URLs stop resolving, and access then requires a signed URL.

#### Signature

```http
POST /repository/file/make-private (body) -> The updated file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Already-issued signed URLs keep working until they expire.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/make-public`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to restrict.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/make-public

**Make a file public**

`operationId: RepositoryController_makePublic`

Grants public access to a file. **Anyone with the URL can then read it, with no authentication** — check the contents before making a file public.

#### Signature

```http
POST /repository/file/make-public (body) -> The updated file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Irreversible in effect once the URL has been shared, even if you make the file private again later.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/make-private`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to publish.

```json
{
  "location": "products/cola-330ml.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/createfolder

**Create a folder**

`operationId: RepositoryController_createfolder`

Creates a folder in storage. Most drivers infer folders from file paths, so this is only needed where an empty folder must exist.

#### Signature

```http
POST /repository/file/createfolder (body) -> The created folder
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/flatlist`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The folder to create.

```json
{
  "location": "products/2026"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The created folder |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/thumbnails

**Generate thumbnails**

`operationId: RepositoryController_createThumbnails`

Generates thumbnail renditions for an image.

#### Signature

```http
POST /repository/file/thumbnails (body) -> The generated thumbnails
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | FILE_NOT_FOUND | File not found | No file exists at that location. | Check the path with `POST /repository/file/exists` first. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/create_favicon`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The image to generate thumbnails for.

```json
{
  "location": "products/cola.jpg",
  "sizes": [
    200,
    800
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The generated thumbnails |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | File not found — No file exists at that location. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/upload

**Upload a file**

`operationId: RepositoryController_upload`

Uploads a file as multipart form data. The stored path is `location` plus the original filename.

**`isPrivate` is read as the string `"true"`, not a boolean** — because this is a multipart form, a JSON `true` does not match and the file is stored **public**. Send the literal string.

#### Signature

```http
POST /repository/file/upload (body) -> The stored file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- A boolean `true` for `isPrivate` does not work — only the string `"true"` makes the file private.
- Uploading to an existing path overwrites it without warning.
- `location` is a FOLDER, not a full path. The filename is appended for you — passing `products/chair/chair.jpg` stores `products/chair/chair.jpg/chair.jpg`.
- The returned `path` is org-prefixed (`<org>/<location>/<file>`). Endpoints that take a `location` want the path WITHOUT that prefix.
- Files are served as `application/octet-stream`. Browsers sniff raster formats, so PNG and JPEG render normally — **SVG does not**, and must be inlined into the page instead of linked.
- Raise your client timeout for large files; the default in most HTTP clients is too short for a slow connection.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/upload-url`
- `POST /repository/file/make-private`
- `POST /repository/file/create_favicon`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Multipart form: the file plus its placement.

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The stored file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/upload-url

**Upload a file from a URL**

`operationId: RepositoryController_uploadFromUrl`

Fetches a file from a URL and stores it, without the client having to download and re-upload it.

#### Signature

```http
POST /repository/file/upload-url (body) -> The stored file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- The server fetches the URL — it must be reachable from the server, not just from your client.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/upload`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Where to fetch from and where to store it.

```json
{
  "url": "https://example.com/hero.jpg",
  "location": "products/hero.jpg"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The stored file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /repository/file/flatlist/{prefix}/{pageNumber}

**List files (URL form)**

`operationId: RepositoryController_flatList`

The URL form of the flat file listing. `check-privacy` additionally reports whether each file is public or private, at the cost of extra lookups.

#### Signature

```http
GET /repository/file/flatlist/{prefix}/{pageNumber} (prefix: string, pageNumber: string, check-privacy?: boolean) -> Files under the prefix
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/file/flatlist`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `prefix` | path | string | yes | Path prefix to list under. |
| `pageNumber` | path | string | yes | Page number. |
| `check-privacy` | query | boolean | — | Also report each file's public/private state. Slower. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Files under the prefix |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/file/flatlist

**List files**

`operationId: RepositoryController_flatListPost`

Lists files under a prefix as a flat list rather than a tree.

#### Signature

```http
POST /repository/file/flatlist (body) -> Files under the prefix
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /repository/file/flatlist/{prefix}/{pageNumber}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to list.

```json
{
  "prefix": "products",
  "pageNumber": 1
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Files under the prefix |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/customer/file/flatlist

**List customer files**

`operationId: RepositoryController_customerFlatList`

Lists files in the calling customer's own storage area.

#### Signature

```http
POST /repository/customer/file/flatlist (body) -> The customer's files
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/customer/file/upload`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to list.

```json
{
  "prefix": "documents"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The customer's files |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/customer/file/upload

**Upload a customer file**

`operationId: RepositoryController_customerUpload`

Uploads a file into the calling customer's own storage area, kept separate from org files so a customer cannot reach another's uploads.

#### Signature

```http
POST /repository/customer/file/upload (body) -> The stored file
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/customer/file/flatlist`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Multipart form with the file.

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The stored file |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /repository/customer/file/delete

**Delete a customer file**

`operationId: RepositoryController_customerDelete`

Deletes a file from the calling customer's storage area.

#### Signature

```http
POST /repository/customer/file/delete (body) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /repository/customer/file/flatlist`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The file to delete.

```json
{
  "location": "documents/contract.pdf"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

