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

# Files and Document Requests: Slate API File Management

> Upload files to Slate via presigned S3 URLs, then assemble them into evidence bundles with exhibit ordering to generate final court-ready PDFs.

Slate organizes document management into two related concepts. **Files** are the raw documents you upload — affidavits, account statements, chain-of-title records, and any other supporting material. **Requests** are structured document bundles that attach files as exhibits, apply templates, and generate final PDFs suitable for court filings or creditor review. You typically upload files first, then reference them in one or more requests.

## Files

### Uploading a File

Slate uses presigned S3 URLs for file uploads. Your application never sends file bytes directly to the Slate API. Instead, you get a short-lived upload URL and form fields from Slate, then POST the file directly to S3 using multipart form data.

<Steps>
  <Step title="Create a file record and get a presigned upload URL">
    Call `POST /v1/files` with metadata about the file. Slate returns a presigned S3 URL, required form fields, and an `id` for the new record.

    ```bash theme={null}
    curl --request POST \
      --url "https://api.slate.inc/files/v1/files" \
      --header "Authorization: Bearer <your-token>" \
      --header "Content-Type: application/json" \
      --data '{
        "matterId": "m1a2b3c4-0001-0001-0001-000000000001",
        "crid": "CRID-00192",
        "fileName": "affidavit-of-debt.pdf",
        "fileType": "affidavit"
      }'
    ```

    Response:

    ```json theme={null}
    {
      "id": "f1a2b3c4-0001-0001-0001-000000000001",
      "uploadUrl": "https://slate-uploads.s3.amazonaws.com/",
      "fields": {
        "key": "uploads/org_abc123/f1a2b3c4-0001-0001-0001-000000000001/affidavit-of-debt.pdf",
        "AWSAccessKeyId": "ASIAIOSFODNN7EXAMPLE",
        "x-amz-security-token": "FwoGZXIvYXdzEHcaDEXAMPLE...",
        "policy": "eyJleHBpcmF0aW9uIjoiMjAyNC0xMS0xNVQxMDo0NTowMFoiLCJjb25kaXRpb25zIjpbXX0=",
        "signature": "EXAMPLESIGNATURE=="
      },
      "key": "uploads/org_abc123/f1a2b3c4-0001-0001-0001-000000000001/affidavit-of-debt.pdf",
      "fileName": "affidavit-of-debt.pdf",
      "maxFileSize": 52428800
    }
    ```
  </Step>

  <Step title="Upload the file bytes directly to S3">
    Use the `uploadUrl` and `fields` from the previous response to construct a multipart form POST. Include every key-value pair from `fields` as individual form fields, then append the actual file as the `file` field last. The order matters: S3 requires all policy fields to appear before the file bytes.

    ```bash theme={null}
    curl --request POST \
      --url "https://slate-uploads.s3.amazonaws.com/" \
      --form "key=uploads/org_abc123/f1a2b3c4-0001-0001-0001-000000000001/affidavit-of-debt.pdf" \
      --form "AWSAccessKeyId=ASIAIOSFODNN7EXAMPLE" \
      --form "x-amz-security-token=FwoGZXIvYXdzEHcaDEXAMPLE..." \
      --form "policy=eyJleHBpcmF0aW9uIjoiMjAyNC0xMS0xNVQxMDo0NTowMFoiLCJjb25kaXRpb25zIjpbXX0=" \
      --form "signature=EXAMPLESIGNATURE==" \
      --form "file=@/path/to/affidavit-of-debt.pdf"
    ```

    A successful upload returns HTTP `204 No Content` from S3. Slate detects the upload asynchronously and transitions the file record's `uploadStatus` to `uploaded`.
  </Step>

  <Step title="Confirm the file is available">
    Once the S3 upload completes, poll the file record to confirm it is ready to use in requests.

    ```bash theme={null}
    curl --request GET \
      --url "https://api.slate.inc/files/v2/files/f1a2b3c4-0001-0001-0001-000000000001" \
      --header "Authorization: Bearer <your-token>"
    ```

    ```json theme={null}
    {
      "id": "f1a2b3c4-0001-0001-0001-000000000001",
      "matterId": "m1a2b3c4-0001-0001-0001-000000000001",
      "owner": "org_abc123",
      "status": "active",
      "uploadStatus": "uploaded",
      "crid": "CRID-00192",
      "fileName": "affidavit-of-debt.pdf",
      "uploadedOn": "2024-11-15T10:32:00Z",
      "downloadUrl": "https://slate-files.s3.amazonaws.com/presigned-url-...",
      "creditorCreationDate": "2024-10-01T00:00:00Z",
      "uploadedBy": "u1a2b3c4-0001-0001-0001-000000000001",
      "tag": "AFFIDAVIT",
      "fileType": "REPAYMENT_AGREEMENT",
      "description": "",
      "metadata": null,
      "fileAttributes": {
        "sizeBytes": 148213,
        "contentType": "application/pdf"
      }
    }
    ```
  </Step>
</Steps>

### File Statuses

| Field          | Values                | Meaning                                                                                                                                |
| -------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `status`       | `active`, `archived`  | Whether the file is in active use or has been archived. Archived files remain accessible but are excluded from default list responses. |
| `uploadStatus` | `pending`, `uploaded` | Whether the file bytes have been successfully received by S3. A file is ready to use only when `uploadStatus` is `uploaded`.           |

### v1 vs v2 Files

<Note>
  **Use v2 for new integrations.** The v1 files API uses a single `fileType` field that blends the document's tag and its canonical type. The v2 API (`GET /v2/files`) separates these into `tag` (the document tag) and `fileType` (the canonical Slate document type). This makes filtering and display significantly easier. Migrate existing integrations to v2 when convenient.
</Note>

### Redaction Summaries

When listing or retrieving files, append `?redactionSummary=true` to include the current redaction state for each file that has at least one redaction. The `redactionSummary` object reflects the most recently created redaction job: `latestId`, `latestStatus` (`pending`, `processing`, `completed`, or `failed`), `latestCreatedOn`, `latestErrorMessage` (populated only when `latestStatus` is `failed`), and `count` of jobs for the file. Files with no redactions omit the object entirely.

```bash theme={null}
curl --request GET \
  --url "https://api.slate.inc/files/v2/files?owner=org_abc123&redactionSummary=true" \
  --header "Authorization: Bearer <your-token>"
```

You can also filter the list by redaction state with `filter[redactionStatus]` (`in_progress`, `completed`, `failed`, or `none`), which requires `redactionSummary=true`.

### Archiving a File

To remove a file from active workflows, call `DELETE /v1/files/{fileId}`. This sets the file's `status` to `archived` without deleting the underlying document. Archived files no longer appear in default `GET /v2/files` results unless you explicitly filter with `filter[status]=archived`.

```bash theme={null}
curl --request DELETE \
  --url "https://api.slate.inc/files/v1/files/f1a2b3c4-0001-0001-0001-000000000001" \
  --header "Authorization: Bearer <your-token>"
```

A successful archive returns HTTP `204 No Content`.

### Concatenating Files

Merge multiple existing Slate PDF files into a single document using `POST /v1/files/concat`. Provide an ordered array of file IDs. Slate returns a presigned `downloadUrl` for the merged output. Non-PDF files are excluded from the merge and reported in the `nonPdfFiles` array.

```bash theme={null}
curl --request POST \
  --url "https://api.slate.inc/files/v1/files/concat" \
  --header "Authorization: Bearer <your-token>" \
  --header "Content-Type: application/json" \
  --data '{
    "files": [
      "f1a2b3c4-0001-0001-0001-000000000001",
      "f1a2b3c4-0002-0002-0002-000000000002"
    ],
    "download": false
  }'
```

### Bulk Downloading Files

To retrieve many files at once, submit a bulk download job with `POST /v1/bulkDownloads`, passing a `files` array of file UUIDs (and an optional `fileName`). Slate responds with `202 Accepted` and a job object containing `id`, `status`, and a `pollUrl`. Poll `GET /files/bulkDownloads/{bulkDownloadId}` until `status` is `done`; the response then includes a presigned `downloadUrl` for the zip. Job statuses are `pending`, `processing`, `done`, and `failed`.

```bash theme={null}
curl --request POST \
  --url "https://api.slate.inc/files/v1/bulkDownloads" \
  --header "Authorization: Bearer <your-token>" \
  --header "Content-Type: application/json" \
  --data '{
    "files": [
      "f1a2b3c4-0001-0001-0001-000000000001",
      "f1a2b3c4-0002-0002-0002-000000000002"
    ]
  }'
```

## Requests

A **Request** is a document bundle tied to a `matterId`. You define the structure of the bundle through a `triggerContext` that determines which templates and exhibits Slate attaches. Then you fill template fields, generate a preview PDF, and approve the request to create a permanent file record.

### Request Workflow

<Steps>
  <Step title="Create a request">
    Call `POST /v1/requests` with the `matterId` and a `triggerContext` that specifies the `templateType`, `lifecycleStep`, and `lineOfBusiness`. Slate returns the created request with its `id` and sets the initial status to `pending`. You can also optionally provide `notes`, `priority`, or `status`.

    ```bash theme={null}
    curl --request POST \
      --url "https://api.slate.inc/files/v1/requests" \
      --header "Authorization: Bearer <your-token>" \
      --header "Content-Type: application/json" \
      --data '{
        "matterId": "m1a2b3c4-0001-0001-0001-000000000001",
        "triggerContext": {
          "templateType": "affidavit",
          "lifecycleStep": "pre_suit",
          "lineOfBusiness": "credit_card"
        },
        "notes": "Needed before court filing on 2024-12-10",
        "priority": 3
      }'
    ```
  </Step>

  <Step title="Fill template fields">
    Use `PATCH /v1/requests/{requestId}` to submit values for the template fields listed in `requestedFields`. Each fill targets a specific `templateId` and provides an array of `{ key, value }` pairs.

    ```bash theme={null}
    curl --request PATCH \
      --url "https://api.slate.inc/files/v1/requests/r1a2b3c4-0001-0001-0001-000000000001" \
      --header "Authorization: Bearer <your-token>" \
      --header "Content-Type: application/json" \
      --data '{
        "filledFields": [
          {
            "templateId": "t1a2b3c4-0001-0001-0001-000000000001",
            "fields": [
              { "key": "debtorName", "value": "Jane Q. Smith" },
              { "key": "accountBalance", "value": "4250.00" }
            ]
          }
        ]
      }'
    ```

    Field fills are merged, not replaced. Previously filled keys remain unless you overwrite them.
  </Step>

  <Step title="Generate a preview PDF">
    Before finalizing, call `POST /v1/requests/{requestId}/generate` to compile the filled templates and exhibits into a preview PDF. Slate returns a temporary `downloadUrl` you can present to reviewers. This does not create a permanent file record.

    ```bash theme={null}
    curl --request POST \
      --url "https://api.slate.inc/files/v1/requests/r1a2b3c4-0001-0001-0001-000000000001/generate" \
      --header "Authorization: Bearer <your-token>"
    ```

    ```json theme={null}
    {
      "downloadUrl": "https://slate-files.s3.amazonaws.com/previews/presigned-url-..."
    }
    ```
  </Step>

  <Step title="Approve to finalize">
    Once the preview has been reviewed, call `POST /v1/requests/{requestId}/approve` to generate the permanent file record. Slate compiles the output into a persistent PDF, creates a new file record, attaches it to the request's `generatedFile` field, and sets the request status to `completed`. Approval is irreversible.

    ```bash theme={null}
    curl --request POST \
      --url "https://api.slate.inc/files/v1/requests/r1a2b3c4-0001-0001-0001-000000000001/approve" \
      --header "Authorization: Bearer <your-token>"
    ```
  </Step>
</Steps>

### Request Statuses

| Status      | Meaning                                                      |
| ----------- | ------------------------------------------------------------ |
| `pending`   | The request has been created and is being assembled.         |
| `completed` | The request has been approved and the final PDF is locked.   |
| `rejected`  | The request was reviewed and rejected. Correct and resubmit. |

### Listing Requests

Retrieve document requests using `GET /v1/requests`. You must pass `owner` if using multi-owner credentials. Filter by status, matter (`filter[matterId]`), creditor reference (`filter[crid]`), service firm (`filter[firmId]`), template (`filter[templateId]`), priority (`filter[hasPriority]`), and completion date (`filter[completedFrom]` / `filter[completedTo]`). Order by `id`, `crid`, `createdOn`, `matterId`, or `priority`. Results are paginated: the response contains a `fileRequests` array and a `pagination` object with `nextCursor`, `previousCursor`, and `totalCount`.

```bash theme={null}
curl --request GET \
  --url "https://api.slate.inc/files/v1/requests?owner=org_abc123&status=pending&orderBy=priority&orderDirection=asc&limit=25" \
  --header "Authorization: Bearer <your-token>"
```

### Deleting a Request

Permanently remove a request that was created in error or is no longer needed using `DELETE /v1/requests/{requestId}`. This is irreversible and removes the request record, template fill state, and exhibit references. Any file generated from a prior approval of this request remains intact.

```bash theme={null}
curl --request DELETE \
  --url "https://api.slate.inc/files/v1/requests/r1a2b3c4-0001-0001-0001-000000000001" \
  --header "Authorization: Bearer <your-token>"
```

A successful deletion returns HTTP `204 No Content`.
