The Zendesk Messaging platform APIs and webhooks are strictly versioned to avoid unexpected breaking changes in behavior or API signature. When backwards-incompatible changes are unavoidable, a new version will be released to avoid breaking existing integration patterns. Integrators can then opt in to the new version when ready.

Versioning scheme

The versioning scheme supports a major version number (for example, v2) and sometimes a minor version (for example, v1.1). A minor version bump is used when the behavior or expected payload of an API needs to change in a breaking way, but without fundamental changes to how the APIs are used. On the other hand, a major version bump signals that significant changes to the API have been introduced, such as the removal of APIs, major changes in behavior or payload structure, etc.

The current supported versions are v1, v1.1, and v2. While all three versions are still maintained, new integrations should only be built against the latest v2 API suite, except in cases where no functional parity exists.

API versioning

When making calls to the messaging API, the version of the API is specified in the request path. For example:

POST /v2/apps/{app_id}/conversations/{conversation_id}/messages

For more information on how to call the API, see our API quickstart guide.

Webhook versioning

The version of a webhook determines the structure of the payload your backend will receive, as well as the list of available triggers that you can subscribe to. A webhook's version is determined by the version of the API used to create it. For example, when creating a custom integration using the v2 Create Integration API, the resulting webhook will have a version of v2. To create a v1.1 webhook, use the v1.1 Create Webhook API instead.

For more information on how to use webhooks, see receiving messages.

Backwards compatible changes

We consider the following types of changes to be backwards compatible. In other words, these types of changes do not require a new version of the API, and can occur at any time. When coding your integration with Zendesk Messaging, take care to ensure that the types of changes listed below would not break any assumptions you make in your code.

For example, your JSON parsing logic should be configured not to throw an error when an unexpected key is found, or when an enum contains a previously unknown value. Assume also that any JSON field returned as an array may contain multiple items in the future, even if you only see one array entry in practice.

Additive changes

  • Adding new fields or HTTP headers to existing API responses and webhook payloads
  • Adding new optional fields, query parameters, or HTTP headers to existing API request payloads
  • Adding new API endpoints or adding new methods on existing endpoints e.g. adding support for HTTP PUT to an existing API path
  • Introducing new types of messages, integrations, clients, or any other typed entity without changing the behavior of existing types
    • For example, introducing a new message type of location or a new integration type of twitter. For any code that processes entities with a type property (or equivalent), unknown types should be gracefully handled or ignored
  • Introducing new webhook triggers
    • In v2, webhook triggers must be explicitly selected. However, in v1 and v1.1, the wildcard trigger (*) can be used to subscribe to all available events. When using the wildcard trigger, your code should gracefully handle or ignore any unknown event types
  • Adding support for existing webhook triggers and message types as channels adopt new capabilities
    • For example, to begin delivering conversation:read webhooks for Twitter clients as soon as the channel adopts the read notification capability

Formatting changes

  • Changing the format or length of primary id fields and keys without exceeding 255 characters
    • For example, changing the string format or character length of user.id or key.secret
  • Changing the order of fields in existing API responses and webhook payloads

Relaxing restrictions

  • Increasing the size or length restrictions on arrays or strings, or allowing certain characters which were previously disallowed
  • Accepting upload and transmission of new file and media types that had been previously rejected
  • Allowing new types on existing fields
    • For example, allowing passing null to unset a field such as user.profile.displayName

Error handling

  • Changing the string content of friendly error descriptions
    • For example, changing the message in the error title, or equivalent. Automated error handling behavior should use the error's code, not its friendly description
  • Changing the validation precedence of invalid HTTP requests
    • For example, when sending a request that is both malformed and with invalid auth credentials, we may return either a status code of 400 or 401
  • Promoting unclassified errors into categorized errors
    • For example, for scenarios that return an error code of unhandled_error or uncategorized_error, the error may be changed to a more specific code instead
  • Introducing new classifications of errors
    • For example, in the error code or equivalent. Your code should be able to gracefully handle unknown error code values
  • Changing the HTTP status code of unhandled API errors
    • For example, changing 500 Internal Server Error to something more specific like 400 Bad Request or 401 Unauthorized

Upgrade guides

The guides below outline the breaking changes to be aware of when upgrading versions of the API.

Upgrading from v1.1 to v2

The v2 API is a new set of APIs with extended capabilities to the v1 suite. Many of the existing v1 API endpoints have equivalent v2 API endpoints, however many request and response payloads have been significantly modified in the new API. A summary of the biggest differences is provided below. For more details, consult the documentation of each specific endpoint.

The v2 API was released on 2020-10-01 and includes the following changes from the v1.1 API:

General changes

  • The _id field has been renamed to id
  • JWT scope of appUser is no longer supported for server-to-server calls
  • Support for implicit app ids in request paths (for example, /v1.1/appusers/{id}) has been removed. All app resources are now only accessible with paths including the app id (/v2/apps/:appId/…)
  • Standardized dates and timestamps on various objects into a single common format. All date-related fields should now be returned as strings with the format YYYY-MM-DDThh:mm:ss.SSSZ
  • When the API returns an error, it now provides an errors array in the response instead of an error object
  • Offset-based pagination has been replaced by cursor-based pagination for all endpoints that support pagination
  • Calls to modify a resource now use the PATCH HTTP verb instead of PUT. The behavior remains unchanged between PUT and PATCH
Apps
  • The metadata field now allows partial updates. Values within metadata can now be unset with null
  • The List Apps API now uses cursor-based pagination instead of offset-based pagination
  • The serviceAccountId query parameter used to return only the apps that the service account has access to was replaced by filter[serviceAccountId]
App Keys
Attachments
  • Instead of passing an appUserId or a userId in the query parameters it is now replaced with conversationId
  • mediaUrl and mediaType in the response body have been moved under a top-level object attachment to match the style of other API responses
Clients
Conversations
  • Conversation-related APIs are now pathed under /conversations instead of /appusers, and a conversation id must be supplied instead of a user id
  • Added support for multiple conversations per user, including new endpoints to create, list and delete conversations for a user
  • The concept of participant has been introduced to track a user's membership in a conversation, and which of a user's clients have been subscribed to receive messages in that conversation
  • Added support for conversations between multiple users, including new endpoints to create, list and delete participants for a conversation
  • The message schema has changed significantly when creating and retrieving messages. The previous message structure has been re-organized and composed into multiple top-level objects including author, source, and content. See the message schema changes below for more details
  • The Post Message API now returns an array of messages rather than a single message object and an array of extraMessages
  • The List Messages and Post Message APIs no longer return a conversation object
  • Post Activity API now requires an author object in the body, rather than the previous role field
  • The Reset Unread Count API has been removed in favor of Post Activity API with "author.role": "user"
  • Updated validation on certain fields when posting messages
    1. The actions array now has has a max size of 10, and a minimum size of 1. The field remains optional if no actions are desired for the message
    2. mediaType can no longer be specified when posting a message. The type of the file will always be inferred from the mediaUrl
    3. Extra channel options webview_height_ratio and fallback_url are no longer considered for webview in Facebook Messenger. Use the size and fallback properties of the webview action instead
    4. When specifying a destination, integration types apn and fcm have been replaced by ios and android, respectively
    5. Shorthand syntax will only be parsed in text type messages. Syntax passed in the text field of other message types will be ignored
    6. A more specific invalidFile error will replace the generic badRequest error when invalid media is sent
  • The List Conversations API now uses cursor-based pagination instead of offset-based pagination
Deployments

Removed in v2

Integrations
  • Integrations of type fcm have been replaced by the android type. The senderId and serverKey properties are no longer required when creating an android integration
  • Integrations of type apn have been replaced by the ios type. The certificate property is no longer required when creating an ios integration
  • The new integration type custom has been introduced to replace the functionality of the previous webhooks API suite. All existing webhooks have been automatically upgraded to belong to custom integrations in the API
  • The Create Integration API now supports creating multiple instances of a channel (including all SDKs and third-party channels)
  • When creating or updating an integration, the displayName property (if passed) now has a minimum length of 1
  • The signingKey is now required when creating an integration of type messagebird
  • The List Integrations API now uses cursor-based pagination instead of offset-based pagination
  • The types query parameter used to return only integrations of a specific type was replaced by filter[types]
Messages
  • The List Messages API now follows the v2 style for cursor-based pagination input and output parameters
  • The List Messages API now uses message IDs instead of timestamps as the pagination cursor
Notifications

Not migrated to v2 yet

Persistent Menus

Removed in v2

Service Accounts

Removed in v2

Templates

Not migrated to v2 yet

Users
  • The concept of appUser has been renamed to user in all API paths and request/response bodies
  • Clients of type android, ios and web are now unified under a single client with type sdk. Existing clients have been converted to devices
  • Introduced the concept of devices to replace the per-device tracking of metadata and push notification tokens that used to be handled by SDK clients
  • The /channels APIs have been removed in favor of Create/List/Remove Client APIs
  • The List Clients API must now be used to fetch the list of clients for a given user, and includes both linked clients and pending clients
  • The DELETE /profile endpoint has been renamed to DELETE /personalinformation
  • The metadata field now allows unsetting all its values at once with null
  • Updated validation on certain fields when creating / updating users:
    • The externalId, givenName, surname, email, avatarUrl and signedUpAt fields are validated in regards to their type and length
Webhooks
  • Webhooks are now a sub-property of a new integration type custom. Existing webhooks have been automatically upgraded to belong to custom integrations in the API
  • Integrations of type custom can be created with the Create Integration API, and require a webhooks array to be passed in the request. Once the custom integration is created, webhooks can be modified with the Update Webhook API
  • Every webhook will be assigned a unique id different from the custom integration id, which can be used to update the webhook

Schema changes

App
  • The name field has been renamed to displayName
  • Removed appToken field
App Key
  • The name field has been renamed to displayName
Client
  • platform has been renamed to type
  • A new status of pending has been introduced to distinguish clients that have not been confirmed yet (previously called pendingClients)
  • Removed fields blocked and active which were marked as deprecated in v1.1. Use status instead
  • Removed fields id, deviceId, pushNotificationToken and appVersion. These are now properties of the device schema
  • The primary property is removed. To know the primary client of a user in relation to a conversation, use the List Participants API. The first item of a participant's clientAssociations array represents the primary client
Conversation
  • Added a new type field. Possible values are personal and sdkGroup
  • Removed fields unreadCount and lastRead. Use the equivalent fields of each participant instead
  • Introduced new properties metadata, lastUpdatedAt, displayName and description
  • appMakerLastRead is now a stringified date instead of a unix timestamp
  • appMakerLastRead property was renamed to businessLastRead
Custom Integration Key
  • Change name property to displayName
Destination
  • type has been renamed to integrationType
  • Payloads with a destination object must include either integrationId or integrationType, not both
Device
  • Added device schema
Errors
  • description has been renamed to title
Integration
  • Introduced new types ios, android, and custom
  • Removed apn and fcm as supported types, they are now exposed as ios and android
Message
  • messageSchema field has been renamed to schema
  • received is now a stringified date instead of a unix timestamp
  • authorId has been renamed to userId and is no longer returned for business messages
  • appUser role has been renamed to user
  • appMaker role has been renamed to business
  • Removed email field when posting a message. Use avatarUrl instead
  • The previous message structure has been re-organized and composed into multiple top-level objects
    • A new author object has been introduced replacing the top-level properties role, subroles, name, authorId and avatarUrl. See the Messages section of the v2 API spec for more details
    • id, received, source, destination, metadata, deleted, override, schema, and quotedMessage remain at the root of the message object
    • Most other fields have been moved under a content object
  • The values api and notifications for a message's source.type have been changed to api:conversations and api:notifications respectively
  • Sub-objects within content no longer include an _id (i.e. actions or items)
Participant
  • Added participant schema
Source
  • New fields client and device may now be included in webhook payloads when includeFullSource is enabled for the webhook
  • originalMessageTimestamp is now a stringified date instead of a unix timestamp
User
  • userId has been renamed to externalId
  • properties has been renamed to metadata
  • Removed top-level fields clients and pendingClients. Use the List Clients API instead
  • Removed conversationStarted field
  • Removed credentialRequired field
  • The user will now contain a profile sub-object that holds the givenName, surname, avatarUrl, and email properties
Webhook
  • No longer an app-level concept. Webhooks are now a sub-property of integrations of type custom, or integrations created by OAuth partners
  • version can have a new value v2
  • includeFullAppUser has been renamed to includeFullUser
  • includeClient has been renamed to includeFullSource
  • Removed support for the wildcard trigger (*). Triggers must all be individually selected
  • Updated the schema of all the existing webhooks to include an array of events instead of a single event. See the Webhook Payloads of the v2 API spec for more details
  • Reorganized and renamed the available triggers. Note that v1 webhooks can still be used in combination with the v2 API/webhooks if you need a trigger that has not yet been migrated
v1.x triggerEquivalent v2 triggerNotes
appUser:deleteuser:remove
client:addclient:addThis event is now triggered for the following reasons: upon initiating a channel link, when logging in the sdk for the first time and when initiating an SDK device with an authCode.
client:blockclient:updateThe payload will include a reason with the value blocked.
client:removeclient:removeThe payload now includes the conversation whenever it is available.
conversation:readconversation:read
conversation:referralconversation:referralTriggered in the same cases as v1.x conversation:referral and conversation:start events, except when conversation:create is triggered instead.
conversation:startconversation:createNow triggers when a conversation is created for any reason, not just in response to a start conversation event.

The creationReason may be used to determine why the conversation was created.
link:failureclient:removeThe payload will include a reason with either linkCancelled or linkFailure.
link:matchclient:updateThe payload will include a reason field with the value matched.
link:successclient:updateThe payload will include a reason field with the value confirmed.
merge:appUseruser:merge
message:appMakerconversation:messageSubscribes to both user and business messages.
message:appUserconversation:messageSubscribes to both user and business messages.
message:delivery:channelconversation:message:delivery:channel
message:delivery:failureconversation:message:delivery:failure
message:delivery:userconversation:message:delivery:user
notification:delivery:channelN/ANot migrated to v2 yet.
notification:delivery:failureN/ANot migrated to v2 yet.
notification:delivery:userN/ANot migrated to v2 yet.
passthrough:apple:extensionpassthrough:apple:extension
passthrough:apple:interactivepassthrough:apple:interactive
postbackconversation:postbackThe message and action linked to a postback event are no longer included in the webhook payload.
request:failureN/ANot migrated to v2 yet.
request:successN/ANot migrated to v2 yet.
typing:appUserconversation:typing

Upgrading from v1 to v1.1

The v1.1 API was released on 2018-10-02 and includes the following changes from the v1 API:

Schema changes

Webhooks
  • Webhooks include a version property
  • Removed support for message trigger. Use message:appUser and message:appMaker instead
  • triggers is now a required property when creating a webhook
  • message:appUser events support file messages. Previous versions sent them as text messages
  • postback, conversation:start, message:appUser and message:appMaker events now include truncated appUser schema
  • New message delivery webhooks have been introduced, described below. See the delivery events guide for more details:
    • Removed delivery:success and delivery:failure webhook triggers which are replaced by message:delivery:channel and message:delivery:failure respectively
    • message:delivery:channel triggers when messages are delivered to SDKs.
    • message:delivery:failure can be triggered after a message:delivery:channel event if a message cannot be delivered to the user.
    • message:delivery:user is a new trigger that allows to confirm the delivery of a message to a user for channels that support it.
    • The payloads used to include a list of messages. They now only include one message and only contain an _id property.
    • New properties isFinalEvent and externalMessages are included in these new webhook payloads.
AppUsers
  • API responses no longer include a devices array and a credentialRequired property. devices has been renamed to clients long ago and it was kept in API responses for backwards compatibility only
  • The Link App User To Channel API now requires a confirmation property, and no longer accepts a skipConfirmation property
  • The Pre-Create App User API no longer accepts a credentialRequired property
Conversations

Upgrading webhooks without downtime

To avoid missing messages for apps used in production, the following strategy can be used to upgrade your webhook version without downtime:

  1. Modify your code to support the webhook schema changes mentioned above. You can use the version property included in all event payloads to conditionally execute code based on the webhook version. Your code should be capable of receiving both webhook versions, while ignoring the newer version for now.
  2. Once changes from step (1) are deployed, create a custom integration with the new version with the equivalent triggers as the webhook you wish to upgrade.
  3. With both webhooks running, write and deploy code to accept payloads with the new version and ignore those with the old version.
  4. Once you are satisfied with the webhook upgrade, remove the webhook with the old version.
  5. At this point you may remove code specific to the old version.

Steps 2-5 should be tested in a non-production environment before they are applied to your production environment.