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

# Run Expert

> POST /v1/agents/run — Invoke a Profy Expert and receive an SSE streaming response

Invoke a Profy Expert (AI Agent) and receive a complete response via SSE streaming, including text output, tool calls, and token usage.

```
POST https://api.profy.cn/v1/agents/run
```

## Authentication

<ParamField header="Authorization" type="string" required>
  `Bearer sk-pro-xxxx` (API Key) or `Bearer <access_token>` (OAuth)
</ParamField>

## Request Body

<ParamField body="expert_identifier" type="string" required>
  The Expert's unique identifier. You can find it on the Expert's marketplace page or in Studio.
</ParamField>

<ParamField body="message" type="string" required>
  The message content to send to the Expert.
</ParamField>

<ParamField body="session_id" type="string">
  Session ID for multi-turn conversations. Not required for the first call — a new session\_id is returned in the `X-Session-Id` response header.
</ParamField>

<ParamField body="model" type="string">
  Specify the model to use. Defaults to the platform's default model if not provided. Use `GET /v1/models` to query available models.
</ParamField>

## Request Examples

<CodeGroup>
  ```python Python theme={null}
  from profy import Profy

  async with Profy(api_key="sk-pro-your-key") as client:
      result = await client.agents.run(
          "my-expert",
          "Help me analyze the performance issues in this code",
          session_id="existing-session-id",  # optional
          model="deepseek-v3",               # optional
      )
      print(result.text)
      print(f"Tool calls: {[t.name for t in result.tool_calls]}")
  ```

  ```typescript TypeScript theme={null}
  import { Profy } from "@profy-ai/sdk";

  const client = new Profy({ apiKey: "sk-pro-your-key" });

  const result = await client.agents.run(
    "my-expert",
    "Help me analyze the performance issues in this code",
    {
      sessionId: "existing-session-id",
      model: "deepseek-v3",
    }
  );

  console.log(result.text);
  console.log("Tool calls:", result.toolCalls.map(t => t.name));
  ```

  ```bash curl theme={null}
  curl -X POST https://api.profy.cn/v1/agents/run \
    -H "Authorization: Bearer sk-pro-your-key" \
    -H "Content-Type: application/json" \
    -d '{
      "expert_identifier": "my-expert",
      "message": "Help me analyze the performance issues in this code"
    }'
  ```
</CodeGroup>

## Response Format

The response is an SSE (Server-Sent Events) stream with hierarchical dot-notation event names (aligned with the OpenAI Responses API). The response headers include `X-Session-Id` for subsequent multi-turn conversations.

```
event: run.in_progress
data: {"type":"run.in_progress","model_name":"deepseek-v3","session_id":"ses_abc123","event_id":2}
```

## SSE Event Types

### Lifecycle Events

| Event             | Description           | Key Fields                 |
| ----------------- | --------------------- | -------------------------- |
| `run.created`     | Agent run created     | `event_id`                 |
| `run.in_progress` | Agent started running | `model_name`, `session_id` |
| `run.completed`   | Agent run completed   | `event_id`                 |
| `run.failed`      | Agent run failed      | `message`                  |

### Output Events

| Event                   | Description                                   | Key Fields |
| ----------------------- | --------------------------------------------- | ---------- |
| `output.text.delta`     | Incremental text output                       | `delta`    |
| `output.thinking.delta` | Chain-of-thought increment (reasoning models) | `delta`    |

### Tool Call Events

| Event                       | Description             | Key Fields                  |
| --------------------------- | ----------------------- | --------------------------- |
| `tool_call.created`         | Tool call started       | `tool_name`, `tool_call_id` |
| `tool_call.arguments.delta` | Tool argument increment | `delta`                     |
| `tool_call.completed`       | Tool call completed     | `tool_name`, `result`       |
| `tool_call.failed`          | Tool call failed        | `tool_name`, `error`        |

### Usage Events

| Event                   | Description            | Key Fields                      |
| ----------------------- | ---------------------- | ------------------------------- |
| `usage.token`           | Token usage statistics | `input_tokens`, `output_tokens` |
| `usage.trial_exhausted` | Trial uses exhausted   | `message`                       |

## Streaming Examples

<CodeGroup>
  ```python Python (streaming) theme={null}
  from profy import Profy

  async with Profy(api_key="sk-pro-your-key") as client:
      async for chunk in client.agents.run_stream("my-expert", "Hello"):
          match chunk.type:
              case "run.in_progress":
                  print(f"Session: {chunk.raw.get('session_id')}")
              case "output.text.delta":
                  print(chunk.delta, end="", flush=True)
              case "tool_call.created":
                  print(f"\nTool call: {chunk.raw.get('tool_name')}")
              case "run.completed":
                  print("\n--- Done ---")
              case "run.failed":
                  print(f"\nError: {chunk.raw.get('message')}")
  ```

  ```typescript TypeScript (streaming) theme={null}
  import { Profy } from "@profy-ai/sdk";

  const client = new Profy({ apiKey: "sk-pro-your-key" });

  for await (const chunk of client.agents.runStream("my-expert", "Hello")) {
    switch (chunk.type) {
      case "run.in_progress":
        console.log(`Session: ${chunk.raw.session_id}`);
        break;
      case "output.text.delta":
        process.stdout.write(chunk.delta ?? "");
        break;
      case "tool_call.created":
        console.log(`\nTool call: ${chunk.raw.tool_name}`);
        break;
      case "run.completed":
        console.log("\n--- Done ---");
        break;
    }
  }
  ```

  ```bash curl (raw SSE) theme={null}
  curl -N -X POST https://api.profy.cn/v1/agents/run \
    -H "Authorization: Bearer sk-pro-your-key" \
    -H "Content-Type: application/json" \
    -H "Accept: text/event-stream" \
    -d '{"expert_identifier":"my-expert","message":"Hello"}'
  ```
</CodeGroup>

## Billing

Billed by token usage (METERED), with credits deducted from the caller's account. Refer to the real-time rates displayed in the product. You can obtain the token consumption for each call from the `usage.token` event.

## Error Codes

| HTTP Status Code | Description                                                  |
| ---------------- | ------------------------------------------------------------ |
| `400`            | Missing or invalid request parameters                        |
| `401`            | Authentication failed (invalid API Key or expired token)     |
| `403`            | Expert access denied (not purchased or trial uses exhausted) |
| `404`            | Expert does not exist or is not published                    |
| `502`            | Agent Runtime upstream error                                 |
| `504`            | Agent Runtime timeout                                        |

## Next Steps

<CardGroup cols={2}>
  <Card title="Chat Completions" icon="comments" href="/en/developers/api/chat-completions">
    OpenAI-compatible chat completions endpoint
  </Card>

  <Card title="Python SDK" icon="python" href="/en/developers/sdk-python">
    Complete Python SDK guide
  </Card>
</CardGroup>
