mapier docs

POST /v1/commands/:type

The shared envelope every command uses — target, payload, idempotency and the two routing paths.

Every action you take on iMessage is a command. They all share one endpoint, one request envelope and one response shape; the :type path segment selects the verb.

POST /v1/commands/{type}

Request

Headers

Prop

Type

Body

Prop

Type

The body must be a JSON object no larger than 65,536 bytes, with both keys present and both objects. See Addressing a conversation for the three target shapes.

Command types

TypePurposeReference
message.sendSend text, rich text, a link, a poll or mediamessage.send
reaction.tapbackReact to any message, in a DM or a groupreaction.tapback
reaction.applyReact to the newest incoming DM messagereaction.apply
name_photo.shareOffer your contact card in a DMname_photo.share
group.createStart a group chatgroup.create
group.updateRename a group or change its membersgroup.update
group.leaveLeave a groupgroup.leave

An unrecognised type returns 404:

{ "error": "unknown_command", "command": "message.explode" }

Response

202 Accepted:

{
  "commandId": "3f1a0c2e-8b47-4d19-9a5e-2c6f0b8d4e71",
  "status": "queued",
  "disposition": "queued"
}

disposition is "adopted" when an identical idempotency key already existed, meaning no new work was created and commandId refers to the original command. In that case status reflects that command's current state, so an adopted duplicate can come back already succeeded.

The response tells you the command was queued. It does not tell you the message was delivered. Watch the response stream for the command event that settles it.

The two routing paths

This is the behaviour most likely to surprise you, and it is invisible in the request. Internally a command takes one of two paths, decided by its type and target, and they differ in ways you can observe.

Prop

Type

On the admin path an Idempotency-Key header is accepted and silently ignored. Retrying a group.create or a cold message.send creates a second group or sends a second message. See Idempotency and retries.

Payloads are not validated here

The endpoint checks the envelope — that target and payload are objects, that a conversation id is a UUID, that a recipient send has text. It does not validate the payload against the command's schema. That happens on the Mac at execution time.

A payload with a misspelled field, an out-of-range value or a bad enum returns 202, then settles failed on the stream seconds later. When you are developing against a new payload shape, keep the stream open.

Errors

StatusCodeCause
400body_too_largeBody over 65,536 bytes
400body_not_objectBody is not a JSON object
400target_and_payload_requiredMissing or non-object target/payload
400invalid_conversationIdNot a UUID
401unauthenticatedNo credential
404unknown_commandUnknown :type
404conversation_not_foundUnknown conversation, or another account's
405method_not_allowedNot a POST
422(varies)Address validation failed
429rate_limited60 requests per minute
500internalPersistence failure
503no_live_connectorNo Mac holds a live lease
503outbound_pausedSending is paused

Full descriptions and retry guidance: Error codes.

On this page