This feature has not been released publicly, and we politely request that you treat everything in this document as confidential.

All details outlined in this document are in beta. We may change the timeline, APIs, and functionality based on feedback from pilot testers like yourself, so you should be prepared to update your code accordingly.

Calls API

This is a preliminary draft spec for a new calls API. As we are in a pre-release phase, this is subject to change.

Feature Overview

Our intent with this API is to expose the same Slack UI surfaces to partner video conferencing applications as provided to our native Slack calls feature. The first iteration primarily focuses on the “call object” which is the message-like object dropped in a Slack channel to represent an ongoing or ended call. It will contain information relevant to the call, such as its title and start time, and will update participant details in real-time.

Creating a Calls App

In order for your calls app to write to the calls API, it needs the calls:write scope. Other suggestions and requirements for apps are outlined in our app guide.

Updating your Calls App to prepare for new phone features

Use the field desktop_app_join_url in both the calls.add and calls.update API to indicate the url used to launch your desktop app. This url should begin with your_call_app_url:// or any other similar URL that supports directly launching their desktop app.

The Slack client will use this field to launch your company's desktop app directly if it is already installed on a user's computer.

If a desktop_app_join_url is not provided or your app is not installed, the default behavior of opening the call_initiation_url in a browser tab will remain in place.

Working with the call button

When a call initiator clicks the call button in the Slack desktop or web client, Slack will send a HTTP POST request containing metadata of the calls request to your app’s preconfigured, whitelisted calls endpoint.

The calls app should then:

  1. Respond to the request with a URL to start a call
  2. Call calls.add to create the call object
  3. Post that object to channel.

Responding to the call button request

The HTTPS request Slack sends to your Calls endpoint will contain a payload similar to that of a slash command. This data will be sent to your URL as a HTTP POST request with a Content-type header set as application/x-www-form-urlencoded

Example payload:

{
    "token": "<verification token>",
    "team_id": "T12AES3D",
    "team_domain": "my-team",
    "channel_id": "C0231S23",
    "channel_name": "test",
    "user_id" : "U2144YR97",
    "user_name": "mattjones",
    "response_url":"https://slack.com/callback/123xyz"
}

Upon receiving the call request, the app must respond with a call initiation URL synchronously within 3 seconds. This specified URL will be automatically opened for user who has initiated the call in a separate window.

desktop_protocol_call_initiation_url is an optional field, representing a custom url scheme that will be used to launch the calls app directly. If it is not available in the response then Slack will fallback by launching call_initiation_url in a new browser window.

Example response:

{
    "response_type":"call",
    "call_initiation_url":"https://join.call.com/123456",
    "desktop_protocol_call_initiation_url": "call://join&room_id=123456"
}

Slack uses the type field in the request payload https:/your_company_url/your/call_url to indicate the type of call:

type: audio or video

If type=video then send the URL for initiating a video call or meeting:

{
    ...
	"type": "video"
    ...
}

If type=audio request payload will have additional phone_number field, then send the URL for initiating a phone call:

{
    ...
	"type": "audio",
	"phone_number": "+1-202-555-0145",
    ...
}

Example response:

{
	"response_type": "audio",
	"call_initiation_url": "https://your_company_url/...",
	"desktop_protocol_call_initiation_url": "your_call_app_url://+1-202-555-0145"
}

phone_number (optional)

A phone number is included when sending the audio type as an optional parameter/

Working with MPDMs and DMs

Your app might not have a user token, which is typically required for posting messages to private channels, MPDMs or DMs, in order to post a call block via the usual chat.postMessage method. You can work around this by utilizing the in_channel slash command response type. This will allow your app to post a message directly to the channel the slash command request originated from, which can include a call block.

Call calls.add

Create the call object with the calls.add method as detailed here

Posting the Call to the Channel

Once the call starts, you should let other users in the channel know so that they can join the call as well. Post the call object returned by calls.add into the channel the call initiator started the call in using the provided response_url

Note that the top-level "text" field ensures that notifications on desktop and mobile apps have text, as call blocks do not appear in these notifications.

{
    "response_type": "in_channel",
    "text": "A new call was started by <name of call provider>",
    "blocks": [{
        "type": "call",
        "call_id": "R123",
    }]
}

API Reference

Events

Events sent from the Slack service to the call provider’s Slack integration


Slash command

An HTTP POST request is sent when the user invokes a slash command (e.g. /my_favorite_calling_service) or presses the Slack call button, as described here.

When receiving this event, the call provider should allocate a meeting/call ID, and return information via the calls.add method.

If the provider is not able to create a call because the user needs to first authenticate, then the user should be prompted to log in or start the OAuth process. After authentication is complete, the provider should initiate a call and send connection information in a calls.add method.

Learn how to respond to slash commands in DMs and MPDMs


The existing link_shared method is sent when a link from a specified domain is shared. Call Apps should respond to this event with the calls.add method to register the call, and then invoke the chat.unfurl method, which will cause a call object to appear in channel, already populated with the call duration and participants.

calls.add will return a call id that looks like Rxxx.

Next, call chat.unfurl and supply your call id:

{
    "token": "xxxx-xxxxxxxxx-xxxx",
    "channel": "Cxxx",
    "ts": "ts",
    "unfurls": {
        "https:\/\/url.to\/your\/call": {
            "blocks": [{
                "type": "call",
                "call_id": "Rxxx"
            }]
        }
    }
}

Read more in in the registering your domain section of this doc.

Image of a call object generated from a link


call_rejected

If a call has been shared with a user in DM using the link_shared method, and the user rejects the call, Slack will inform the call provider via this event.

Argument Example Description
type call_rejected The type of event—in this case call rejected
call_id 123-456 call provider ID
user_id U123 User who rejected the DM call
external_unique_id 123-456-7890 ID of the external call
channel_id DL5JN9K0T The channel that contains the call being rejected

Example:

{
    "token": "12345FVmRUzNDOAuy4BiWh",
    "team_id": "TL1BBBQBD",
    "api_app_id": "BBBU04BB4",
    "event": {
        "type": "call_rejected",
        "call_id": "RL731AVEF",
        "user_id": "ULJS1TYR5",
        "channel_id": "DL5JN9K0T",
        "external_unique_id": "123-456-7890"
    },
    "type": "event_callback",
    "event_id": "EvLLACMB6BB",
    "event_time": 1563448153,
    "authed_users": ["UBBB1TYR5"]
}

Image of a rejected call


Methods

Slack API Methods called by the call provider’s Slack integration

calls.add

This method is called with connection information required for the Slack client to connect the user to a Platform call.

Return value: This method returns the call object json, of which only the id must be supplied when invoking calls.end, calls.participants.add, calls.participants.remove, and other methods that refer to this call. Example return value:

{
    "ok": true,
    "call": {
        "id": "R0120388",
        "date_start": 1562002086,
        "external_unique_id": "025169F6-E37A-4E62-BB54-7F93A0FC4C1F",
        "join_url": "https://example.com/calls/1234567890",
        "external_display_id": "705-292-868",
        "title": "Daily sync up",
        "users": [
            {
                "slack_id": "U0MQG83FD"
            },
            {
                "external_id": "54321678",
                "display_name": "External User",
                "avatar_url": "https://example.com/users/avatar1234.jpg"
            }
        ]
    }
}

In order to update the join_url or the name, use the calls.update method.

Argument Example Required Description
token xxxx-xxxxxxxxx-xxxx Required Authentication token bearing required scopes.
external_unique_id uuid Required This id is provided by the call provider, and must be unique across all calls from that service.
external_display_id 123-456 Optional
join_url https://url.to/your/call Required
start_time 1532627506 Optional This information is necessary to display the ongoing duration of the call in the call object. If start_time is not provided, the start_time is assumed to be the time that this method was invoked.

This should be a UNIX/epoch timestamp in UTC, similar to other timestamps used by the Slack API. The “1532627506” example string corresponds to “July 26th, 2018 at 17:51:46 UTC”.
title Daily Standup Optional If the call is renamed, calls.add might be invoked again in order to update the call object.
created_by U2144YR97 Optional The ID of the User who has started this call. This field can be populated using user_id sent in the HTTPS call made by Slack to your Calls Endpoint.
users array of user objects (example below) Optional Send if this call is already in progress. The format of the participants array is the same as the calls.participants.add method, and more documentation is available there.

Image of an added call


calls.update

This method updates information about calls already started and registered via calls.add.

The fields which may be provided for update are title​ and join_url​, described in calls.add​.


calls.info

This method returns information about a call. It requires token and the id of the call being queried.


calls.participants.add {#calls.participants.add}

This method is sent from the call provider’s Slack integration when a new user joins a call.

If the call provider knows the Slack user ID of the participant, they may provide it, so Slack can show their name and avatar in the call object. If the Slack user ID is unknown, a user name can be provided instead for display in the call object, along with a URL for the avatar image.

What the user sees: The call object will be updated to show the user who joined the call. If Slack have the user’s Slack ID, then Slack can show their avatar on the call object.

Argument Example Required Description
token xxxx-xxxxxxxxx-xxxx Required Authentication token bearing required scopes.
id slack_call_id Required This is the Slack call ID, which is returned by calls.add
users array of user objects (example below) Required* If the call provider can’t provide the Slack user_id, then they still need to provide a platform-specific user id, along with a display_name
users example
[
    {
        "slack_id": "U1H77"
    },
    {
        "external_id": "54321678",
        "display_name": "External User",
        "avatar_url": "https://example.com/users/avatar1234.jpg"
    }
]

calls.participants.remove

Removes participants from the call object when they leave the call.

Argument Example Required Description
token xxxx-xxxxxxxxx-xxxx Required Authentication token bearing required scopes.
id slack_call_id Required slack_call_id returned by calls.add
users array of user objects (example below) Required

users example

[
    {
        "slack_id": "U1H77"
    },
    {
        "external_id": "54321678",
        "display_name": "External User",
        "avatar_url": "https://example.com/users/avatar1234.jpg"
    }
]

calls.end

The provider notifies Slack that the call has ended with this method. When received, the call object will gray out so no other users can try to join the call.

Argument Example Required Description
token xxxx-xxxxxxxxx-xxxx Required Authentication token bearing required scopes.
id slack_call_id Required slack_call_id returned by calls.add
duration 65 Optional Duration in seconds. The call provider can optionally provide the exact duration of a call, which would show in the call object. If this value is not provided, then Slack will calculate call duration, using the time this method was invoked as the call end time.

Image of a call that has ended

Errors

Error Description
internal_error An unexpected exception with the service has occurred.
invalid_start_time The start time is invalid.
not_authorized User not authorized to create a call in this channel
not_authed No authentication token provided.
invalid_auth Some aspect of authentication cannot be validated. Either the provided token is invalid or the request originates from an IP address disallowed from making the request.
account_inactive Authentication token is for a deleted user or workspace.
token_revoked Authentication token is for a deleted user or workspace or the app has been removed.
no_permission The workspace token used in this request does not have the permissions necessary to complete the request. Make sure your app is a member of the conversation it's attempting to post a message to.
org_login_required The workspace is undergoing an enterprise migration and will not be available until migration is complete.
ekm_access_denied Administrators have suspended the ability to post a message.
missing_scope The token used is not granted the specific scope permissions required to complete this request.
invalid_arguments The method was called with invalid arguments.
invalid_arg_name The method was passed an argument whose name falls outside the bounds of accepted or expected values. This includes very long names and names with non-alphanumeric characters other than _. If you get this error, it is typically an indication that you have made a very malformed API call.
invalid_charset The method was called via a POST request, but the charset specified in the Content-Type header was invalid. Valid charset names are: utf-8 iso-8859-1.
invalid_form_data The method was called via a POST request with Content-Type application/x-www-form-urlencoded or multipart/form-data, but the form data was either missing or syntactically invalid.
invalid_post_type The method was called via a POST request, but the specified Content-Type was invalid. Valid types are: application/json application x-www-form-urlencoded multipart/form-data text/plain.
missing_post_type The method was called via a POST request and included a data payload, but the request did not include a Content-Type header.
team_added_to_org The workspace associated with your request is currently undergoing migration to an Enterprise Organization. Web API and other platform operations will be intermittently unavailable until the transition is complete.
invalid_json The method was called via a POST request with Content-Type application/json, but the body was not valid JSON.
json_not_object The method was called via a POST request a valid JSON body, but the JSON value was not an object.
request_timeout The method was called via a POST request, but the POST data was either missing or truncated.
upgrade_required The calling application needs to be upgraded.
fatal_error The server could not complete your operation(s) without encountering a catastrophic error. It's possible some aspect of the operation succeeded before the error was raised.
Empower builders in your workspace
Build functions your coworkers can remix in their workflows