---
title: "POST /clipboard/dispatch"
method: POST
path: "/clipboard/dispatch"
tags: ["clipboard"]
---

# POST /clipboard/dispatch

`POST /clipboard/dispatch`

Wraps plaintext into a single `text/plain` snapshot and fans it out to
online peers. Returns the per-target delivery outcome.

## Request body

- DispatchTextRequest — Request body for `POST /clipboard/dispatch`. The daemon wraps the text into a single `text/plain` `SystemClipboardSnapshot` and fans it out to online peers.
  - `peers` string[], nullable — Optional target device IDs. Empty or absent = full fan-out.
  - `text` string, required — Plaintext to dispatch.

## Response `200`

Dispatch fan-out outcome

- DispatchOutcomeEnvelope — Canonical success envelope: `{ "data": T, "ts": <unix millis i64> }`. `ts` is `chrono::Utc::now().timestamp_millis()`, set in the webserver handler via [`ApiEnvelope::now`] (the contract carries only the type + the clock helper, not a hard dependency on when the handler reads the clock). `rename_all = "camelCase"` is a no-op for the single-word fields here but is declared for forward-compat. IMPORTANT (utoipa v4): every concrete `ApiEnvelope<X>` that needs a named OpenAPI component is declared in the `#[aliases(...)]` block below. Add a new alias line whenever a new payload type needs enveloping. NEVER register the bare `ApiEnvelope` in `components(schemas(...))` — utoipa errors on a bare generic, and an un-aliased generic inlines an anonymous schema.
  - `data` DispatchOutcomeResponse, required — Response body for `POST /clipboard/dispatch`.
    - `atMs` integer, required
    - `perTarget` PerTargetOutcomeDto[], required
      - `deviceId` string, required
      - `error` string, nullable
      - `outcome` string, required — `"accepted"` | `"duplicate"` | `"error"`.
    - `snapshotHash` string, required
    - `totalAccepted` integer, required
    - `totalDuplicate` integer, required
    - `totalErrored` integer, required
    - `totalOffline` integer, required
  - `ts` integer, required — Server time when the response was built (unix epoch milliseconds).

## Other responses

- `400` — Empty or malformed request
- `500` — Internal server error
- `503` — Daemon is draining a controlled restart; retry against the successor

---

[API](https://skmtc.net/uniclipboard/apis/uniclipboard-daemon-api.md) · [All operations](https://skmtc.net/uniclipboard/apis/uniclipboard-daemon-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/uniclipboard/uniclipboard-daemon-api/versions/a5d29889448a/schema)
