Subscribing to events

If you want to build your own integrations, you can quickly subscribe to Papercups events (e.g. message:created) via webhooks.

This page will walk you through setting up your own webhook URL. Let's get started!

Step 1: Go to the Integrations page#

After logging in, navigate to the Integrations page to get started:

Step 2: Click "Add webhook URL"#

Click the "Add webhook URL" to open the modal which will guide you through setting up your first webhook URL.

Step 3: Enter your webhook URL#

Enter the URL that you would like Papercups to notify of new events. After you enter a URL, we will attempt to verify it by sending it a POST request with a request body that looks like:

"event": "webhook:verify",
// Randomly generated string

In order to get your URL verified, it will need to respond with the randomly generated string in the payload. In a NodeJS backend, this might look something like:'/api/webhook', (req, res) => {
const {event, payload} = req.body;
switch (event) {
case 'webhook:verify':
// Alternatively, this will work as well:
// return res.json({challenge: payload})
// Respond with the random string in the payload
return res.send(payload);
case 'message:created':
case 'conversation:created':
case 'customer:created':
// TODO: handle events here!
return res.json({ok: true});

To quickly test that your endpoint is working as expected, the following cURL command should output PONG. (Note that it assumes your endpoint is called /api/webhook and is running on localhost:3000. Be sure to change the URL below to whatever you're using!)

curl --header "Content-Type: application/json" \
--request POST \
--data '{"event":"webhook:verify","payload":"PONG"}' \

NB: In development, you may need to use a service like ngrok to test your webhook. URLs like http://localhost:3000/api/webhook or will not work.

Step 4: Respond to events#

The following events will be sent to your webhook URL once it's verified:

  • message:created - sent when a message is created
  • conversation:created- sent when a conversation is created
  • conversation:updated- sent when a conversation is updated (e.g. closed, assigned, etc)
  • customer:created (coming soon!) - sent when a customer is created
  • customer:updated (coming soon!) - sent when a customer is updated

As an example, the message:created event request body would look something like this:

"event": "message:created",
"payload": {
"account_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"attachments": [],
"body": "Hey there!",
"conversation_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"created_at": "2021-02-24T00:10:45",
"customer": {
"browser": "Chrome",
"company_id": null,
"created_at": "2021-02-02T20:35:01",
"current_url": "",
"email": "",
"external_id": "a1b2c3d4e5",
"host": "",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"metadata": {
"plan": "premium"
"name": "Joe",
"object": "customer",
"os": "Mac OS X",
"pathname": "/account",
"phone": null,
"profile_photo_url": null,
"updated_at": "2021-02-24T00:10:43"
"customer_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"object": "message",
"private": false,
"seen_at": null,
"sent_at": "2021-02-24T00:10:45Z",
"type": "reply",
"user": null,
"user_id": null

To see some examples of webhook integrations, check out this demo: