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

# Get Upload URL

> Generate a presigned URL for uploading files to use as case inputs

If your workflow contains file inputs (type: `file` or `array_files`), you must upload files before executing the case. This endpoint generates a presigned URL for uploading.

<Note>
  Call this endpoint once for **each file** you need to upload. After receiving the presigned URL, proceed to [Upload File](/api-reference/v1-file/upload-file) to complete the upload.
</Note>

## Headers

<ParamField header="x-service-key" type="string" required>
  Your API authentication key
</ParamField>

## Body Parameters

<ParamField body="fileExtension" type="string" required>
  The file extension including the dot (e.g., `.pdf`, `.docx`)
</ParamField>

<ParamField body="accessScope" type="string">
  Access scope for the file. Options: `workspace`, `unlisted`. If omitted, the file is uploaded as **unlisted** — tracked by the platform but not shown in the file library.
</ParamField>

<ParamField body="originalName" type="string">
  The original filename of the file being uploaded (e.g., `Q4-Report.pdf`). Surfaced in the Opus file library to make the file easier to identify later.
</ParamField>

<ParamField body="workspaceId" type="string">
  Target workspace ID (UUID) for the file — the workspace the upload is checked against. Required unless `workflowId` is provided.
</ParamField>

<ParamField body="workflowId" type="string">
  Target workflow ID (UUID) for the file. The workspace that owns this workflow becomes the owner of the file. Required unless `workspaceId` is provided.
</ParamField>

<Warning>
  Every upload is checked against a workspace — you must provide either `workspaceId` or `workflowId`, regardless of `accessScope`.
</Warning>

## Supported File Types

| Extension               | Description        |
| ----------------------- | ------------------ |
| `.pdf`                  | PDF documents      |
| `.docx`                 | Word documents     |
| `.csv`                  | CSV spreadsheets   |
| `.xls`, `.xlsx`         | Excel spreadsheets |
| `.txt`                  | Plain text files   |
| `.json`                 | JSON files         |
| `.html`                 | HTML files         |
| `.xml`                  | XML files          |
| `.jpeg`, `.jpg`, `.png` | Image files        |

<Warning>
  The maximum file size for uploads is **10 MB**. Files exceeding this limit will be rejected.
</Warning>

## Response

<ResponseField name="presignedUrl" type="string" required>
  Temporary URL for uploading your file. Use this in the [Upload File](/api-reference/v1-file/upload-file) step.
</ResponseField>

<ResponseField name="fileUrl" type="string" required>
  Permanent URL to reference this file in your [Execute Case](/api-reference/v1-case/execute-case) request.
</ResponseField>

## Errors

<ResponseField name="401" type="Unauthorized">
  Missing, invalid, or expired API key.
</ResponseField>

<ResponseField name="404" type="Not Found">
  The workspace or workflow does not exist.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://operator.opus.com/api/v1/file/upload/presigned \
    --header 'Content-Type: application/json' \
    --header 'x-service-key: {YOUR_SERVICE_KEY}' \
    --data '{
      "fileExtension": ".pdf",
      "originalName": "Q4-Report.pdf",
      "workflowId": "{YOUR_WORKFLOW_ID}"
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://operator.opus.com/api/v1/file/upload/presigned"
  headers = {
      "Content-Type": "application/json",
      "x-service-key": "{YOUR_SERVICE_KEY}"
  }
  payload = {
      "fileExtension": ".pdf",
      "originalName": "Q4-Report.pdf",
      "workflowId": "{YOUR_WORKFLOW_ID}"
      # Or target a workspace directly instead:
      # "workspaceId": "{YOUR_WORKSPACE_ID}"
  }

  response = requests.post(url, json=payload, headers=headers)
  data = response.json()
  print(data)
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://operator.opus.com/api/v1/file/upload/presigned",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-service-key": "{YOUR_SERVICE_KEY}",
      },
      body: JSON.stringify({
        fileExtension: ".pdf",
        originalName: "Q4-Report.pdf",
        workflowId: "{YOUR_WORKFLOW_ID}",
        // Or target a workspace directly instead:
        // workspaceId: "{YOUR_WORKSPACE_ID}",
      }),
    }
  );

  const data = await response.json();
  console.log(data);
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Response theme={null}
  {
    "presignedUrl": "{PRESIGNED_URL}",
    "fileUrl": "{FILE_URL}"
  }
  ```
</ResponseExample>
