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

# Create Task

> Create a new task and start background execution

# Create Task

Create a new task and start background AI agent execution. The endpoint returns immediately with the task ID. Connect to the [Stream endpoint](/tasks/stream) to receive real-time updates.

## Request

```bash theme={null}
POST /api/v1/tasks
Authorization: Bearer {api_key_or_jwt}
Content-Type: multipart/form-data
```

<Info>
  You can authenticate with either an API key (`sigmic_...`) or a JWT token (`eyJ...`) from [Widget Authentication](/widget).
</Info>

### Form Fields

| Field           | Type    | Required | Default | Description                                                  |
| --------------- | ------- | -------- | ------- | ------------------------------------------------------------ |
| `message`       | string  | Yes      | -       | The task instruction or prompt                               |
| `systemPrompt`  | string  | No       | null    | Custom system prompt to prepend                              |
| `showInHistory` | boolean | No       | true    | Whether to show this task in conversation history            |
| `autoExecute`   | boolean | No       | true    | Automatically approve tool executions                        |
| `files`         | file\[] | No       | -       | Files to upload (max 20 files, 50MB each)                    |
| `env`           | object  | No       | null    | Non-sensitive environment variables (stored with task)       |
| `secrets`       | object  | No       | null    | Sensitive environment variables (never stored, never logged) |

### Environment Variables

Both `env` and `secrets` accept key-value string maps. They are injected into the sandbox as `process.env` variables and as MCP server `context` for `{{mcp.KEY}}` template resolution.

* **`env`** — Non-sensitive config (tenant IDs, feature flags). Stored with the task and returned in GET responses for debugging.
* **`secrets`** — Sensitive credentials (API tokens, database URLs). **Never stored**, never logged, never returned in any response.
* Keys must be valid env var names: letters, digits, and underscores, starting with a letter or underscore.
* If the same key appears in both, `secrets` takes precedence.

<Note>
  When using `env` or `secrets`, send the request as `application/json` instead of `multipart/form-data`. File uploads require `multipart/form-data` and cannot be combined with `env`/`secrets` in the same request.
</Note>

### File Upload Notes

* **ZIP files** are automatically extracted into the workspace
* Files are uploaded to the workspace `uploads/` directory
* File paths are included in the context sent to the agent
* Maximum **20 files** per request
* Maximum **50MB** per file

## Response

Returns JSON with the task ID. Execution starts in the background.

```json theme={null}
{
  "success": true,
  "data": {
    "id": "c37c1d78-4d23-4e53-949a-ddd775f25e01",
    "status": "pending"
  }
}
```

| Field    | Type   | Description                |
| -------- | ------ | -------------------------- |
| `id`     | string | Unique task identifier     |
| `status` | string | Initial status (`pending`) |

After receiving the task ID, connect to `GET /api/v1/tasks/:id/stream` to receive real-time execution events including history replay and live streaming.

## Examples

### Basic Task

<CodeGroup>
  ```bash cURL theme={null}
  # 1. Create the task
  RESPONSE=$(curl -s -X POST https://api.sigmic.ai/api/v1/tasks \
    -H "Authorization: Bearer sigmic_your_key_here" \
    -F "message=What is the capital of France?")

  echo $RESPONSE
  # {"success":true,"data":{"id":"c37c1d78-...","status":"pending"}}

  # 2. Stream the execution
  TASK_ID=$(echo $RESPONSE | jq -r '.data.id')
  curl -N https://api.sigmic.ai/api/v1/tasks/$TASK_ID/stream \
    -H "Authorization: Bearer sigmic_your_key_here"
  ```

  ```javascript JavaScript theme={null}
  // 1. Create the task
  const formData = new FormData();
  formData.append('message', 'What is the capital of France?');

  const createResponse = await fetch('https://api.sigmic.ai/api/v1/tasks', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer sigmic_your_key_here' },
    body: formData
  });

  const { data: { id: taskId } } = await createResponse.json();
  console.log('Task ID:', taskId);

  // 2. Stream the execution
  const streamResponse = await fetch(
    `https://api.sigmic.ai/api/v1/tasks/${taskId}/stream`,
    { headers: { 'Authorization': 'Bearer sigmic_your_key_here' } }
  );

  const reader = streamResponse.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    console.log(decoder.decode(value));
  }
  ```

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

  # 1. Create the task
  response = requests.post(
      'https://api.sigmic.ai/api/v1/tasks',
      headers={'Authorization': 'Bearer sigmic_your_key_here'},
      data={'message': 'What is the capital of France?'}
  )

  task_id = response.json()['data']['id']
  print(f'Task ID: {task_id}')

  # 2. Stream the execution
  stream = requests.get(
      f'https://api.sigmic.ai/api/v1/tasks/{task_id}/stream',
      headers={'Authorization': 'Bearer sigmic_your_key_here'},
      stream=True
  )

  for line in stream.iter_lines():
      if line:
          print(line.decode('utf-8'))
  ```
</CodeGroup>

### With File Upload

<CodeGroup>
  ```bash cURL theme={null}
  RESPONSE=$(curl -s -X POST https://api.sigmic.ai/api/v1/tasks \
    -H "Authorization: Bearer sigmic_your_key_here" \
    -F "message=Analyze this CSV file and summarize the data" \
    -F "files=@data.csv")

  TASK_ID=$(echo $RESPONSE | jq -r '.data.id')
  curl -N https://api.sigmic.ai/api/v1/tasks/$TASK_ID/stream \
    -H "Authorization: Bearer sigmic_your_key_here"
  ```

  ```javascript JavaScript theme={null}
  const formData = new FormData();
  formData.append('message', 'Analyze this CSV file and summarize the data');
  formData.append('files', fileInput.files[0]);

  const createResponse = await fetch('https://api.sigmic.ai/api/v1/tasks', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer sigmic_your_key_here' },
    body: formData
  });

  const { data: { id: taskId } } = await createResponse.json();
  // Connect to stream...
  ```

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

  with open('data.csv', 'rb') as f:
      response = requests.post(
          'https://api.sigmic.ai/api/v1/tasks',
          headers={'Authorization': 'Bearer sigmic_your_key_here'},
          data={'message': 'Analyze this CSV file and summarize the data'},
          files={'files': f}
      )

  task_id = response.json()['data']['id']
  # Connect to stream...
  ```
</CodeGroup>

### With Manual Tool Approval

Set `autoExecute=false` to review tool calls before they execute:

```bash theme={null}
RESPONSE=$(curl -s -X POST https://api.sigmic.ai/api/v1/tasks \
  -H "Authorization: Bearer sigmic_your_key_here" \
  -F "message=List all files in the current directory" \
  -F "autoExecute=false")

TASK_ID=$(echo $RESPONSE | jq -r '.data.id')
```

When a tool call requires approval, the stream will emit a `tool_call` event with `status: awaiting_approval`. You can also poll `GET /api/v1/tasks/:id` and check the `pendingApprovals` array. Use the [Approve Tool Call](/tasks/approve) endpoint to approve or reject it.

### With Environment Variables

Inject credentials and configuration into the sandbox:

<CodeGroup>
  ```bash cURL theme={null}
  curl -s -X POST https://api.sigmic.ai/api/v1/tasks \
    -H "Authorization: Bearer sigmic_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "message": "Query the database and generate a report",
      "env": { "TENANT_ID": "acme-corp", "REPORT_FORMAT": "csv" },
      "secrets": { "DATABASE_URL": "postgres://user:pass@host/db" }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.sigmic.ai/api/v1/tasks', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sigmic_your_key_here',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      message: 'Query the database and generate a report',
      env: { TENANT_ID: 'acme-corp', REPORT_FORMAT: 'csv' },
      secrets: { DATABASE_URL: 'postgres://user:pass@host/db' }
    })
  });
  ```

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

  response = requests.post(
      'https://api.sigmic.ai/api/v1/tasks',
      headers={
          'Authorization': 'Bearer sigmic_your_key_here',
          'Content-Type': 'application/json'
      },
      json={
          'message': 'Query the database and generate a report',
          'env': {'TENANT_ID': 'acme-corp', 'REPORT_FORMAT': 'csv'},
          'secrets': {'DATABASE_URL': 'postgres://user:pass@host/db'}
      }
  )
  ```
</CodeGroup>

The agent's sandbox will have `TENANT_ID`, `REPORT_FORMAT`, and `DATABASE_URL` available as `process.env` variables. MCP servers configured with `{{mcp.DATABASE_URL}}` in their headers will have the value resolved automatically.

### With Custom System Prompt

```bash theme={null}
curl -s -X POST https://api.sigmic.ai/api/v1/tasks \
  -H "Authorization: Bearer sigmic_your_key_here" \
  -F "message=Write a greeting" \
  -F "systemPrompt=You are a helpful assistant that always responds in Spanish."
```

## Errors

| Code               | Description                                                 |
| ------------------ | ----------------------------------------------------------- |
| `AUTH_REQUIRED`    | No authentication provided                                  |
| `INVALID_API_KEY`  | Invalid or expired API key                                  |
| `VALIDATION_ERROR` | Missing or invalid `message` field, or invalid env var name |
| `EXECUTION_ERROR`  | Task execution failed                                       |
