mapier docs

Addressing a conversation

The three target shapes, and how to get the conversation id you need.

Every command has a target that says who it acts on. There are three shapes, and picking the right one is usually the first question you answer.

conversation — reply into an existing thread

The one you will use most.

{ "kind": "conversation", "conversationId": "a0000000-0000-4000-8000-000000000001" }

conversationId is a Mapier UUID, not an iMessage GUID. You get it from the message event on the response stream:

{
  "conversationId": "a0000000-0000-4000-8000-000000000001",
  "from": "+14155550100",
  "text": "is it here yet?",
  "externalId": "guid-1",
  "replyToExternalId": null,
  "occurredAt": "2026-08-24T18:03:11.000Z",
  "attachmentIds": []
}

Store that id against your own records — a customer, a ticket, a thread — and you can reply at any time. It is stable for the life of the conversation.

Works for both direct messages and groups. Some commands accept only one or the other; each reference page says which.

A conversation id from another account returns conversation_not_found — the same response as an id that does not exist. If you are getting this unexpectedly, check the id came from your own stream.

recipient — start a new thread

When you have a phone number or email but no conversation yet.

{ "kind": "recipient", "recipientExternalId": "+14155550100" }

Prop

Type

Two limits apply, and both surprise people:

  • Plain text only, and it degrades silently. The endpoint forwards payload.text and drops every other key, so a recipient send carrying an effect or a reply target returns 202 and delivers the bare text with those parts missing. Nothing tells you they were ignored. Rich content needs a conversation target.
  • No idempotency. Recipient sends take the admin routing path, where an Idempotency-Key is accepted and ignored. A retry sends a second message.

The usual pattern is therefore: send a plain text opener, wait for the conversation to appear on the stream, then use its conversationId for everything after.

Check reachability first if you are unsure the address is on iMessage — POST /v1/handle-check answers synchronously and saves you a message that goes nowhere.

new_group — create a group

Only group.create accepts this.

{
  "kind": "new_group",
  "participantExternalIds": ["+14155550100", "+14155550111"]
}

Between 2 and 32 participants, each unique, each in the same E.164-or-email format as a recipient. Do not include yourself. Order does not matter.

Address formats

KindFormatValidInvalid
PhoneE.164, leading +, 7–15 digits+141555501004155550100, (415) 555-0100
EmailLowercase, NFC-normalisedperson@example.comPerson@Example.com

Addresses that fail these rules are rejected with invalid_address on handle check, or 422 on a send.

Conversation ids go stale

A group's id is resolved against its membership at the time you use it. Change the membership — add or remove someone — and commands issued against the old id settle stale_target.

The fix is to wait for a new message in the group, which carries a fresh conversationId, then use that. See Groups.

On this page