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

# タスク一覧

> すべてのタスクの一覧表示

## エンドポイント

```
GET http://localhost:8080/api/v1/tasks
```

## 説明

ステータスとセッションによるオプションのフィルタリングを伴う、ページネートされたタスクのリストを取得します。

## 認証

**必要**: はい

ヘッダーにAPIキーを含めてください:

```
X-API-Key: sk_test_123456
```

## リクエスト

### ヘッダー

| ヘッダー        | 必要 | 説明   |
| ----------- | -- | ---- |
| `X-API-Key` | はい | 認証キー |

### クエリパラメータ

| パラメータ        | タイプ | 必要  | 説明                | デフォルト |
| ------------ | --- | --- | ----------------- | ----- |
| `limit`      | 整数  | いいえ | 返すタスクの数 (1-100)   | `20`  |
| `offset`     | 整数  | いいえ | スキップするタスクの数       | `0`   |
| `session_id` | 文字列 | いいえ | セッションIDでフィルタリング   | -     |
| `status`     | 文字列 | いいえ | タスクのステータスでフィルタリング | -     |

### ステータスフィルタ値

* `QUEUED` - 実行待ちのタスク
* `RUNNING` - 現在実行中のタスク
* `COMPLETED` - 成功裏に完了したタスク
* `FAILED` - 失敗したタスク
* `CANCELLED` または `CANCELED` - キャンセルされたタスク
* `TIMEOUT` - タイムアウトを超えたタスク

<Note>
  フィルター値は短縮形式を使用します（例：`RUNNING`）。レスポンスのstatusフィールドには`TASK_STATUS_`プレフィックスが含まれます（例：`TASK_STATUS_RUNNING`）。
</Note>

## レスポンス

### 成功レスポンス

**ステータス**: `200 OK`

**ボディ**:

```json theme={null}
{
  "tasks": [
    {
      "task_id": "string",
      "query": "string",
      "status": "string",
      "mode": "string",
      "created_at": "timestamp",
      "completed_at": "timestamp",
      "total_token_usage": {
        "total_tokens": 0,
        "cost_usd": 0.0,
        "prompt_tokens": 0,
        "completion_tokens": 0
      }
    }
  ],
  "total_count": 0
}
```

### レスポンスフィールド

| フィールド         | タイプ | 説明              |
| ------------- | --- | --------------- |
| `tasks`       | 配列  | タスクの概要の配列       |
| `total_count` | 整数  | フィルタに一致するタスクの総数 |

### タスク概要フィールド

| フィールド               | タイプ     | 説明                                                                                   |
| ------------------- | ------- | ------------------------------------------------------------------------------------ |
| `task_id`           | 文字列     | 一意のタスク識別子                                                                            |
| `query`             | 文字列     | 元のタスククエリ                                                                             |
| `status`            | 文字列     | 現在のタスクステータス                                                                          |
| `mode`              | 文字列     | 実行モード (`EXECUTION_MODE_SIMPLE`, `EXECUTION_MODE_STANDARD`, `EXECUTION_MODE_COMPLEX`) |
| `created_at`        | タイムスタンプ | タスク作成時間 (ISO 8601)                                                                   |
| `completed_at`      | タイムスタンプ | タスク完了時間 (未完了の場合はnull)                                                                |
| `total_token_usage` | オブジェクト  | トークン使用量とコストのメトリクス                                                                    |

<Note>
  リスト応答の`mode`フィールドは`EXECUTION_MODE_`プレフィックスを使用します（例：`EXECUTION_MODE_STANDARD`）。単一タスクGETエンドポイントは短縮形式を返します（例：`standard`）。
</Note>

### トークン使用量フィールド

| フィールド               | タイプ   | 説明           |
| ------------------- | ----- | ------------ |
| `total_tokens`      | 整数    | 消費されたトークンの総数 |
| `cost_usd`          | 浮動小数点 | USDでの総コスト    |
| `prompt_tokens`     | 整数    | プロンプト内のトークン  |
| `completion_tokens` | 整数    | 完了内のトークン     |

## 例

### すべてのタスクをリスト

```bash theme={null}
curl -X GET "http://localhost:8080/api/v1/tasks" \
  -H "X-API-Key: sk_test_123456"
```

**レスポンス**:

```json theme={null}
{
  "tasks": [
    {
      "task_id": "task_01HQZX3Y9K8M2P4N5S7T9W2V",
      "query": "What is the capital of France?",
      "status": "TASK_STATUS_COMPLETED",
      "mode": "EXECUTION_MODE_SIMPLE",
      "created_at": "2025-10-22T10:30:00Z",
      "completed_at": "2025-10-22T10:30:05Z",
      "total_token_usage": {
        "total_tokens": 150,
        "cost_usd": 0.0023,
        "prompt_tokens": 45,
        "completion_tokens": 105
      }
    },
    {
      "task_id": "task_01HQZX4Y9K8M2P4N5S7T9W2W",
      "query": "Analyze sales trends for Q4",
      "status": "TASK_STATUS_RUNNING",
      "mode": "EXECUTION_MODE_STANDARD",
      "created_at": "2025-10-22T10:31:00Z",
      "completed_at": null,
      "total_token_usage": null
    }
  ],
  "total_count": 2
}
```

### ステータスでフィルタリング

```bash theme={null}
# 実行中のタスクのみ取得
curl -X GET "http://localhost:8080/api/v1/tasks?status=RUNNING" \
  -H "X-API-Key: sk_test_123456"
```

```bash theme={null}
# 完了したタスクを取得
curl -X GET "http://localhost:8080/api/v1/tasks?status=COMPLETED" \
  -H "X-API-Key: sk_test_123456"
```

```bash theme={null}
# 失敗したタスクを取得
curl -X GET "http://localhost:8080/api/v1/tasks?status=FAILED" \
  -H "X-API-Key: sk_test_123456"
```

### セッションでフィルタリング

```bash theme={null}
curl -X GET "http://localhost:8080/api/v1/tasks?session_id=user-123-chat" \
  -H "X-API-Key: sk_test_123456"
```

**レスポンス**:

```json theme={null}
{
  "tasks": [
    {
      "task_id": "task_abc123",
      "query": "What is Python?",
      "status": "TASK_STATUS_COMPLETED",
      "created_at": "2025-10-22T10:00:00Z",
      "completed_at": "2025-10-22T10:00:03Z"
    },
    {
      "task_id": "task_def456",
      "query": "What are its main advantages?",
      "status": "TASK_STATUS_COMPLETED",
      "created_at": "2025-10-22T10:01:00Z",
      "completed_at": "2025-10-22T10:01:04Z"
    }
  ],
  "total_count": 2
}
```

### ページネーション

```bash theme={null}
# 最初のページ (20タスク)
curl -X GET "http://localhost:8080/api/v1/tasks?limit=20&offset=0" \
  -H "X-API-Key: sk_test_123456"

# 2ページ目
curl -X GET "http://localhost:8080/api/v1/tasks?limit=20&offset=20" \
  -H "X-API-Key: sk_test_123456"

# 3ページ目
curl -X GET "http://localhost:8080/api/v1/tasks?limit=20&offset=40" \
  -H "X-API-Key: sk_test_123456"
```

### 複合フィルタ

```bash theme={null}
# セッション内の完了したタスクをページネートして取得
curl -X GET "http://localhost:8080/api/v1/tasks?session_id=user-123&status=COMPLETED&limit=10&offset=0" \
  -H "X-API-Key: sk_test_123456"
```

## エラー応答

### 401 Unauthorized

```json theme={null}
{
  "error": "Unauthorized"
}
```

### 429 Too Many Requests

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

### 500 Internal Server Error

```json theme={null}
{
  "error": "Failed to list tasks: database error"
}
```

## コード例

### Python with httpx

```python theme={null}
import httpx

response = httpx.get(
    "http://localhost:8080/api/v1/tasks",
    headers={"X-API-Key": "sk_test_123456"},
    params={
        "status": "COMPLETED",
        "limit": 50,
        "offset": 0
    }
)

data = response.json()
print(f"Total: {data['total_count']} tasks")

for task in data["tasks"]:
    print(f"- {task['task_id']}: {task['status']}")
    if task['total_token_usage']:
        print(f"  Cost: ${task['total_token_usage']['cost_usd']:.4f}")
```

### Python - すべてのタスクをリスト (ページネーション)

```python theme={null}
import httpx

def list_all_tasks(api_key: str, status: str = None):
    """ページネーションを使用してすべてのタスクをリストします。"""
    all_tasks = []
    offset = 0
    limit = 100

    while True:
        response = httpx.get(
            "http://localhost:8080/api/v1/tasks",
            headers={"X-API-Key": api_key},
            params={
                "status": status,
                "limit": limit,
                "offset": offset
            }
        )

        data = response.json()
        tasks = data["tasks"]
        all_tasks.extend(tasks)

        # すべてのタスクを取得したか確認
        if len(tasks) < limit:
            break

        offset += limit

    return all_tasks

# 使用例
completed_tasks = list_all_tasks("sk_test_123456", status="COMPLETED")
print(f"Found {len(completed_tasks)} completed tasks")
```

### JavaScript/Node.js

```javascript theme={null}
const axios = require('axios');

async function listTasks(filters = {}) {
  try {
    const response = await axios.get(
      'http://localhost:8080/api/v1/tasks',
      {
        headers: {
          'X-API-Key': 'sk_test_123456'
        },
        params: {
          status: filters.status,
          session_id: filters.sessionId,
          limit: filters.limit || 20,
          offset: filters.offset || 0
        }
      }
    );

    console.log(`Total tasks: ${response.data.total_count}`);

    response.data.tasks.forEach(task => {
      console.log(`${task.task_id}: ${task.status}`);
    });

    return response.data;
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
    throw error;
  }
}

// 実行中のタスクをリスト
listTasks({ status: 'RUNNING' });

// セッション内のタスクをリスト
listTasks({ sessionId: 'user-123-chat', limit: 50 });
```

> 注: `session_id` フィルターは UUID または `external_id` を受け入れます。

### Bash スクリプト - 実行中のタスクを監視

```bash theme={null}
#!/bin/bash

API_KEY="sk_test_123456"
BASE_URL="http://localhost:8080"

echo "実行中のタスクを監視中..."

while true; do
  clear
  echo "=== 実行中のタスク ==="
  echo ""

  RESPONSE=$(curl -s "$BASE_URL/api/v1/tasks?status=RUNNING" \
    -H "X-API-Key: $API_KEY")

  TOTAL=$(echo $RESPONSE | jq -r '.total_count')
  echo "実行中の合計: $TOTAL"
  echo ""

  echo $RESPONSE | jq -r '.tasks[] | "\(.task_id): \(.query)"'

  sleep 5
done
```

### Go

```go theme={null}
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "net/url"
)

type ListTasksResponse struct {
    Tasks      []TaskSummary `json:"tasks"`
    TotalCount int32         `json:"total_count"`
}

type TaskSummary struct {
    TaskID      string  `json:"task_id"`
    Query       string  `json:"query"`
    Status      string  `json:"status"`
    Mode        string  `json:"mode"`
    CreatedAt   string  `json:"created_at"`
    CompletedAt *string `json:"completed_at"`
}

func listTasks(status string, limit, offset int) (*ListTasksResponse, error) {
    baseURL := "http://localhost:8080/api/v1/tasks"

    // クエリパラメータを構築
    params := url.Values{}
    if status != "" {
        params.Add("status", status)
    }
    params.Add("limit", fmt.Sprintf("%d", limit))
    params.Add("offset", fmt.Sprintf("%d", offset))

    reqURL := baseURL + "?" + params.Encode()

    req, _ := http.NewRequest("GET", reqURL, nil)
    req.Header.Set("X-API-Key", "sk_test_123456")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    var result ListTasksResponse
    json.NewDecoder(resp.Body).Decode(&result)

    return &result, nil
}

func main() {
    tasks, err := listTasks("COMPLETED", 10, 0)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }

    fmt.Printf("Total tasks: %d\n", tasks.TotalCount)
    for _, task := range tasks.Tasks {
        fmt.Printf("- %s: %s\n", task.TaskID, task.Status)
    }
}
```

## ユースケース

### 1. ダッシュボード - 最近のタスクを表示

```python theme={null}
def get_recent_tasks(api_key: str, limit: int = 10):
    """ダッシュボード用の最近のタスクを取得します。"""
    response = httpx.get(
        "http://localhost:8080/api/v1/tasks",
        headers={"X-API-Key": api_key},
        params={"limit": limit, "offset": 0}
    )
    return response.json()["tasks"]

recent = get_recent_tasks("sk_test_123456", limit=5)
for task in recent:
    print(f"{task['created_at']}: {task['query'][:50]}...")
```

### 2. コスト追跡

```python theme={null}
def calculate_session_cost(api_key: str, session_id: str):
    """セッションの総コストを計算します。"""
    response = httpx.get(
        "http://localhost:8080/api/v1/tasks",
        headers={"X-API-Key": api_key},
        params={"session_id": session_id, "limit": 100}
    )

    total_cost = 0
    for task in response.json()["tasks"]:
        if task["total_token_usage"]:
            total_cost += task["total_token_usage"]["cost_usd"]

    return total_cost

cost = calculate_session_cost("sk_test_123456", "user-123-chat")
print(f"セッションコスト: ${cost:.4f}")
```

### 3. 失敗監視

```python theme={null}
import time

def monitor_failures(api_key: str, interval: int = 60):
    """失敗したタスクを監視します。"""
    while True:
        response = httpx.get(
            "http://localhost:8080/api/v1/tasks",
            headers={"X-API-Key": api_key},
            params={"status": "FAILED", "limit": 10}
        )

        failed_tasks = response.json()["tasks"]

        if failed_tasks:
            print(f"⚠️  {len(failed_tasks)} 件の失敗したタスク:")
            for task in failed_tasks:
                print(f"  - {task['task_id']}: {task['query']}")

                # 詳細を取得
                details = httpx.get(
                    f"http://localhost:8080/api/v1/tasks/{task['task_id']}",
                    headers={"X-API-Key": api_key}
                )
                error = details.json().get("error", "不明なエラー")
                print(f"    エラー: {error}")

        time.sleep(interval)

monitor_failures("sk_test_123456")
```

## 実装ノート

### レート制限

このエンドポイントはレート制限されています。デフォルトの制限:

* **APIキーごとに60リクエスト/分**
* **バーストで20リクエスト/秒**

### パフォーマンス

* **インデックス付きクエリ**: `status` と `session_id` でのフィルタリングは高速です
* **ページネーション**: 大きなレスポンスを避けるために `limit` と `offset` を使用します
* **総カウント**: 返されたページだけでなく、すべての一致するタスクを含みます

### 並び順

タスクは **逆時系列順**（最新が最初）で返されます。

## ベストプラクティス

### 1. ページネーションを使用する

大きな結果セットの場合は常にページネーションを行います:

```python theme={null}
def fetch_page(offset, limit=20):
    return httpx.get(
        "http://localhost:8080/api/v1/tasks",
        headers={"X-API-Key": "sk_test_123456"},
        params={"limit": limit, "offset": offset}
    ).json()

# 最初の3ページを取得
for page in range(3):
    tasks = fetch_page(offset=page * 20, limit=20)
    process_tasks(tasks)
```

### 2. ステータスでフィルタリング

特定のステータスのみが必要な場合は、すべてのタスクを取得しないでください:

```python theme={null}
# ✅ 良い - サーバー側でフィルタリング
running = httpx.get(..., params={"status": "RUNNING"})

# ❌ 悪い - クライアント側でフィルタリング
all_tasks = httpx.get(...)
running = [t for t in all_tasks if t["status"] == "RUNNING"]
```

### 3. 結果をキャッシュする

ダッシュボード用にタスクリストをキャッシュします:

```python theme={null}
import time

cache = {"data": None, "timestamp": 0}

def get_cached_tasks():
    now = time.time()
    if cache["data"] is None or now - cache["timestamp"] > 60:
        # 60秒ごとに更新
        response = httpx.get(...)
        cache["data"] = response.json()
        cache["timestamp"] = now

    return cache["data"]
```

## 関連エンドポイント

<CardGroup cols={2}>
  <Card title="タスクを送信" icon="paper-plane" href="/ja/api/rest/submit-task">
    POST /api/v1/tasks
  </Card>

  <Card title="タスクのステータスを取得" icon="circle-info" href="/ja/api/rest/get-status">
    GET /api/v1/tasks/{id}
  </Card>

  <Card title="イベントをストリーム" icon="stream" href="/ja/api/rest/streaming">
    リアルタイム監視
  </Card>

  <Card title="Python SDK" icon="python" href="/ja/sdk/python/quickstart">
    代わりにSDKを使用
  </Card>
</CardGroup>

## ノート

<Note>
  **SDKの代替**: Python SDKは `list_tasks()` メソッドを公開していません。このエンドポイントはREST専用です。SDKを使用する場合は、タスクIDを保存し、個別にステータスをクエリするために `client.get_status(task_id)` を使用してください。
</Note>
