> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.cloudraker.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.cloudraker.com/_mcp/server.

# Complete a human step

POST https://api.cloudraker.com/v1/agent-runs/{id}/tasks/{taskId}/complete
Content-Type: application/json

Marks one of the run's `executor: "human"` steps done, which releases everything waiting on it.

```json
{ "note": "Client signed; scan attached.", "files": ["file_01JQ8ZKMRT4V6WXYZ0ABCDEF"] }
```

Both fields are optional. `files` are ids you [registered](https://docs.cloudraker.com/api/cloud-raker-api/files/create-file) or that the run already holds; they are attached to the step and show up in the run's `output.files`.

Only human steps are completable — an agent's own step answers `422`. A step whose dependencies are unfinished answers `409`, and so does one that is already done. The response carries the step plus `run.status`; `?wait=` holds the request while the run picks the work back up.

An API key has no person behind it, so the run records your organization's key as the actor rather than a named individual.

**Learn more:** [Agents guide](https://docs.cloudraker.com/capabilities/agents)

Reference: https://docs.cloudraker.com/paperwork/api/agents/complete-agent-run-task

## Authentication

- `Authorization` header (bearer token, required)

## Request

### Path parameters

- `id` (string, required)
- `taskId` (string, required)

### Query parameters

- `wait` (integer, optional, default: 60) — How many seconds to hold the request open. Releases early the moment the run finishes **or** blocks on a person. Maximum 120; `0` returns immediately.

### Headers

- `idempotency-key` (string, optional) — Retries with the same key replay the first applied mutation.

### Body (application/json)

- `note` (string, optional) — What you did, recorded on the step and visible on the run.
- `files` (list of string, optional) — Files produced while doing the step, by file id.

## Response

### 200

The completed step, and where the run stands after it.

- `object` ("agent_run_task", required)
- `id` (string, required)
- `title` (string, required)
- `executor` (enum, required) — Who performs the step: `agent` runs by itself, `human` waits for a person to complete it.
  - Allowed values: `agent`, `human`
- `status` (enum, required)
  - Allowed values: `pending`, `ready`, `in_progress`, `completed`, `skipped`
- `summary` (string, required, nullable)
- `completedAt` (string, required, nullable)
- `run` (object, required)
  - `id` (string, required)
  - `status` (enum, required) — Where the agent run is in its life. | Status | Meaning | | --- | --- | | `queued` | Accepted; its files are still being prepared | | `processing` | The agent is working | | `waiting` | Blocked on a person — see `waiting`, `approvals` and `tasks[]` | | `paused` | Stopped short of finishing and resumable; not a failure | | `completed` | Finished; `result` and `output` are populated | | `failed` | Finished without producing a result | | `cancelled` | Stopped on request | | `expired` | Reached its `expiresAt` without finishing | `completed`, `failed`, `cancelled` and `expired` are terminal. A `completed` run that still had outstanding work also carries `incomplete: true`.
    - Allowed values: `queued`, `processing`, `waiting`, `paused`, `completed`, `failed`, `cancelled`, `expired`
  - `statusUrl` (string, required)
- `note` (string, optional)

## Examples

**Request**

```json
{}
```

**Response**

```json
{
  "object": "string",
  "id": "string",
  "title": "string",
  "executor": "agent",
  "status": "pending",
  "summary": "string",
  "completedAt": "string",
  "run": {
    "id": "string",
    "status": "queued",
    "statusUrl": "string"
  },
  "note": "string"
}
```

**SDK Code**

```typescript
import { CloudRakerClient } from "@cloudraker/api";

async function main() {
    const client = new CloudRakerClient({
        token: "YOUR_TOKEN_HERE",
    });
    await client.agents.completeAgentRunTask({
        id: "id",
        taskId: "taskId",
    });
}
main();

```

```python
from cloudraker import CloudRaker

client = CloudRaker(
    token="YOUR_TOKEN_HERE",
)

client.agents.complete_agent_run_task(
    id="id",
    task_id="taskId",
)

```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.cloudraker.com/v1/agent-runs/id/tasks/taskId/complete"

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.cloudraker.com/v1/agent-runs/id/tasks/taskId/complete")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.cloudraker.com/v1/agent-runs/id/tasks/taskId/complete")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.cloudraker.com/v1/agent-runs/id/tasks/taskId/complete', [
  'body' => '{}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.cloudraker.com/v1/agent-runs/id/tasks/taskId/complete");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.cloudraker.com/v1/agent-runs/id/tasks/taskId/complete")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```