---
title: "Create Intent"
method: POST
path: "/api/v1/devices/{device_id}/launch-intents"
tags: ["device launch intents"]
---

# Create Intent

`POST /api/v1/devices/{device_id}/launch-intents`

## Request

- Base URL: `https://api.brumby.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.brumby.com/api/v1/devices/{device_id}/launch-intents`
- Auth: HTTP bearer

Place an intent. The action-worker publishes it retained.

The idempotency key is REQUIRED, and it is not ceremony. A retried POST without one
would place a second intent with a second id, and the dock dedupes by id -- so two
rows are two launches, however carefully the dock behaves.

## Path parameters

- `device_id` string, required

## Headers

- `Idempotency-Key` string, nullable

## Request body

- LaunchIntentCreate: Place an intent on a dock's retained downlink. ``intent_type=launch`` is refused: a flight starts only from a mission request's LAUNCH. ``valid_from``/``valid_until`` are optional: omitted, the window opens now and runs for the service default.
  - `intent_type` 'launch' | 'open' | 'close' | 'hold' | 'recall' | 'clear_fault', required: Doc 04 §1.1's intent vocabulary. ``launch`` and ``recall`` have dock seams. The rest are declared because the dock's own contract declares them, and a type it does not handle is logged and ignored rather than mistaken for a launch.
  - `parameters` object, nullable
  - `valid_from` string, date-time, nullable
  - `valid_until` string, date-time, nullable

## Response `201`

Successful Response

- LaunchIntentResponse
  - `intent_id` string, uuid, required
  - `device_id` string, required
  - `intent_type` 'launch' | 'open' | 'close' | 'hold' | 'recall' | 'clear_fault', required: Doc 04 §1.1's intent vocabulary. ``launch`` and ``recall`` have dock seams. The rest are declared because the dock's own contract declares them, and a type it does not handle is logged and ignored rather than mistaken for a launch.
  - `state` 'pending' | 'published' | 'acknowledged' | 'refused' | 'withdrawn' | 'failed', required: FleetOps-side lifecycle of one intent. Shorter than a diagnostic action's, and the difference is the point: an intent is RETAINED, so the broker owns redelivery. There is no publishing/accepted dance to track, because the dock may collect it minutes later on reconnect and that is correct rather than late. ``WITHDRAWN`` is a real state and not a deletion: clearing a standing intent means publishing an empty retained payload, which is an act that has to be recorded.
  - `parameters` object, nullable, required
  - `requested_by_actor` string, required
  - `valid_from` string, date-time, required
  - `valid_until` string, date-time, required
  - `published_at` string, date-time, nullable, required
  - `withdrawn_at` string, date-time, nullable, required
  - `acknowledged_at` string, date-time, nullable
  - `disposition` 'accepted' | 'refused' | 'ignored': What the dock reported doing with a collected intent, verbatim. ``ignored`` is a type with no supervisor seam (open/close/hold today) — recorded as REFUSED state-wise, but the word is kept because "the dock cannot do this yet" and "preflight said no" are different answers.
  - `disposition_detail` object, nullable
  - `last_error` string, nullable, required
  - `created_at` string, date-time, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/brumby/apis/brumby-platform-api.md) - [All operations](https://skmtc.dev/brumby/apis/brumby-platform-api/llms.txt) - [OpenAPI document](https://skmtc.dev/brumby/apis/brumby-platform-api/revisions/fe185e20813e?raw)
