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
tapped_action.payload, withtapped_action.kindset to"postback", - 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.tapped_action?.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 | tapped_action.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. To keep the conversation tappable after that first message, send quick replies and buttons mid-thread.