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

# Upload Signed Document

> Upload an externally signed document and attach it to a signature step

## Endpoint

```
POST /v2/tasks/{task_id}/upload-signed-document
```

## Authentication

This endpoint requires an OAuth access token. Send it as a bearer token:

```bash theme={null}
Authorization: Bearer your_access_token
```

**Required scope:** `tasks:write`

<Info>
  The document is uploaded as the access token's user. The `user_email` field on the request body is
  ignored.
</Info>

## Path Parameters

| Parameter | Type    | Required | Description                    |
| --------- | ------- | -------- | ------------------------------ |
| `task_id` | integer | Yes      | Unique identifier for the task |

## Request Body

The request body must be a JSON object with the following fields:

### Required Fields

| Field         | Type   | Description                                                            |
| ------------- | ------ | ---------------------------------------------------------------------- |
| `step_run_id` | string | ID of the signature step run                                           |
| `file`        | object | Signed document file to upload. See [File Object](#file-object-fields) |

### File Object Fields

| Field            | Type   | Description                          |
| ---------------- | ------ | ------------------------------------ |
| `filename`       | string | Filename, e.g. `signed_contract.pdf` |
| `base64_content` | string | Base64-encoded file content          |

## Request Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://platform.chamelio.ai/v2/tasks/12345/upload-signed-document" \
    -H "Authorization: Bearer your_access_token" \
    -H "Content-Type: application/json" \
    -d '{
      "step_run_id": "sr_abc123",
      "file": {
        "filename": "signed_contract.pdf",
        "base64_content": "JVBERi0xLjcKJ..."
      }
    }'
  ```

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

  task_id = 12345

  with open("signed_contract.pdf", "rb") as f:
      content = base64.b64encode(f.read()).decode("utf-8")

  url = f"https://platform.chamelio.ai/v2/tasks/{task_id}/upload-signed-document"
  headers = {
      "Authorization": "Bearer your_access_token",
      "Content-Type": "application/json"
  }

  payload = {
      "step_run_id": "sr_abc123",
      "file": {
          "filename": "signed_contract.pdf",
          "base64_content": content
      }
  }

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

  ```javascript JavaScript theme={null}
  const taskId = 12345;

  const response = await fetch(
    `https://platform.chamelio.ai/v2/tasks/${taskId}/upload-signed-document`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer your_access_token',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        step_run_id: 'sr_abc123',
        file: {
          filename: 'signed_contract.pdf',
          base64_content: 'JVBERi0xLjcKJ...'
        }
      })
    }
  );

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

## Response

### Success Response

**Status Code:** `200 OK`

```json theme={null}
{
  "task_id": 12345,
  "success": true,
  "output_variable_id": "signed_document"
}
```

### Response Fields

| Field                | Type    | Description                                |
| -------------------- | ------- | ------------------------------------------ |
| `task_id`            | integer | ID of the task                             |
| `success`            | boolean | Whether the upload succeeded               |
| `output_variable_id` | string  | Output variable ID for the signed document |

## Error Responses

### 400 Bad Request

Returned when the access token has no user behind it.
`client_credentials` tokens act as the admin who created the application, so this applies only to
tokens issued before application creators were recorded.

```json theme={null}
{
  "detail": "client_credentials tokens are not associated with a user"
}
```

### 401 Unauthorized

Returned when the access token is missing, unknown, revoked, or expired, or when an `X-API-Key` was
sent instead of a bearer token. See [OAuth error responses](/api-reference/oauth-apps#error-responses).

```json theme={null}
{
  "detail": "Invalid access token"
}
```

### 403 Forbidden

Returned when the token lacks the required scope:

```json theme={null}
{
  "detail": "Insufficient scope; this endpoint requires: tasks:write"
}
```

Or when the user may not act on this task:

```json theme={null}
{
  "detail": "You do not have access to this resource"
}
```

### 404 Not Found

Returned when the task does not exist.

```json theme={null}
{
  "detail": "Not found"
}
```

### 409 Conflict

Returned when the task is not at a signature step or the document cannot be attached in the current state.

```json theme={null}
{
  "detail": "The task is not in a state that allows this operation"
}
```

### 422 Validation Error

Returned when the request body is invalid.

```json theme={null}
{
  "detail": [
    {
      "loc": ["body", "step_run_id"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}
```

### 429 Too Many Requests

Returned when your organization exceeds its per-minute request limit.

```json theme={null}
{
  "detail": "Rate limit exceeded"
}
```

### 500 Internal Server Error

Returned when the upload fails due to a server error.

```json theme={null}
{
  "detail": "Failed to upload signed document"
}
```

## Notes

<Info>
  Use this endpoint when a document is signed outside Chamelio (for example, a manually signed PDF) and
  you need to attach the executed copy to the signature step.
</Info>

<Tip>
  Call [Get Signature Details](/api-reference/endpoint/v2/tasks/signature-details) to obtain the
  `step_run_id` for the signature step before uploading.
</Tip>

## Use Cases

This endpoint is useful for:

* **Manual signing flows** - Attach wet-signed or externally signed documents to a task
* **Third-party signature providers** - Record the executed document from a provider not integrated with Chamelio
* **Audit completeness** - Ensure the final signed copy is stored against the workflow step, attributed to the person who uploaded it
