Assign Intercom Conversations to the Current On-Call with Pagerly
An unassigned support conversation is a customer waiting. How to route Intercom to whoever is on call, and let them answer from Slack.
Support queues have a sharper version of the unassigned-ticket problem than engineering queues do. A bug sitting unowned for two days is embarrassing. A conversation sitting unowned for two hours is a customer deciding what they think of you.
Intercom's own routing is good at getting a conversation to a team. Getting it to the person who is actually working right now is a different question, and it is the one your on-call rota already answers.
How Intercom assignment actually works
Intercom assigns to an admin ID — its term for a teammate — not to an email address. So the flow has three steps rather than two, and the middle one is where most implementations get sloppy.
Step one: who is on call
curl -s 'https://api.pagerly.io/pagerly/o/currentusers?teamname=support' \
-H "X-APIKEY: $PAGERLY_API_KEY"
[{ "name": "mansi", "email": "mansi@pagerly.io", "id": "U04CTTV5Z6G", "imageurl": null }]
Step two: email to admin ID
curl -s https://api.intercom.io/admins \
-H "Authorization: Bearer $INTERCOM_TOKEN" \
-H "Intercom-Version: 2.13"
{
"type": "admin.list",
"admins": [
{ "type": "admin", "id": "814860", "name": "Mansi", "email": "mansi@pagerly.io" }
]
}
The admin list is small and changes rarely — a handful of teammates, updated when someone joins or leaves. Cache it and refresh on a miss. Calling it once per conversation is a waste on a busy queue and gets you rate-limited on a very busy one.
Step three: assign
Conversations and tickets are different objects in Intercom with different endpoints, which is worth knowing before you spend twenty minutes debugging a 404.
Assigning a conversation is posting a conversation part:
curl -s -X POST \
"https://api.intercom.io/conversations/$CONVERSATION_ID/parts" \
-H "Authorization: Bearer $INTERCOM_TOKEN" \
-H "Intercom-Version: 2.13" \
-H 'Content-Type: application/json' \
-d '{
"message_type": "assignment",
"type": "admin",
"admin_id": "<acting-admin-id>",
"assignee_id": "<oncall-admin-id>"
}'
admin_id is the actor doing the assigning — the admin whose token you are calling with. assignee_id is the on-call engineer from step two. Mixing these up assigns the conversation to your integration account, which looks like it worked right up until nobody replies.
Assigning a ticket is an update:
curl -s -X PUT \
"https://api.intercom.io/tickets/$TICKET_ID" \
-H "Authorization: Bearer $INTERCOM_TOKEN" \
-H "Intercom-Version: 2.13" \
-H 'Content-Type: application/json' \
-d '{
"assignment": {
"admin_id": "<acting-admin-id>",
"assignee_id": "<oncall-admin-id>"
}
}'
Triggering it
Intercom fires webhooks on conversation.user.created and conversation.user.replied. Point one at a handler that runs the three steps, or build the same sequence in Zapier, Make or n8n — new conversation, fetch on-call, match admin, post assignment.
Pagerly exposes a Make-shaped variant of the endpoint (/o/currentusersformake) that wraps the same payload in an output array so Make's iterator consumes it directly. Zapier and n8n are happier with the plain /o/currentusers.
The other half: answering from Slack
Assignment tells you who owns the conversation. It does not help them answer it, and for a support rota that second part is where the time actually goes.
Once Intercom is connected to Pagerly, an Intercom conversation can be mirrored into a Slack thread. Customer messages appear in the thread as they arrive; the on-call replies in Slack; Pagerly posts the reply back to Intercom as an admin, so the customer sees a normal support response in the Messenger. Tickets can be raised from Slack too, with priority and description, and the Slack thread stays linked to the Intercom ticket from then on.
The practical effect is one surface instead of two. A conversation lands, it is assigned to the person on shift, a thread opens where they already are, and they answer without switching context. For engineers covering support rotations — which is most small teams — this is the difference between a rota people tolerate and one they resent, because the cost of being on support stops being "keep a second inbox open all day".
The edges support rotas actually hit
Support schedules have more awkward boundaries than engineering ones, and these are worth deciding deliberately rather than discovering.
Out of hours. At 03:00 your rota may legitimately have nobody on it, and the endpoint returns an empty array. Assigning to an Intercom team rather than an admin is the right fallback here — the conversation still lands somewhere with an SLA and a queue, rather than in the void that assignment-to-nobody creates.
Handover. A conversation assigned at 17:55 to a shift ending at 18:00 is functionally orphaned. Two fixes, and they compose: reassign open conversations at handover, and trigger assignment on customer reply rather than only on creation. The second is the more elegant of the two — a conversation naturally moves to whoever is on duty when the customer next writes, which is exactly when ownership matters.
Escalation is not reassignment. A conversation that turns out to need an engineer rather than a support agent should page the engineering rota, not silently move to it. Assignment is for work that is in the right queue. Escalation is for work that is in the wrong one, and it needs an acknowledgement model, not just an assignee field.
Identity is the thing that breaks
Every failure mode in this integration reduces to identity, so it is worth being systematic about it once.
The on-call user must exist as an admin in Intercom, with the same email they have in Pagerly. Being on the support rota does not create an Intercom seat, and a contractor who covers weekends but was never added as a teammate will resolve to nothing every Saturday. The symptom is a conversation that stays unassigned with no error anywhere, because the admin lookup returned an empty list and your code moved on.
Audit it properly: for each person on each support rota, confirm they are an Intercom admin and the emails match. It takes ten minutes and it removes the entire class of bug.
Two other things that look like assignment problems and are not. An assignment that succeeds but produces no notification is an Intercom notification-preferences issue — mirror the thread into Slack rather than fighting it. And a 401 after months of working means the OAuth connection was revoked or expired, which is a reconnect, not a code change.
Why this is worth the setup
The measurable win is first-response time on conversations that arrive outside the moment someone happens to be watching the inbox. The less measurable one is that support stops being a thing that happens to whoever notices.
A rota that governs support conversations is exercised dozens of times a day rather than a few times a month. Gaps in it surface immediately and cheaply — as a conversation landing on the wrong person on a Tuesday, rather than as a customer who waited six hours on a Sunday.
Setup details are in the Intercom assignment documentation. For the same pattern in Jira and Linear, see assigning bugs and tickets to the current on-call.
