---
title: "Create Chat Task"
method: POST
path: "/v1/chat/tasks"
tags: ["sdk-v1"]
---

# Create Chat Task

`POST /v1/chat/tasks`

Create a new SDK-driven task and kick off its first turn.

Single endpoint does three things atomically from the caller's
perspective:

  1. Verifies the body's ``agent_id`` matches the agent bound to
     the presented API key. Mismatch -> 404 ``agent_not_found``
     (404 not 403, so the existence of unrelated agents isn't
     leaked via error code).
  2. Persists a new :class:`Task` row owned by the agent's user,
     with ``source='sdk'`` and ``input`` set to the user message.
     Also persists the first user message to
     ``task_chat_messages`` so the existing background execution
     path can consume it without special-casing this entry point.
  3. Schedules background execution via
     ``start_task_in_background`` (which uses the same coroutine
     the WebSocket handler does). Returns 202 immediately --
     callers poll ``GET /v1/chat/tasks/{task_id}`` to observe the
     eventual ``completed`` / ``failed`` status.

Args:
    request: Validated :class:`CreateTaskRequest`. ``message.content``
        is guaranteed non-empty by Pydantic; ``agent_id`` is the
        target agent the SDK caller wants to invoke.
    authed: ``(Agent, AgentApiKey)`` tuple resolved by the auth
        dependency. The agent here is the *key-bound* agent, the
        single source of truth for what this caller may touch.
    db: SQLAlchemy session.

Returns:
    :class:`CreateTaskResponse` with the new ``task_id``,
    ``agent_id``, ``status='running'`` (the atomic claim inside
    the handler flips the row from PENDING to RUNNING before the
    response is sent), and ``created_at`` for the caller to
    start polling from.

Raises:
    V1ApiError 401: missing/invalid/revoked key (raised inside
        ``get_agent_from_api_key``; envelope is uniform with
        other auth failures).
    V1ApiError 404: ``request.agent_id != authed_agent.id``.
    500 (V1 envelope): any unexpected exception -- the global
        handler in ``web/app.py`` translates to
        ``{"error": {"code": "internal_error", ...}}`` and the raw
        exception message stays out of the response.

## Request body

- CreateTaskRequest — Body for ``POST /v1/chat/tasks``. ``agent_id`` is required and must match the agent bound to the presented API key; the server enforces ``body.agent_id == authed.agent.id`` and returns 404 ``agent_not_found`` on mismatch.
  - `agent_id` integer, required — Target agent's primary key. Must match the agent the presented API key is bound to.
  - `message` MessageBody, required — One chat message in the SDK request body. Currently the SDK surface only accepts ``role='user'`` -- the SDK is for SaaS clients pushing user input, not for replaying transcripts. Future-proofed as a string so we don't have to break the wire shape when adding ``system`` / ``function`` later.
    - `role` 'user' — Currently must be 'user'. Reserved as a field for future expansion (system / function roles) without breaking the wire shape.
    - `content` string, required — The user's message text. Must be non-empty.
  - `metadata` object, nullable — Free-form correlation data the SDK caller can pass through (trace_id, request_id, etc). Not interpreted server-side.

## Response `202`

Successful Response

- CreateTaskResponse — ``POST /v1/chat/tasks`` -> 202 Accepted response. The task has been persisted, claimed as RUNNING in the same transaction, and queued for background execution; callers poll ``GET /v1/chat/tasks/{task_id}`` to observe the transition running -> completed/failed.
  - `task_id` integer, required — Newly created task primary key.
  - `agent_id` integer, required — Agent the task is bound to.
  - `status` string, required — Initial status, 'running' in the 202 response (the atomic claim inside POST commits the status flip before the response is sent). Use GET /v1/chat/tasks/{task_id} to observe later transitions.
  - `created_at` string, date-time, required — UTC creation timestamp.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/xorbitsai/apis/xagent.md) · [All operations](https://skmtc.net/xorbitsai/apis/xagent/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/xorbitsai/xagent/revisions/33e4ba4936ad/schema)
