Start or select a group
to. An admin API key also passes the sending identity as agent_identity_id; an identity-scoped API key always sends as its own identity.
bash
- One unresolved local group with the same requested members is reused before a remote thread has been established, whether creation is still pending or being retried.
- One established group with the same best-known members is reused only when its current membership can be verified and still matches the request.
- If no reusable match remains, a new group conversation is created.
- If multiple groups match, the request returns
409 ambiguous_group_conversationinstead of choosing one. Continue a specific thread by itsconversation_id.
to request never adds or removes members from an existing group. A different member set selects another exact match or creates a separate group. A scalar to value and a one-item to list keep their existing 1:1 behavior. to and conversation_id are mutually exclusive.
The 201 response uses the regular Message object. Group-specific fields look like this:
JSON
Creation lifecycle
Group creation is asynchronous. The initial201 means Inkbox stored the local conversation and queued the first message; it does not mean the remote thread is ready yet. Read the conversation or opt groups into the conversation list to inspect group_creation_status:
An unconfirmed first send is closed after a 15-minute confirmation window, without
assuming that it was never delivered. It retains
error_code: "send_outcome_ambiguous".
Waiting messages that were never sent are closed with error_reason: "request_not_sent".
They do not automatically create a replacement group. If you choose to send again,
use a fresh request key and do not blindly repeat the uncertain original.
A new attempt can create a separate group if the earlier creation succeeded
without confirmation.
While the conversation is creating, another send to the same conversation_id or exact to set is stored as another pending message on that local conversation and waits behind the elected creation send instead of initiating creation independently. If the initial attempt fails, the local conversation keeps the same conversation_id and the failed message remains visible in its history with status: "error". Send the next message with that conversation_id to retry creation. A successful retry changes the conversation to ready; later sends continue the newly bound group without creating another local conversation.
Continue the same group
For Companion mode,conversation_id is required to use conversation-only reply permission. Raw to sends cannot borrow that permission. The sponsor must remain in the verified current group; membership changes require fresh sponsorship. Read access and reply readiness are separate, and ordinary send requirements still apply.
Keep the conversation_id from the first response and use it for every later send into that exact thread:
JSON
conversation_id is the canonical group key. Do not reconstruct a thread from its participants when you need to continue a specific conversation: membership can change, and more than one real group can have the same members. A send by conversation_id continues that native thread with its verified current membership; all current recipients must pass the send preflight.
Group creation and conversation replies support the same 13 expressive send_style values as 1:1 messages. A style can accompany text, one media_urls item, or both:
JSON
Native reply threads
To reply to a specific message within an established group, sendconversation_id, reply_to_message_id, and your text or media through the existing messages endpoint. The target can be a participant’s message or a confirmed sent message in that same group. Omit the target for an ordinary group message.
Group messages expose nullable reply_to_message_id, thread_id, and thread_root_message_id on message reads and message webhooks. A non-null parent identifies a visible reply; an ordinary message can have its own thread ID before anyone replies. Use sender_number to identify the participant. Retrieve the root and visible replies with Get a reply thread, or Get conversation thread when you already have its ID.
A reply thread stays inside the existing group; it does not create another conversation or change its membership. plain_reply_fallback defaults to true: a target known to use SMS/RCS or to have been downgraded can receive an ordinary response in that same group, without native reply metadata linking it to the target. This uses ordinary transport selection, not a separate 1:1 send to each participant. Set plain_reply_fallback: false to require native threading. Missing, inaccessible, pending, failed, or unresolved targets remain errors. Fallback does not automatically retry a rejected native reply, delivery failure, timeout, or uncertain send. See reply behavior.
List and read groups
Existing list endpoints exclude groups by default so current 1:1 callers keep the same result set and pagination. Passinclude_groups=true to opt in:
is_group: true, participants, group_creation_status, and null assignment_id, assignment_status, and remote_number fields. MCP conversation reads expose is_group, participants, and the same null assignment/recipient fields, but do not include group_creation_status. Group messages return a participant snapshot. On inbound group messages, sender_number identifies who sent the message and remote_number mirrors that value for compatibility.
Membership semantics
Conversationparticipants is an append-only, best-known history of E.164 phone numbers observed in the thread. A newly added member may not appear until later group activity, and a member who leaves is not removed from the stored list. Do not use this field as an authoritative current-membership or authorization check. Before an existing-group send or tapback is accepted, Inkbox resolves the thread’s current recipients and applies opt-out and contact-rule checks to each one.
There is no API operation to add or remove a group member in V1. Membership changes happen in the native group conversation, and Inkbox updates its best-known participant history as activity reveals changes. After that history gains a member, sending to the original subset can create a separate group instead of continuing this one; use conversation_id whenever thread continuity matters.
Delivery and current limitations
Outbound group messages include onerecipients entry per participant. Group delivery transitions are message-level in V1, so the aggregate state is applied to those participant entries together. See iMessage webhooks.
Ready groups support tapbacks with the same targeting, replacement, and removal semantics as 1:1 conversations. Group reactions have assignment_id: null, and an inbound group reaction’s remote_number identifies the participant who reacted.
Read receipts and typing indicators return 409 operation_not_supported_for_group_conversation. MCP supports group reads, sends, and tapbacks; conversation lists include groups only when requested.
Detaching or reassigning the dedicated line leaves the old conversation readable as history to its original organization and identity, but sends and actions on it return 409. A later line owner does not inherit the old group.
Error responses
Use the response’s
detail.error to choose the recovery path. Select a specific conversation_id for ambiguous_group_conversation. For group_membership_changed, verify the intended members and repeat the request so matching runs again. Retry group_conversation_not_ready only after the conversation is ready on its current line. Membership-consistency conflicts and group_membership_unavailable may be retried with backoff, while attachment and unsupported-operation conflicts require changing the line or operation instead of retrying unchanged.
