---
title: "Add files to a matter"
method: POST
path: "/matters/{matterId}/documents/files/bulk"
tags: ["Files"]
---

# Add files to a matter

`POST /matters/{matterId}/documents/files/bulk`

Registers a batch of new files on the matter and returns one 'UploadFileInfo' (presigned PUT URL, valid for 1 hour)
per file, in request order. Intended for data migrations. The same rules as 'AddFile' apply to each item.
            
The operation is not atomic: items are validated in order and a 400 on item n leaves the upload requests for
items before it in place. No 'Location' header is returned. There is no cap on the array size.

## Path parameters

- `matterId` string, required

## Request body

- AddFileDto[]
  - `fileName` string, required — Full name of the file including the file extension. Required, maximum 256 characters. The name is split on the last '.' into name and extension, and the name is normalised to XML-safe characters. It must contain at least one valid character after normalisation.
  - `folderId` string, nullable — Unique identifier (GUID) of the folder to add the file to. If null (and FolderPath is not set) the file is placed in the root folder. Mutually exclusive with FolderPath. The folder is not validated for existence.
  - `userId` string, nullable — Unique identifier (GUID) of the file owner. If null it will fallback to the authenticated user
  - `folderPath` string, nullable — Path of the folder to add the file to, relative to the matter root, with '/' separating folder names. Mutually exclusive with FolderId: set at most one of the two. If neither is set the file is placed in the root folder.
  - `fileAdditionalData` object, nullable — Dictionary of custom metadata to store against the file. Keys must not be blank. Values must be strings, integers, numbers, booleans or null; objects and arrays are rejected.
  - `dateCreated` string, date-time, nullable — The original datetime that the file was created. If null the current datetime will be used
  - `dateModified` string, date-time, nullable — The initial datetime that the file was last modified. If null the current datetime will be used

## Response `202`

When request is accepted. Returns an array of 'UploadFileInfo' objects.

- UploadFileInfo[]
  - `fileId` string, nullable — Unique identifier of the file.
  - `uploadUrl` string, nullable — Temporary presigned URL to upload the file content to. Send the raw file bytes with an HTTP PUT request. The URL is valid for 1 hour from the time of the API call (see Expiry). Important note: When uploading to this URL, set the 'Content-Type' header to an empty value. Example cURL: curl --location --request PUT 'URL_GOES_HERE' \ --header 'Content-Type: ""' \ --data '@/C:/dir/test.pdf'
  - `expiry` string, date-time — UTC date/time when the upload link is no longer accessible (1 hour after issue).

## Other responses

- `400` — When the supplied matterId is not a valid GUID; when the body fails validation; or when any item has a file name with no valid XML characters, has both 'folderId' and 'folderPath' set, or has additional data with a blank key or a non-primitive value.

## Changes

- **2026-08-26** `db1b8a86b58e` — 1 breaking, 5 warning
  - the response's body type/format changed from `object`/`` to `string`/`` for status `400`
  - removed the optional property `detail` from the response with the `400` status
  - removed the optional property `instance` from the response with the `400` status
  - removed the optional property `status` from the response with the `400` status
  - …2 more

[Change history](https://skmtc.dev/smokeball/apis/api/changes/matters/:matterId/documents/files/bulk/post.md)

---

[API](https://skmtc.dev/smokeball/apis/api.md) · [All operations](https://skmtc.dev/smokeball/apis/api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/smokeball/api/revisions/db1b8a86b58e/schema)
