> ## 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.

# Upload Evidence Files to Slate Using Presigned URLs

> Learn how to create a file upload session, transfer your file to S3 via a presigned URL, verify upload status, and reference the file id in Slate.

Slate stores evidence files — affidavits, account statements, charge-off letters, and more — directly in your matter's document library. Uploading a file is a three-step process: create a session to get a presigned S3 URL, POST the file bytes directly to S3, then confirm the upload completed. This approach keeps large binaries out of Slate's API servers and lets S3 handle transfer reliability.

<Tip>
  For all new integrations, target the **v2 read endpoints** (`GET /v2/files` and `GET /v2/files/{fileId}`) where available. The v2 file schema splits the single v1 `fileType` field into `tag` (the owner-specific document tag) and `fileType` (the owner-agnostic canonical Slate type). Creating an upload session (`POST /v1/files`), concatenating (`POST /v1/files/concat`), and archiving (`DELETE /v1/files/{fileId}`) remain v1 operations.
</Tip>

<Steps>
  <Step title="Create a file upload session">
    Call `POST /v1/files` to register the file with Slate and receive a presigned upload URL. Slate creates a file record in a `pending` state and returns a short-lived URL along with required form fields.

    **Required fields:**

    | Field      | Type   | Description                                                                                                                                                  |
    | ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `matterId` | UUID   | The matter this file belongs to                                                                                                                              |
    | `crid`     | string | Your internal reference ID for the file                                                                                                                      |
    | `fileName` | string | File name **including extension** (e.g. `affidavit.pdf`)                                                                                                     |
    | `fileType` | string | Document type (e.g. `account_statement`, `affidavit`). Contact your Slate account manager for the full list of supported values in your owner configuration. |

    <Warning>
      The `fileName` field **must include the file extension**. Omitting it (e.g. sending `affidavit` instead of `affidavit.pdf`) causes the upload session to fail or the file to be stored without a MIME type, breaking downstream rendering and redaction.
    </Warning>

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.slate.inc/files/v1/files \
        -H 'Authorization: Bearer <token>' \
        -H 'Content-Type: application/json' \
        -d '{
          "matterId": "m1a2b3c4-0001-0001-0001-000000000001",
          "crid": "CRID-00192",
          "fileName": "statement_oct_2024.pdf",
          "fileType": "account_statement"
        }'
      ```

      ```json Example Request Body theme={null}
      {
        "matterId": "m1a2b3c4-0001-0001-0001-000000000001",
        "crid": "CRID-00192",
        "fileName": "statement_oct_2024.pdf",
        "fileType": "account_statement"
      }
      ```
    </CodeGroup>

    The response body contains:

    * `id` — Slate's UUID for this file record
    * `uploadUrl` — the presigned S3 POST URL
    * `fields` — form fields that must be included in the multipart POST
    * `key` — the S3 object key where the file will be stored
    * `fileName` — the file name Slate recorded for this upload
    * `maxFileSize` — maximum file size in bytes that S3 will accept for this upload session

    ```json Example Response 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/statement_oct_2024.pdf",
        "AWSAccessKeyId": "ASIAIOSFODNN7EXAMPLE",
        "x-amz-security-token": "FwoGZXIvYXdzEHcaDEXAMPLE...",
        "policy": "eyJleHBpcmF0aW9uIjoiMjAyNC0xMS0xNVQxMDo0NTowMFoiLCJjb25kaXRpb25zIjpbXX0=",
        "signature": "EXAMPLESIGNATURE=="
      },
      "key": "uploads/org_abc123/f1a2b3c4-0001-0001-0001-000000000001/statement_oct_2024.pdf",
      "fileName": "statement_oct_2024.pdf",
      "maxFileSize": 52428800
    }
    ```
  </Step>

  <Step title="Upload the file to the presigned S3 URL">
    POST your file directly to the `uploadUrl` using multipart form data. Include **all fields** from the `fields` object first, then append the file itself as the final `file` part. The field order matters — S3 requires the `file` part to be last.

    <Note>
      Presigned S3 upload URLs expire after **15 minutes**. Start the file transfer immediately after receiving the session response. If your upload window is longer than 15 minutes, create a new session rather than reusing an expired URL.
    </Note>

    ```bash cURL theme={null}
    curl -X POST https://slate-uploads.s3.amazonaws.com/ \
      -F 'key=uploads/org_abc123/f1a2b3c4-0001-0001-0001-000000000001/statement_oct_2024.pdf' \
      -F 'AWSAccessKeyId=ASIAIOSFODNN7EXAMPLE' \
      -F 'x-amz-security-token=FwoGZXIvYXdzEHcaDEXAMPLE...' \
      -F 'policy=eyJleHBpcmF0aW9uIjoiMjAyNC0xMS0xNVQxMDo0NTowMFoiLCJjb25kaXRpb25zIjpbXX0=' \
      -F 'signature=EXAMPLESIGNATURE==' \
      -F 'file=@/local/path/to/statement_oct_2024.pdf'
    ```

    A successful S3 upload returns HTTP `204 No Content` with an empty body. Any non-2xx response from S3 means the file was not stored — check your `fields` values and URL for accuracy before retrying.
  </Step>

  <Step title="Verify the upload status">
    After the S3 transfer completes, call `GET /v2/files/{fileId}` to confirm Slate has processed the file and marked it as ready for use. Poll until `uploadStatus` equals `uploaded`.

    ```bash cURL theme={null}
    curl -X GET https://api.slate.inc/files/v2/files/f1a2b3c4-0001-0001-0001-000000000001 \
      -H 'Authorization: Bearer <token>'
    ```

    ```json Example Response 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": "statement_oct_2024.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": "ACCT_STMT",
      "fileType": "ACCOUNT_STATEMENT",
      "description": "Monthly statement for October 2024",
      "metadata": null,
      "fileAttributes": {
        "sizeBytes": 148213,
        "contentType": "application/pdf"
      }
    }
    ```

    The `redactionSummary` object is only included when you pass `?redactionSummary=true` and the file has at least one redaction job.

    Poll until `uploadStatus` is `"uploaded"`. Possible `uploadStatus` values:

    | Status     | Meaning                                       |
    | ---------- | --------------------------------------------- |
    | `pending`  | Session created; S3 upload not yet confirmed  |
    | `uploaded` | File is ready to use in downstream operations |

    Use exponential backoff starting at 2 seconds. Most files reach `uploaded` within 10–30 seconds.
  </Step>

  <Step title="Reference the id in downstream operations">
    Once the file `uploadStatus` is `"uploaded"`, use the `id` anywhere Slate accepts a file reference:

    * **Exhibits** — attach the file to a pleading or court filing
    * **Redaction** — submit the `id` to `POST /v1/redactions` to automatically redact sensitive data
    * **E-signature** — include the file as a document in a signature request
    * **QC review** — associate the file with a quality control checklist item

    Store the `id` alongside your `crid` in your own system so you can retrieve the Slate reference without an extra lookup.
  </Step>
</Steps>
