# API Usage

### API Versions

The service provides two API versions based on queue configuration:

* **`/api/v2/`** - Queue enabled (default): Asynchronous request processing with no request loss
* **`/api/v1/`** - Queue disabled (v17.1.6 and older): Direct synchronous execution

{% hint style="info" %}
The v2 queue API was introduced in Commander 17.1.7 with release date Aug 28 2025
{% endhint %}

### **Request Queue System (API v2)**

When queue is enabled (default), the service uses an asynchronous request queue system that provides:

* **Sequential Processing**: Requests are processed one at a time in FIFO order
* **Request Tracking**: Each request receives a unique ID for status tracking
* **No Dropped Requests**: All requests are queued and processed
* **Result Retrieval**: Asynchronous result retrieval using request IDs

#### **Queue API Endpoints**

***Submit Request (Async):***

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

*Response (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."
}
```

***Check Request Status:***

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

*Response:*

```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"
}
```

***Get Request Result:***

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

*Response (for completed request) (similar to direct execution via api/v1/executecommand):*

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

***Get Queue Status:***

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

*Response:*

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

#### **Request States**

* `queued` - Request accepted and waiting in queue
* `processing` - Currently being executed
* `completed` - Successfully completed
* `failed` - Execution failed
* `expired` - Request timed out before processing

#### **Queue Configuration**

The queue system is configured as:

```yaml
queue_max_size: 100          # Maximum queued requests
request_timeout: 300         # Request timeout (5 minutes)
result_retention: 3600       # Result retention (1 hour)
```

#### **Error Responses**

* **503 Service Unavailable**: Queue is full
* **404 Not Found**: Request ID not found
* **500 Internal Server Error**: Command execution failed
* **429 Too Many Requests**: Rate limit exceeded

***

### **Direct Execution (API v1)**

When queue is disabled, use the legacy synchronous endpoint:

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

If you're using Ngrok, the Curl command will be:

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

If you're using Cloudflare, the Curl command will be:

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

#### **File Input Parameters (FILEDATA)**

Commands requiring file input can use the `FILEDATA` placeholder with JSON content sent in the `filedata` field. This feature enables seamless file-based operations through the REST API without requiring physical file uploads.

**FILEDATA Examples**

**PAM Project Import:**

```bash
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"
        }
      ]
    }
  }
}'
```

**Import Command:**

```bash
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 Features**

* **Automatic Processing**: No manual file handling required
* **Temporary File Management**: Service handles file creation and cleanup automatically
* **Security**: Sensitive data automatically masked in logs for privacy
* **Error Handling**: Robust error handling with proper cleanup on failures
* **Both API Versions**: Works with both `/api/v1/executecommand` and `/api/v2/executecommand-async`

#### Postman

You can send requests through the Postman app. Just ensure that the Content-Type header and api-key header is provided. Example screenshot below:

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FqFYoWXHv5wfkIZIwdGgI%2FScreenshot%202025-03-23%20at%205.09.47%E2%80%AFPM.png?alt=media&#x26;token=b4f8654b-7a40-4244-99c6-f27ac1cb64a7" alt=""><figcaption><p>HTTP Body Configuration in Postman</p></figcaption></figure>

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2F5kke9cceH6JAWq389XaO%2FScreenshot%202025-03-23%20at%205.10.39%E2%80%AFPM.png?alt=media&#x26;token=dd5bd3e4-fc62-4579-b548-7c1f832a4c73" alt=""><figcaption><p>Header Configuration in Postman</p></figcaption></figure>

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FvEySf18jygzWesjlEnhO%2FScreenshot%202025-09-08%20at%208.58.29%E2%80%AFPM.png?alt=media&#x26;token=2f8c532c-1da5-4b83-a285-0553d8c696aa" alt="HTTP Request and Response in v2 in Postman"><figcaption><p>Demonstrating v2 API Request/Response Structure in Postman</p></figcaption></figure>

All responses in api/v1 and get request result in api/v2 use this basic format:&#x20;

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

### Command Specific Responses

Some commands have been modified to return formatted JSON. Other commands will return data exactly as they normally do through the Commander CLI version.

Examples of modified output:

#### List Command (ls):

{ "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" } ] } }

#### Tree Command:

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

#### Make Directory Command (mkdir):

{ "status": "success", "command": "mkdir", "data": { "folder\_uid": "new\_folder\_uid\_string" } }

#### Record Add Command:

{ "status": "success", "command": "record-add", "data": { "record\_uid": "new\_record\_uid\_string" } }

#### Search Record Command:

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

#### Search Folder Command:

{ "status": "success", "command": "search folder", "data": \[ { "number": 1, "uid": "folder\_uid\_string", "name": "Matching Folder" } ] }

#### Get Command:

{ "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" }

#### Commands with --format = json enabled (e.g. audit-report --format=json):

{ "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>" } ] }
