How to Set Instagram Ice Breakers via API
Manage the suggested questions Instagram shows when a user opens a new DM thread — set up to 4 ice breakers, receive taps as webhooks, and auto-respond by payload.
What ice breakers are
Ice breakers are up to 4 predefined questions Instagram shows a user who opens a new DM thread with your business — before they type anything. The user taps one, you get the tap with a payload you chose, and the conversation starts on your terms.
Three properties make them worth setting up:
- You pick the questions. “Track my order”, “What are your hours?”, “Talk to a human” — the first message routes itself.
- A tap opens the 24-hour messaging window, so you can reply free-form immediately.
- They unlock ig.me referral tracking. Meta only sends ig.me link referrals for profiles with at least one ice breaker set — without them, your campaign
refparameters go nowhere.
They work on Instagram professional accounts with DMs enabled only.
Set ice breakers
curl -X POST "https://api.postproxy.dev/api/profiles/PROFILE_ID/ice_breakers" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ice_breakers": [ { "question": "Track my order", "payload": "TRACK_ORDER" }, { "question": "What are your hours?", "payload": "HOURS" }, { "question": "Talk to a human", "payload": "HUMAN" } ] }'Each item needs a question (what the user sees, 1–4 items total) and a payload (what you get back when it’s tapped). A POST replaces the existing set — there is no partial update. The response is { "success": true }.
To inspect the current set, GET /api/profiles/PROFILE_ID/ice_breakers; to remove them entirely, DELETE the same path.
Receive taps
When a user taps an ice breaker, Meta sends a postback — not a regular message. Postproxy normalizes it into an inbound message in the chat:
bodyis the tapped question (e.g."Track my order"),- your payload rides along at
platform_data.postback.payload, - a
message.receivedwebhook fires, - the 24-hour messaging window opens.
So an ice-breaker tap looks exactly like any other inbound DM to your handler, with one extra field telling you which button it was.
Route by payload
A minimal handler that answers each ice breaker differently:
app.post("/webhooks/postproxy", async (req, res) => { res.sendStatus(200); // ack fast, work after
const event = req.body; if (event.type !== "message.received") return;
const msg = event.data.object; const payload = msg.platform_data?.postback?.payload; if (!payload) return; // a typed message, not an ice-breaker tap
const replies = { TRACK_ORDER: "Send me your order number and I'll look it up.", HOURS: "We're open Mon-Fri 9:00-18:00 CET.", HUMAN: "Connecting you with the team — expect a reply within the hour.", };
await fetch(`https://api.postproxy.dev/api/chats/${msg.chat_id}/messages`, { method: "POST", headers: { Authorization: `Bearer ${process.env.POSTPROXY_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ body: replies[payload] ?? replies.HUMAN }), });});The reply is a normal send through the Direct Messages API — the tap opened the 24-hour window, so no special handling is needed. From here the thread continues like any conversation: see How to Send Instagram DMs via API.
Rules and limits, in one place
| Rule | Value |
|---|---|
| Platform | Instagram professional accounts, DMs enabled |
| Max questions | 4 |
| Update semantics | POST replaces the whole set |
| Tap arrives as | Inbound message + message.received webhook |
| Payload location | platform_data.postback.payload |
| Opens 24-hour window | Yes |
| Unlocks ig.me referrals | Yes — Meta requires at least one ice breaker set |
| Wrong platform / DMs off | 422 with an explanatory error |
Full endpoint details: Ice breakers in the Direct Messages reference. To know which campaign brought the user into the thread in the first place, pair ice breakers with ig.me link referrals.