---
title: "Create command definition"
method: POST
path: "/api/v2/devices/{id}/commands"
tags: ["Commands"]
---

# Create command definition

`POST /api/v2/devices/{id}/commands`

## Request

- Base URL: `https://api.kiloiot.io`
- URL: `https://api.kiloiot.io/api/v2/devices/{id}/commands`
- Auth: API key in header `X-API-Key` and API key in header `X-Organization-Id`

Create an actuator command definition on a digital device. Validation enforces mode/encoder/protocol constraints (direct = MQTT JSON payload, encoded = encoder pipeline).

**Required scope:** `commands:write`

## Path parameters

- `id` string, required

## Request body

- object
  - `organizationId` string, required: Organization ID
  - `command` object, required: Command definition.
    - `name` string, required
    - `description` string
    - `mode` 'direct' | 'encoded', required: direct = MQTT JSON payload; encoded = encoder pipeline.
    - `paramsSchema` object: Per-parameter JSON Schema subset, keyed by parameter name.
    - `encodedParamsTemplate` object: Template rendered into encoder input (encoded mode).
    - `directPayload` string: Raw JSON payload (direct mode).
    - `customEncoder` string: JavaScript encoder source (encoded mode).
    - `fPort` integer
    - `mqttTopic` string
    - `confirmed` boolean
    - `verificationStrategy` 'no_verification' | 'wait_next_uplink' | 'query_after_ack', required
    - `queryCommandId` string
    - `expectedSensorStates` object[]
      - `sensorId` string
      - `valueTemplate` string
    - `convergenceTimeout` integer

## Response `200`

Command created (HTTP 201)

- Command: A command definition stored under a digital device.
  - `id` string
  - `name` string
  - `description` string
  - `mode` 'direct' | 'encoded'
  - `paramsSchema` object: Per-parameter JSON Schema subset, keyed by parameter name.
  - `encodedParamsTemplate` object
  - `directPayload` string
  - `customEncoder` string
  - `fPort` integer
  - `mqttTopic` string
  - `confirmed` boolean
  - `verificationStrategy` 'no_verification' | 'wait_next_uplink' | 'query_after_ack'
  - `queryCommandId` string
  - `expectedSensorStates` object[]
    - `sensorId` string
    - `valueTemplate` string
  - `convergenceTimeout` integer
  - `suitableAsQuery` boolean
  - `createdAt` string, date-time
  - `updatedAt` string, date-time

## Other responses

- `401`: Missing or invalid API key
- `403`: Insufficient permissions (missing required scope)

---

[API](https://skmtc.dev/kiloiot/apis/kiloiot-public-api.md) · [All operations](https://skmtc.dev/kiloiot/apis/kiloiot-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/kiloiot/apis/kiloiot-public-api/revisions/faf39bde186c?raw)
