# APIの使用

## APIバージョン

このサービスでは、キュー設定に基づいて2種類のAPIバージョンを利用できます。

* `/api/v2/` – キュー有効 (デフォルト): 非同期処理方式でリクエストが失われません
* `/api/v1/` – キュー無効 (v17.1.6以前): 同期方式で直接実行します

{% hint style="info" %}
v2のキューAPIはコマンダー17.1.7で追加されました (リリース日: 2025年8月28日)。
{% endhint %}

## リクエストキューシステム (API v2)

キューが有効な場合(デフォルト)、サービスは非同期リクエストキューを利用し、次の特長を備えています。

* 順次処理: リクエストはFIFO順に1件ずつ処理
* リクエスト追跡: 各リクエストに固有IDを付与し、状態を確認可能
* リクエスト喪失防止: すべてのリクエストがキューに登録され確実に処理
* 結果取得: リクエストIDを使って非同期で結果を取得

### キューAPIエンドポイント

リクエスト送信 (非同期)

```
curl -X POST 'http://localhost:<port>/api/v2/executecommand-async' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{"command": "tree"}'
```

応答 (202 Accepted)

```json
{
    "success": true,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "queued",
    "message": "Request queued successfully. Use /api/v2/status/<request_id> to check progress, /api/v2/result/<request_id> to get results, or /api/v2/queue/status for queue info."
}
```

リクエスト状態の確認

```
curl 'http://localhost:<port>/api/v2/status/<request_id>' \
--header 'api-key: <your-api-key>'
```

応答

```json
{
    "success": true,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "command": "tree",
    "status": "completed",
    "created_at": "2024-01-15T10:30:00.000000",
    "started_at": "2024-01-15T10:30:01.000000",
    "completed_at": "2024-01-15T10:30:03.000000"
}
```

結果の取得

```
curl 'http://localhost:<port>/api/v2/result/<request_id>' \
--header 'api-key: <your-api-key>'
```

応答 (完了済みリクエストの場合、api/v1 の直接実行と同様)

```
{
    "result": "...",
    "status": "success"
}
```

キュー状態の取得

```
curl 'http://localhost:<port>/api/v2/queue/status' \
--header 'api-key: <your-api-key>'
```

応答

```json
{
    "success": true,
    "queue_size": 3,
    "active_requests": 5,
    "completed_requests": 12,
    "currently_processing": "550e8400-e29b-41d4-a716-446655440000",
    "worker_running": true
}
```

### リクエスト状態

* `queued` - リクエストを受け付けてキューで待機中
* `processing` - 実行中
* `completed` - 正常に完了
* `failed` - 実行エラー
* `expired` - 期限内に処理されずタイムアウト

### キュー設定

キューシステムは以下のように構成されています。

```yaml
queue_max_size: 100          # キューに登録できる最大リクエスト数
request_timeout: 300         # リクエストのタイムアウト (5 分)
result_retention: 3600       # 結果の保持期間 (1 時間)
```

### エラー応答

* **503 Service Unavailable** - キューが満杯
* **404 Not Found** - リクエスト ID が存在しない
* **500 Internal Server Error** - コマンド実行エラー
* **429 Too Many Requests** - レート制限に達した

***

## 直接実行 (API v1)

キューが無効の場合は、従来の同期エンドポイントを使用します。

```
curl --location 'http://localhost:<port>/api/v1/executecommand' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{
    "command": "tree"
}'
```

Ngrokを使用する場合のCurl コマンド

```
curl --location 'http://<your-ngrok-url>/api/v1/executecommand' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{
    "command": "tree"
}'
```

Cloudflareを使用する場合のCurlコマンド

```
curl --location 'http://<your-cloudflare-url>/api/v1/executecommand' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{
    "command": "tree"
}'
```

### ファイル入力パラメータ (FILEDATA)

ファイル入力が必要なコマンドでは、`filedata` フィールドに JSON を渡し、ファイル名として `FILEDATA` を指定できます。物理ファイルのアップロードを行わずに、REST API を通じてファイルベース処理を実行できます。

#### FILEDATAの例

PAMプロジェクトのインポート

```
curl -X POST 'http://localhost:<port>/api/v2/executecommand-async' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{
  "command": "pam project import --filename=FILEDATA --name=\"My PAM Project\"",
  "filedata": {
    "project": "My PAM Project",
    "pam_data": {
      "resources": [
        {
          "type": "pamDirectory",
          "title": "Domain Controller",
          "directory_type": "active_directory",
          "host": "dc.example.com",
          "port": "636",
          "use_ssl": true,
          "domain_name": "example.com"
        }
      ]
    }
  }
}'
```

インポートコマンド

```
curl -X POST 'http://localhost:<port>/api/v2/executecommand-async' \
--header 'Content-Type: application/json' \
--header 'api-key: <your-api-key>' \
--data '{
  "command": "import FILEDATA --format=json",
  "filedata": {
    "records": [
      {
        "title": "My Website",
        "login": "user@example.com",
        "password": "MyPassword123!"
      }
    ]
  }
}'
```

### FILEDATA の特長

* Automatic Processing: 手作業でファイルを扱う必要なし
* Temporary File Management: 一時ファイルの作成と削除をサービス側で自動処理
* Security: 機密データがログで自動マスクされるため安全
* Error Handling: エラー発生時も確実にクリーンアップ
* Both API Versions: `/api/v1/executecommand` と `/api/v2/executecommand-async` の両方で利用可能

### Postman

Postmanアプリからもリクエストを送信できます。`Content-Type` ヘッダと `api-key` ヘッダを設定してください。以下は参考画像です。

<figure><img src="/files/2h72O3lQHAT4sMIh7sKF" alt=""><figcaption><p>PostmanにおけるHTTPボディ設定</p></figcaption></figure>

<figure><img src="/files/PuFE9Q2QDKla1J8oC6jz" alt=""><figcaption><p>Postmanでのヘッダ構成</p></figcaption></figure>

<figure><img src="/files/7YKhUFey9TIuQSzO195o" alt=""><figcaption><p>Postmanでv2APIのリクエストとレスポンス構造を確認する方法</p></figcaption></figure>

api/v1 の全レスポンス、および api/v2 の結果取得は共通の基本形式を使用します。

```
{ "command": "<command_name>", "data": <command_specific_data>, "status": "success" }
```

### コマンドごとの応答について

一部のコマンドはJSON形式で見やすく整形されるよう変更されています。その他のコマンドはコマンダー CLIと同じ形式でデータを返します。

#### 整形済み出力の例

list (ls) コマンド

{% code overflow="wrap" %}

```
{ "status": "success", "command": "ls", "data": { "folders": [ { "number": 1, "uid": "folder_uid_string", "name": "My Folder", "flags": "RW" } ], "records": [ { "number": 1, "uid": "record_uid_string", "type": "login", "title": "My Login", "description": "Optional description" } ] } }
```

{% endcode %}

tree コマンド

{% code overflow="wrap" %}

```
{ "status": "success", "command": "tree", "data": [ { "level": 0, "name": "Root Folder", "path": "Root Folder" }, { "level": 1, "name": "Subfolder", "path": "Root Folder/Subfolder" } ] }
```

{% endcode %}

mkdir コマンド

{% code overflow="wrap" %}

```
{ "status": "success", "command": "mkdir", "data": { "folder_uid": "new_folder_uid_string" } }
```

{% endcode %}

record-add コマンド

{% code overflow="wrap" %}

```
{ "status": "success", "command": "record-add", "data": { "record_uid": "new_record_uid_string" } }
```

{% endcode %}

search record コマンド

{% code overflow="wrap" %}

```
{ "status": "success", "command": "search record", "data": [ { "number": 1, "uid": "record_uid_string", "type": "login", "title": "Matching Record", "description": "Optional description" } ] }
```

{% endcode %}

search folder コマンド

{% code overflow="wrap" %}

```
{ "status": "success", "command": "search folder", "data": [ { "number": 1, "uid": "folder_uid_string", "name": "Matching Folder" } ] }
```

{% endcode %}

get コマンド

{% code overflow="wrap" %}

```
{ "command": "get", "data": { "attachments": "service_config.yaml 537b ID: XYZ", "last_modified": "2025-01-18 15:35:21", "share_admins": "xyz@email.com", "shared": "False", "shared_users": "xyz@email.com (Owner)", "title": "Commander Service Mode", "type": "", "uid": "folder_uid_string" }, "status": "success" }
```

{% endcode %}

\--format=json を有効化したコマンド (例: audit-report --format=json)

{% code overflow="wrap" %}

```
{ "status": "success", "command": "audit-report", "data": [ { "audit_event_type": "open_record", "created": "2025-02-18T10:30:45+00:00", "geo_location": "New York, NY, US", "ip_address": "192.168.1.100", "keeper_version": "Commander 16.11.0", "message": "User john.doe@example.com opened record UID ABCD1234EFGH5678", "username": "john.doe@example.com" } ] }
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keeper.io/keeperpam/jp/commander-cli/service-mode-rest-api/api-usage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
