chat_background.set
Set the background of a conversation — one confirmed person's, or a group chat's — to a named preset or to two colours of your own.
POST /v1/commands/chat_background.setSets the background of an iMessage conversation, by the background's name at
payload.preset: one of Apple's own backgrounds, or custom with two colours
you choose. It is done in a conversation with one person that the
transport has confirmed is with that one person, or in a group chat it
reported.
Honours Idempotency-Key: a retry under the same key adopts the first command
rather than setting the background again. A set and a
chat_background.remove each take a key of
their own — see One key for each command.
A change arrives as a message with no text
On a live line a background set in a conversation with one person also arrives as a message from
that person with no text: a message frame and a message.received webhook whose text is
null. Skip a received message that has no text and no attachment rather than reply to it — see
The message a change leaves.
Target
Prop
Type
Each of these is 422 validation_failed at target.conversationId before
anything is sent:
- a conversation the transport has not named;
- a conversation with one person it has not yet confirmed, with
reason: conversation_not_confirmed— send the person a text first; - in place of a conversation, the address of someone this project has already exchanged messages with.
An address this project has never exchanged messages with is refused at the field you wrote it at, as for every command done in a conversation.
Payload
Prop
Type
Presets
A preset's name is lower-case and sent exactly as written here.
| Preset | What it is |
|---|---|
gradient | Apple's default background. |
color_mango, color_ice, color_plum, color_deep_sea, color_green_apple, color_cherry, color_bubblegum, color_tangerine, color_magenta, color_lime, color_silver, color_carbon, color_stone | Apple's two-colour gradients, by Apple's name for each. |
custom | A gradient of the two colours you give at colors. |
aurora_green, aurora_purple, aurora_pink | Apple's animated aurora backgrounds. |
sky_dusk, sky_haze, sky_sunset, sky_clear, sky_sunrise, sky_dawn | Apple's animated sky backgrounds. |
water_light, water_dark | Apple's animated water backgrounds. |
glitter_gold, glitter_copper, glitter_silver | Apple's animated glitter backgrounds. |
Colours of your own
custom is a gradient of two colours, given at payload.colors as an array of
exactly two strings, each #RRGGBB:
{ "preset": "custom", "colors": ["#008080", "#FFE600"] }Every other preset has its own colours and takes no colors.
What is refused
Each of these is 422 validation_failed before anything is sent:
- a preset that is missing or not on that list, at
payload.preset; - a
customset without exactly two#RRGGBBcolours, atpayload.colors; colorsbeside any other preset, atpayload.colors;- any other key, at that key (
payload.<key>).
What comes back
At once, beside the refusals above, the transport can answer
503 upstream_unavailable:
- with
details.reason: "connector_unavailable"while the line's device is offline; - with
details.reason: "outbound_paused"while the transport's sending is paused.
Otherwise 202, then one command frame on the
response stream:
succeeded— the device read the change back.failedwithgateway_rejected— the device refused before changing anything: it was busy with another background change, could not find the conversation, or was without what a background change needs at that moment. Nothing changed, and the set can be sent again under a newIdempotency-Key.failedwithstale_target— a group chat the device could not find among its own with the members the transport last saw. A group addressed right after its membership changed, before its next message, is one.failedwithcapability_not_negotiated— the line's device has not announced that it sets a background. Setting and removing are announced apart.failedwithcapability_constraint_violation— the line's device does not carry that preset. Nothing changed. See A preset the line's device does not carry.expiredwithcommand_expired_before_execution— the device did not reach the change in time. Nothing changed.ambiguouswithchat_background_unverified— the device began the change and could not read it back. It may or may not have been made.
Rarely, a set settles ambiguous with gateway_timeout instead, when the
device's own call failed before it could say what it did. Read it as
chat_background_unverified.
chat_background_unverified: ask before you send it again
This API cannot read a background back. Ask someone in the conversation whether the background changed before you send the set again.
A preset the line's device does not carry
Each line's device announces the backgrounds it can set, and one on older
software announces fewer. A set of a preset it does not carry is accepted and
then settles failed with capability_constraint_violation and
failureClass: "capability". Nothing changed.
gradient is on every device that sets a background, so it is the one to fall
back to.
While a change is under way
A background change lets the line's other waiting commands go first. Once it
has started, the line runs nothing else until the change is read back or given
up on, so anything sent meanwhile, into any conversation on the line, waits for
it — everything but a typing.start.
A message into a confirmed conversation or a group chat, a reaction.tapback,
a name_photo.share or a poll.vote that waits past the
conversation path's 30 seconds
settles expired.
The message a change leaves
On a live line a background set or removed in a conversation with one person also arrives as a message from that person with no text. It arrives whoever made the change: this command, or the person on their own phone.
It is a message frame and a message.received webhook whose text is
null. It is stored in the conversation, counted as a received message, and
leaves the conversation awaiting a reply in the console until the line next
sends.
Nobody wrote anything, so there is nothing to answer. Skip a received message that has no text and no attachment rather than reply to it — see Inbound message events and Webhooks.
In a group chat the line's own change files nothing.
One key for each command
Give a set and a remove a key each. On a live line the transport reads the two
as one verb: one Idempotency-Key reused across a set and a remove is answered
with the first command and changes nothing more. On a test line the same reuse
is 409 conflict with details.reason: "idempotency_key_reused".
In test
A test line carries a set in a conversation with one person and settles it as
a live line does. Its device carries every preset on the list, so a test line
never settles capability_constraint_violation. Nothing draws the background, and no message with no text is
filed. A test line has no group chat to set one in.
Request
curl https://api.mapier.ai/v1/commands/chat_background.set \
-H "Authorization: Bearer $MAPIER_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: background-set-order-2481" \
-H "x-mapier-version: 2026-10-15" \
-d '{
"target": {
"kind": "conversation",
"conversationId": "a0000000-0000-4000-8000-000000000001"
},
"payload": { "preset": "sky_dusk" }
}'Response
{
"commandId": "cmd-14",
"status": "queued",
"disposition": "queued",
"lineId": "0192a7b0-3e4f-7051-8c6d-7e8f9a0b1c2d",
"lineSelection": "reused_active_chat"
}Then, on the response stream:
{
"commandId": "cmd-14",
"logicalActionId": "background-set-order-2481",
"status": "succeeded",
"errorCode": null,
"conversationId": "a0000000-0000-4000-8000-000000000001",
"type": "chat_background.set",
"messageId": null,
"externalId": null,
"namePhoto": null,
"projectId": "b0000000-0000-4000-8000-000000000002",
"environment": "live",
"failureClass": null
}Errors
A command answers the one set of HTTP refusals
POST /v1/commands/{type} publishes, so that table is
the one to handle. What is particular to this type:
422 validation_failedattarget.conversationIdfor a conversation the transport has not named, one with one person it has not confirmed — withreason: conversation_not_confirmed— or the address of someone this project has already exchanged messages with, in place of a conversation.422 validation_failedatpayload.preset,payload.colorsorpayload.<key>, as above.409 conflictwithdetails.reason: "idempotency_key_reused"on a test line for a key achat_background.removeused.503 upstream_unavailablewithdetails.reason: "connector_unavailable"while the line's device is offline, or"outbound_paused"while the transport's sending is paused.404 unsupported_commandwithreason: not_on_channelon a line of any other channel.
Settlement codes you will see for this command: gateway_rejected,
stale_target, capability_not_negotiated, capability_constraint_violation,
command_expired_before_execution, chat_background_unverified and
gateway_timeout. See Error codes.
Related
poll.vote
Vote on a poll in a conversation, naming the poll and the choice by the ids its poll.created event carried. A vote adds a choice; it never takes one back.
chat_background.remove
Remove the background of a conversation — one confirmed person's, or a group chat's. It takes no payload, and its success does not say whether there was one to remove.