1MSG
Reference

Inbox API

WhatsApp Inbox API is an HTTP API for 1MSG Inbox. Your code does in Inbox what an operator does on the Platform: list conversations, assign them, open and close them, and block a contact. Your team keeps working in Inbox as usual and sees every change your code makes. Each action leaves a system message in the chat.

The two APIs split the work. The WhatsApp Business API sends and receives messages. Inbox API manages who handles a conversation, what state it is in, and what has changed. You still reply to customers through the WhatsApp Business API. Incoming messages and delivery statuses still arrive at your channel webhook. Inbox events go to their own webhook, and each one is signed.

API key

Sign in at platform.1msg.io. Open Settings → Developer → API Settings, generate a key, and copy it. The full key is shown once.

Send it on every request:

Authorization: Bearer 1msg_live_••••••••

The key belongs to a user and has that user's permissions. It sees the same channels, and every action is made on that user's behalf. For all channels, the account owner creates a key for themselves. To work within a teammate's permissions, create a key for that teammate.

GET
/api/v1/inbox/channels

An account key sees every channel. A user key sees only channels that user can open.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Response Body

application/json
  1. response
[index: integer]?
curl -X GET 'https://api.1msg.io/api/v1/inbox/channels'
[  {    "id": "QAF261225002",    "name": "QA FMF",    "status": "ACTIVE"  }]
GET
/api/v1/inbox/channels/{channelId}/assignees

The account owner, plus operators who already have this channel. Use the returned id as userId when assigning a conversation.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Path Parameters

channelId*string

Channel id from GET /inbox/channels

Response Body

application/json
  1. response
[index: integer]?
curl -X GET 'https://api.1msg.io/api/v1/inbox/channels/QAF261225002/assignees'
[  {    "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",    "name": "QA Stage",    "avatar": null,    "role": "OPERATOR"  }]

List conversations

GET
/api/v1/inbox/conversations

Newest lastMessageAt first. Pass pagination.nextCursor as cursor for the next page.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Query Parameters

limit?number

Page size. Default 50.

cursor?string

pagination.nextCursor from the previous page (ISO lastMessageAt).

channelId?string

Limit to one channel.

status?string

Conversation status.

Value in"OPEN""CLOSED"
unread?boolean

true keeps only conversations with unread messages.

tab?string

mine_open: open and assigned to this key. unassigned: open and nobody assigned. all: no extra tab filter.

Value in"mine_open""unassigned""all"
assigneeId?string

Only conversations assigned to this user id.

Response Body

application/json
  1. response
data*array<>
pagination*
curl -X GET 'https://api.1msg.io/api/v1/inbox/conversations'
{  "data": [    {      "id": "string",      "channelId": "string",      "contactId": "string",      "status": "OPEN",      "assignedTo": "string",      "assignedUser": {        "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",        "name": "QA Stage",        "avatar": null      },      "lastMessageAt": "2019-08-24T14:15:22Z",      "isUnread": true,      "tags": [        "string"      ],      "lastMessagePreview": "string",      "lastMessageType": "string",      "lastMessageDirection": "INBOUND",      "lastMessageStatus": "string",      "unreadCount": 0,      "isBlocked": true,      "title": "string",      "lastCustomerMessageAt": "2019-08-24T14:15:22Z",      "createdAt": "2019-08-24T14:15:22Z",      "updatedAt": "2019-08-24T14:15:22Z",      "contact": {        "id": "string",        "phoneNumber": "79001234567",        "name": "string",        "avatar": "string"      },      "channelType": "WABA",      "customerPhone": "string"    }  ],  "pagination": {    "hasMore": true,    "nextCursor": "2019-08-24T14:15:22Z",    "limit": 50  }}

Search conversations

GET
/api/v1/inbox/conversations/search

Matches contact name, phone, and message text in one channel. channelId is required. query must be at least 3 characters; a shorter query returns two empty lists.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Query Parameters

query*string

At least 3 characters.

channelId*string

Channel to search. Required.

Response Body

application/json
  1. response
contacts*array<>

Conversations matched by contact name or phone.

messages*array<>

Conversations matched by message text. A conversation already listed in contacts is not repeated here.

curl -X GET 'https://api.1msg.io/api/v1/inbox/conversations/search?query=7900&channelId=QAF261225002'
{  "contacts": [    {      "id": "string",      "channelId": "string",      "contactId": "string",      "status": "OPEN",      "assignedTo": "string",      "assignedUser": {        "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",        "name": "QA Stage",        "avatar": null      },      "lastMessageAt": "2019-08-24T14:15:22Z",      "isUnread": true,      "tags": [        "string"      ],      "lastMessagePreview": "string",      "lastMessageType": "string",      "lastMessageDirection": "INBOUND",      "lastMessageStatus": "string",      "unreadCount": 0,      "isBlocked": true,      "title": "string",      "lastCustomerMessageAt": "2019-08-24T14:15:22Z",      "createdAt": "2019-08-24T14:15:22Z",      "updatedAt": "2019-08-24T14:15:22Z",      "contact": {        "id": "string",        "phoneNumber": "79001234567",        "name": "string",        "avatar": "string"      },      "channelType": "WABA",      "customerPhone": "string"    }  ],  "messages": [    {      "id": "string",      "channelId": "string",      "contactId": "string",      "status": "OPEN",      "assignedTo": "string",      "assignedUser": {        "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",        "name": "QA Stage",        "avatar": null      },      "lastMessageAt": "2019-08-24T14:15:22Z",      "isUnread": true,      "tags": [        "string"      ],      "lastMessagePreview": "string",      "lastMessageType": "string",      "lastMessageDirection": "INBOUND",      "lastMessageStatus": "string",      "unreadCount": 0,      "isBlocked": true,      "title": "string",      "lastCustomerMessageAt": "2019-08-24T14:15:22Z",      "createdAt": "2019-08-24T14:15:22Z",      "updatedAt": "2019-08-24T14:15:22Z",      "contact": {        "id": "string",        "phoneNumber": "79001234567",        "name": "string",        "avatar": "string"      },      "channelType": "WABA",      "customerPhone": "string"    }  ]}

Conversation counts

GET
/api/v1/inbox/conversations/counts

mine_open and unassigned count only OPEN conversations. all counts every visible conversation.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Query Parameters

channelId?string

Limit the counts to one channel.

Response Body

application/json
  1. response
mine_open*number

Open conversations assigned to the key actor.

unassigned*number

Open conversations with no assignee.

all*number

All conversations visible to the key, any status.

curl -X GET 'https://api.1msg.io/api/v1/inbox/conversations/counts'
{  "mine_open": 0,  "unassigned": 0,  "all": 1}

One conversation

GET
/api/v1/inbox/conversations/{conversationId}

Includes the contact, assignee, and customer phone.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Path Parameters

conversationId*string

Conversation id

Response Body

application/json
  1. response
id*string
channelId*string

Channel id, for example QAF261225002

contactId*string
status*string

The key sets only OPEN or CLOSED. Other values can appear on older rows.

Value in"OPEN""CLOSED""ASSIGNED""RESOLVED""BLOCKED"
assignedTo?|

User id of the assignee. Null when unassigned.

assignedUser?|null
lastMessageAt?|
Formatdate-time
isUnread*boolean
tags*array<string>
lastMessagePreview?string|null
lastMessageType?string|null
lastMessageDirection?|
Value in"INBOUND""OUTBOUND"
lastMessageStatus?string|null
unreadCount*number
isBlocked*boolean
title?|

Custom title. Null until renamed.

lastCustomerMessageAt?|

Last inbound customer message. Used for the WhatsApp service window.

Formatdate-time
createdAt*string
Formatdate-time
updatedAt*string
Formatdate-time
contact?|

Present on GET conversation, list, and search. Absent on block, title, and status writes.

channelType?string

Present on reads.

customerPhone?|

Customer phone taken from the contact.

curl -X GET 'https://api.1msg.io/api/v1/inbox/conversations/string'
{  "id": "string",  "channelId": "string",  "contactId": "string",  "status": "OPEN",  "assignedTo": "string",  "assignedUser": {    "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",    "name": "QA Stage",    "avatar": null  },  "lastMessageAt": "2019-08-24T14:15:22Z",  "isUnread": true,  "tags": [    "string"  ],  "lastMessagePreview": "string",  "lastMessageType": "string",  "lastMessageDirection": "INBOUND",  "lastMessageStatus": "string",  "unreadCount": 0,  "isBlocked": true,  "title": "string",  "lastCustomerMessageAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "contact": {    "id": "string",    "phoneNumber": "79001234567",    "name": "string",    "avatar": "string"  },  "channelType": "WABA",  "customerPhone": "string"}
GET
/api/v1/inbox/conversations/{conversationId}/messages

Newest first. Omit kind, or pass kind=all, to include SYSTEM events (status, assignee, block, title) together with messages. kind=messages hides SYSTEM events. kind=system returns only SYSTEM events. Notes stay with messages. Pass nextCursor as cursor to load older rows of the same kind.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Path Parameters

conversationId*string

Conversation id

Query Parameters

limit?number

Page size. Default 50.

cursor?string

nextCursor from the previous page (ISO createdAt). Returns rows older than that instant, still filtered by kind.

kind?string

all (default when omitted): every row. messages: everything except SYSTEM. system: only SYSTEM.

Value in"all""messages""system"

Response Body

application/json
  1. response
messages*array<>

Newest first. Includes SYSTEM events.

nextCursor?|

Pass back as cursor to load older messages. Null on the last page.

Formatdate-time
hasMore*boolean
curl -X GET 'https://api.1msg.io/api/v1/inbox/conversations/string/messages'
{  "messages": [    {      "id": "string",      "conversationId": "string",      "channelId": "string",      "direction": "INBOUND",      "type": "TEXT",      "content": "string",      "mediaUrl": "string",      "mediaType": "string",      "fileName": "string",      "fileSize": 0,      "mediaDuration": 0,      "thumbnailUrl": "string",      "templateName": "string",      "templateLanguage": "string",      "status": "PENDING",      "externalId": "string",      "sentAt": "2019-08-24T14:15:22Z",      "deliveredAt": "2019-08-24T14:15:22Z",      "readAt": "2019-08-24T14:15:22Z",      "createdAt": "2019-08-24T14:15:22Z",      "systemEventSource": "string",      "systemEventOperatorName": "string",      "systemEventOperatorEmail": "string",      "assignmentEvent": {        "kind": "assign",        "actor": {          "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",          "name": "QA Stage",          "avatar": null        },        "target": {          "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",          "name": "QA Stage",          "avatar": null        }      },      "author": {        "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",        "name": "QA Stage",        "avatar": null      },      "quotedMessage": {        "id": "string",        "content": "string",        "type": "string",        "direction": "INBOUND",        "contactName": "string",        "contactPhone": "string",        "mediaUrl": "string",        "fileName": "string"      },      "latitude": 0,      "longitude": 0    }  ],  "nextCursor": "2019-08-24T14:15:22Z",  "hasMore": true}
PATCH
/api/v1/inbox/conversations/{conversationId}/assignee

userId is the id from GET /api/v1/inbox/channels/{channelId}/assignees. That person must already be able to open this channel. null clears the assignee. Setting the same assignee does nothing and writes no system message. A real change writes one SYSTEM message.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Path Parameters

conversationId*string

Conversation id

Request Body

application/json
  1. body
userId*|

User id from GET /api/v1/inbox/channels/{channelId}/assignees. Null clears the assignee. The same assignee is a no-op.

Response Body

Updated conversation row.

application/json
  1. response
id*string
channelId*string

Channel id, for example QAF261225002

contactId*string
status*string

The key sets only OPEN or CLOSED. Other values can appear on older rows.

Value in"OPEN""CLOSED""ASSIGNED""RESOLVED""BLOCKED"
assignedTo?|

User id of the assignee. Null when unassigned.

assignedUser?|null
lastMessageAt?|
Formatdate-time
isUnread*boolean
tags*array<string>
lastMessagePreview?string|null
lastMessageType?string|null
lastMessageDirection?|
Value in"INBOUND""OUTBOUND"
lastMessageStatus?string|null
unreadCount*number
isBlocked*boolean
title?|

Custom title. Null until renamed.

lastCustomerMessageAt?|

Last inbound customer message. Used for the WhatsApp service window.

Formatdate-time
createdAt*string
Formatdate-time
updatedAt*string
Formatdate-time
contact?|

Present on GET conversation, list, and search. Absent on block, title, and status writes.

channelType?string

Present on reads.

customerPhone?|

Customer phone taken from the contact.

curl -X PATCH 'https://api.1msg.io/api/v1/inbox/conversations/string/assignee' \  -H 'Content-Type: application/json' \  -d '{  "userId": "66c21609-01ed-4f83-8058-9b6ac090db3f"}'
{  "id": "string",  "channelId": "string",  "contactId": "string",  "status": "OPEN",  "assignedTo": "string",  "assignedUser": {    "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",    "name": "QA Stage",    "avatar": null  },  "lastMessageAt": "2019-08-24T14:15:22Z",  "isUnread": true,  "tags": [    "string"  ],  "lastMessagePreview": "string",  "lastMessageType": "string",  "lastMessageDirection": "INBOUND",  "lastMessageStatus": "string",  "unreadCount": 0,  "isBlocked": true,  "title": "string",  "lastCustomerMessageAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "contact": {    "id": "string",    "phoneNumber": "79001234567",    "name": "string",    "avatar": "string"  },  "channelType": "WABA",  "customerPhone": "string"}
PATCH
/api/v1/inbox/conversations/{conversationId}/status

Send status OPEN or CLOSED in the JSON body. The conversation id alone does not change anything. A change writes a SYSTEM message. The same status again returns 409.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Path Parameters

conversationId*string

Conversation id

Request Body

application/json
  1. body
status*string

OPEN reopens the conversation. CLOSED closes it. Repeating the current value returns 409.

Value in"OPEN""CLOSED"

Response Body

application/json
  1. response
id*string
channelId*string

Channel id, for example QAF261225002

contactId*string
status*string

The key sets only OPEN or CLOSED. Other values can appear on older rows.

Value in"OPEN""CLOSED""ASSIGNED""RESOLVED""BLOCKED"
assignedTo?|

User id of the assignee. Null when unassigned.

assignedUser?|null
lastMessageAt?|
Formatdate-time
isUnread*boolean
tags*array<string>
lastMessagePreview?string|null
lastMessageType?string|null
lastMessageDirection?|
Value in"INBOUND""OUTBOUND"
lastMessageStatus?string|null
unreadCount*number
isBlocked*boolean
title?|

Custom title. Null until renamed.

lastCustomerMessageAt?|

Last inbound customer message. Used for the WhatsApp service window.

Formatdate-time
createdAt*string
Formatdate-time
updatedAt*string
Formatdate-time
contact?|

Present on GET conversation, list, and search. Absent on block, title, and status writes.

channelType?string

Present on reads.

customerPhone?|

Customer phone taken from the contact.

curl -X PATCH 'https://api.1msg.io/api/v1/inbox/conversations/string/status' \  -H 'Content-Type: application/json' \  -d '{  "status": "CLOSED"}'
{  "id": "string",  "channelId": "string",  "contactId": "string",  "status": "OPEN",  "assignedTo": "string",  "assignedUser": {    "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",    "name": "QA Stage",    "avatar": null  },  "lastMessageAt": "2019-08-24T14:15:22Z",  "isUnread": true,  "tags": [    "string"  ],  "lastMessagePreview": "string",  "lastMessageType": "string",  "lastMessageDirection": "INBOUND",  "lastMessageStatus": "string",  "unreadCount": 0,  "isBlocked": true,  "title": "string",  "lastCustomerMessageAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "contact": {    "id": "string",    "phoneNumber": "79001234567",    "name": "string",    "avatar": "string"  },  "channelType": "WABA",  "customerPhone": "string"}

Block the contact

POST
/api/v1/inbox/conversations/{conversationId}/block

No body. Incoming messages from this contact are rejected. Writes a SYSTEM message. Blocking an already blocked contact returns 409.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Path Parameters

conversationId*string

Conversation id

Response Body

application/json
  1. response
id*string
channelId*string

Channel id, for example QAF261225002

contactId*string
status*string

The key sets only OPEN or CLOSED. Other values can appear on older rows.

Value in"OPEN""CLOSED""ASSIGNED""RESOLVED""BLOCKED"
assignedTo?|

User id of the assignee. Null when unassigned.

assignedUser?|null
lastMessageAt?|
Formatdate-time
isUnread*boolean
tags*array<string>
lastMessagePreview?string|null
lastMessageType?string|null
lastMessageDirection?|
Value in"INBOUND""OUTBOUND"
lastMessageStatus?string|null
unreadCount*number
isBlocked*boolean
title?|

Custom title. Null until renamed.

lastCustomerMessageAt?|

Last inbound customer message. Used for the WhatsApp service window.

Formatdate-time
createdAt*string
Formatdate-time
updatedAt*string
Formatdate-time
contact?|

Present on GET conversation, list, and search. Absent on block, title, and status writes.

channelType?string

Present on reads.

customerPhone?|

Customer phone taken from the contact.

curl -X POST 'https://api.1msg.io/api/v1/inbox/conversations/string/block'
{  "id": "string",  "channelId": "string",  "contactId": "string",  "status": "OPEN",  "assignedTo": "string",  "assignedUser": {    "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",    "name": "QA Stage",    "avatar": null  },  "lastMessageAt": "2019-08-24T14:15:22Z",  "isUnread": true,  "tags": [    "string"  ],  "lastMessagePreview": "string",  "lastMessageType": "string",  "lastMessageDirection": "INBOUND",  "lastMessageStatus": "string",  "unreadCount": 0,  "isBlocked": true,  "title": "string",  "lastCustomerMessageAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "contact": {    "id": "string",    "phoneNumber": "79001234567",    "name": "string",    "avatar": "string"  },  "channelType": "WABA",  "customerPhone": "string"}

Unblock the contact

POST
/api/v1/inbox/conversations/{conversationId}/unblock

No body. Messages can be sent and received again. Writes a SYSTEM message. Unblocking a contact that is not blocked returns 409.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Path Parameters

conversationId*string

Conversation id

Response Body

application/json
  1. response
id*string
channelId*string

Channel id, for example QAF261225002

contactId*string
status*string

The key sets only OPEN or CLOSED. Other values can appear on older rows.

Value in"OPEN""CLOSED""ASSIGNED""RESOLVED""BLOCKED"
assignedTo?|

User id of the assignee. Null when unassigned.

assignedUser?|null
lastMessageAt?|
Formatdate-time
isUnread*boolean
tags*array<string>
lastMessagePreview?string|null
lastMessageType?string|null
lastMessageDirection?|
Value in"INBOUND""OUTBOUND"
lastMessageStatus?string|null
unreadCount*number
isBlocked*boolean
title?|

Custom title. Null until renamed.

lastCustomerMessageAt?|

Last inbound customer message. Used for the WhatsApp service window.

Formatdate-time
createdAt*string
Formatdate-time
updatedAt*string
Formatdate-time
contact?|

Present on GET conversation, list, and search. Absent on block, title, and status writes.

channelType?string

Present on reads.

customerPhone?|

Customer phone taken from the contact.

curl -X POST 'https://api.1msg.io/api/v1/inbox/conversations/string/unblock'
{  "id": "string",  "channelId": "string",  "contactId": "string",  "status": "OPEN",  "assignedTo": "string",  "assignedUser": {    "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",    "name": "QA Stage",    "avatar": null  },  "lastMessageAt": "2019-08-24T14:15:22Z",  "isUnread": true,  "tags": [    "string"  ],  "lastMessagePreview": "string",  "lastMessageType": "string",  "lastMessageDirection": "INBOUND",  "lastMessageStatus": "string",  "unreadCount": 0,  "isBlocked": true,  "title": "string",  "lastCustomerMessageAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "contact": {    "id": "string",    "phoneNumber": "79001234567",    "name": "string",    "avatar": "string"  },  "channelType": "WABA",  "customerPhone": "string"}

Rename a conversation

PATCH
/api/v1/inbox/conversations/{conversationId}/title

Body title replaces the conversation title and writes a SYSTEM message.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Path Parameters

conversationId*string

Conversation id

Request Body

application/json
  1. body
title*string

Replaces the dialog title. A system message records the change.

Response Body

application/json
  1. response
id*string
channelId*string

Channel id, for example QAF261225002

contactId*string
status*string

The key sets only OPEN or CLOSED. Other values can appear on older rows.

Value in"OPEN""CLOSED""ASSIGNED""RESOLVED""BLOCKED"
assignedTo?|

User id of the assignee. Null when unassigned.

assignedUser?|null
lastMessageAt?|
Formatdate-time
isUnread*boolean
tags*array<string>
lastMessagePreview?string|null
lastMessageType?string|null
lastMessageDirection?|
Value in"INBOUND""OUTBOUND"
lastMessageStatus?string|null
unreadCount*number
isBlocked*boolean
title?|

Custom title. Null until renamed.

lastCustomerMessageAt?|

Last inbound customer message. Used for the WhatsApp service window.

Formatdate-time
createdAt*string
Formatdate-time
updatedAt*string
Formatdate-time
contact?|

Present on GET conversation, list, and search. Absent on block, title, and status writes.

channelType?string

Present on reads.

customerPhone?|

Customer phone taken from the contact.

curl -X PATCH 'https://api.1msg.io/api/v1/inbox/conversations/string/title' \  -H 'Content-Type: application/json' \  -d '{  "title": "Billing question"}'
{  "id": "string",  "channelId": "string",  "contactId": "string",  "status": "OPEN",  "assignedTo": "string",  "assignedUser": {    "id": "b2bb82f0-2253-4e05-b955-a21f3d699caa",    "name": "QA Stage",    "avatar": null  },  "lastMessageAt": "2019-08-24T14:15:22Z",  "isUnread": true,  "tags": [    "string"  ],  "lastMessagePreview": "string",  "lastMessageType": "string",  "lastMessageDirection": "INBOUND",  "lastMessageStatus": "string",  "unreadCount": 0,  "isBlocked": true,  "title": "string",  "lastCustomerMessageAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "contact": {    "id": "string",    "phoneNumber": "79001234567",    "name": "string",    "avatar": "string"  },  "channelType": "WABA",  "customerPhone": "string"}
GET
/api/v1/inbox/webhook

One HTTPS URL per account. The owner sets it here or in Settings → Developer → API Settings. A user key cannot. When inbox state changes, 1MSG POSTs InboxWebhookEnvelope to that URL. Headers: Content-Type application/json, X-1msg-Event (the type), X-1msg-Delivery (the id), X-1msg-Signature sha256=. Compare the signature with HMAC-SHA256 over the exact request body. Reject a mismatch. This is not the channel webhook. Incoming messages and delivery statuses stay on the channel URL. Delivery does not change the API response. A failed POST is stored as lastDeliveryStatus and lastDeliveryError. Events: inbox.conversation.status_changed — Conversation opened or closed. status is OPEN or CLOSED. data fields: conversationId, channelId, status, previousStatus, actorUserId. inbox.conversation.assigned — An assignee was set. assigneeUserId is the new assignee. data fields: conversationId, channelId, assigneeUserId, previousAssigneeUserId, actorUserId. inbox.conversation.unassigned — The assignee was cleared. assigneeUserId is null. data fields: conversationId, channelId, assigneeUserId, previousAssigneeUserId, actorUserId. inbox.conversation.blocked — The contact was blocked. Incoming messages are rejected. data fields: conversationId, channelId, actorUserId. inbox.conversation.unblocked — The contact was unblocked. data fields: conversationId, channelId, actorUserId. inbox.conversation.title_changed — The conversation title was renamed. data fields: conversationId, channelId, title, previousTitle, actorUserId. inbox.user.invited — The owner invited a user. They are not a member until they accept. data fields: inviteId, email, channelIds, actorUserId. inbox.user.added — The invited person accepted and is now an operator. data fields: memberId, userId, email, channelIds. inbox.user.removed — An operator was removed from the account. data fields: memberId, userId, actorUserId. inbox.user.channels_changed — The channels an operator can open were replaced. data fields: memberId, userId, channelIds, actorUserId. inbox.user.invite_revoked — A pending invite was cancelled before it was accepted. data fields: inviteId, email, actorUserId.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Response Body

application/json
  1. response
url?|

HTTPS URL that receives POST deliveries. Null when no webhook is saved.

secretPrefix?|

First 12 characters of the signing secret. The full secret is not returned here.

createdAt?|
Formatdate-time
updatedAt?|
Formatdate-time
lastDeliveryAt?|

When the last delivery attempt finished.

Formatdate-time
lastDeliveryStatus?|

HTTP status from the last delivery. Null when the request did not get a response.

lastDeliveryError?|

Short error from the last failed delivery.

events*array<>

Every event this webhook can send. Message and delivery-status events stay on the channel webhook.

envelope*

Example of the JSON body 1MSG POSTs. data matches events[].example for the type in the body.

curl -X GET 'https://api.1msg.io/api/v1/inbox/webhook'
{  "url": "https://example.com/1msg/inbox",  "secretPrefix": "whsec_abc123",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "lastDeliveryAt": "2019-08-24T14:15:22Z",  "lastDeliveryStatus": 200,  "lastDeliveryError": "string",  "events": [    {      "type": "inbox.conversation.status_changed",      "description": "Conversation opened or closed. status is OPEN or CLOSED.",      "example": {        "conversationId": "d94a047f-5984-42af-9f89-0f26c7e70ef1",        "channelId": "QAF261225002",        "status": "CLOSED",        "previousStatus": "OPEN",        "actorUserId": "b2bb82f0-2253-4e05-b955-a21f3d699caa"      }    }  ],  "envelope": {    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",    "type": "inbox.conversation.status_changed",    "createdAt": "2019-08-24T14:15:22Z",    "data": {}  }}
DELETE
/api/v1/inbox/webhook

Later inbox changes are not delivered until a URL is saved again.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Response Body

application/json
  1. response
removed*boolean
curl -X DELETE 'https://api.1msg.io/api/v1/inbox/webhook'
{  "removed": true}
PUT
/api/v1/inbox/webhook

Creates the webhook and returns the signing secret once, or updates the URL and keeps the existing secret.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Request Body

application/json
  1. body
url*string

HTTPS endpoint. 1MSG POSTs a JSON event here. Credentials in the URL are rejected.

Response Body

application/json
  1. response
url?|

HTTPS URL that receives POST deliveries. Null when no webhook is saved.

secretPrefix?|

First 12 characters of the signing secret. The full secret is not returned here.

createdAt?|
Formatdate-time
updatedAt?|
Formatdate-time
lastDeliveryAt?|

When the last delivery attempt finished.

Formatdate-time
lastDeliveryStatus?|

HTTP status from the last delivery. Null when the request did not get a response.

lastDeliveryError?|

Short error from the last failed delivery.

events*array<>

Every event this webhook can send. Message and delivery-status events stay on the channel webhook.

envelope*

Example of the JSON body 1MSG POSTs. data matches events[].example for the type in the body.

secret?|

Full signing secret. Present only when the webhook is created or the secret is rotated. Store it. Later reads return secretPrefix only.

created*boolean

True when this call created the webhook. False when it updated the URL or rotated the secret.

curl -X PUT 'https://api.1msg.io/api/v1/inbox/webhook' \  -H 'Content-Type: application/json' \  -d '{  "url": "https://example.com/1msg/inbox"}'
{  "url": "https://example.com/1msg/inbox",  "secretPrefix": "whsec_abc123",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "lastDeliveryAt": "2019-08-24T14:15:22Z",  "lastDeliveryStatus": 200,  "lastDeliveryError": "string",  "events": [    {      "type": "inbox.conversation.status_changed",      "description": "Conversation opened or closed. status is OPEN or CLOSED.",      "example": {        "conversationId": "d94a047f-5984-42af-9f89-0f26c7e70ef1",        "channelId": "QAF261225002",        "status": "CLOSED",        "previousStatus": "OPEN",        "actorUserId": "b2bb82f0-2253-4e05-b955-a21f3d699caa"      }    }  ],  "envelope": {    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",    "type": "inbox.conversation.status_changed",    "createdAt": "2019-08-24T14:15:22Z",    "data": {}  },  "secret": "whsec_example_secret",  "created": true}
POST
/api/v1/inbox/webhook/secret

Returns the new secret once. The previous secret stops verifying deliveries immediately. 404 when no URL is saved.

Authorization

bearer
headerAuthorizationBearer <token>

Key issued in the cabinet: Settings → Developer → API Settings.

Response Body

application/json
  1. response
url?|

HTTPS URL that receives POST deliveries. Null when no webhook is saved.

secretPrefix?|

First 12 characters of the signing secret. The full secret is not returned here.

createdAt?|
Formatdate-time
updatedAt?|
Formatdate-time
lastDeliveryAt?|

When the last delivery attempt finished.

Formatdate-time
lastDeliveryStatus?|

HTTP status from the last delivery. Null when the request did not get a response.

lastDeliveryError?|

Short error from the last failed delivery.

events*array<>

Every event this webhook can send. Message and delivery-status events stay on the channel webhook.

envelope*

Example of the JSON body 1MSG POSTs. data matches events[].example for the type in the body.

secret?|

Full signing secret. Present only when the webhook is created or the secret is rotated. Store it. Later reads return secretPrefix only.

created*boolean

True when this call created the webhook. False when it updated the URL or rotated the secret.

curl -X POST 'https://api.1msg.io/api/v1/inbox/webhook/secret'
{  "url": "https://example.com/1msg/inbox",  "secretPrefix": "whsec_abc123",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "lastDeliveryAt": "2019-08-24T14:15:22Z",  "lastDeliveryStatus": 200,  "lastDeliveryError": "string",  "events": [    {      "type": "inbox.conversation.status_changed",      "description": "Conversation opened or closed. status is OPEN or CLOSED.",      "example": {        "conversationId": "d94a047f-5984-42af-9f89-0f26c7e70ef1",        "channelId": "QAF261225002",        "status": "CLOSED",        "previousStatus": "OPEN",        "actorUserId": "b2bb82f0-2253-4e05-b955-a21f3d699caa"      }    }  ],  "envelope": {    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",    "type": "inbox.conversation.status_changed",    "createdAt": "2019-08-24T14:15:22Z",    "data": {}  },  "secret": "whsec_example_secret",  "created": true}

On this page