# Open Channels Deliver notifications to any platform that can accept a JSON payload, without requiring an Airship SDK. # Getting Started > Set up your webhook server and Airship before sending your first push notification.*Open Channels* support notifications to any medium that can accept a JSON payload, through either the Airship API or web dashboard. Unlike natively supported channels such as iOS, Android and web, Open Channels are not backed by an Airship SDK. In the absence of an SDK, it's up to you, the developer, to **A)** register end users with our [Open Channels API](https://www.airship.com/docs/developer/rest-api/ua/operations/open-channels/) and **B)** determine how to parse and display the notification payloads in the available interface. Registering a user returns a [Channel ID](https://www.airship.com/docs/reference/glossary/#channel_id). Leverage features such as segmentation, scheduling, and local time delivery, while sending notifications to any messaging channels you choose. You can send to natively supported channels, e.g., Android or iOS, and open messaging channels in combination or in isolation, using our familiar `device_types` selector and platform-specific payloads. Open Channels is an extension of the Channels API. See the [Intro to Channels](https://www.airship.com/docs/guides/getting-started/developers/channels-intro/) for more information. > **Tip:** If you use an AI coding assistant, you can connect it to Airship with Skills and an MCP server. See [Airship AI Tools](https://www.airship.com/docs/developer/ai-tools/ai-tools/). ## API Resources * [Intro to Channels](https://www.airship.com/docs/guides/getting-started/developers/channels-intro/) * [Open Channels API Reference](https://www.airship.com/docs/developer/rest-api/ua/operations/open-channels/) * [Open Channels Platform Override API Reference](https://www.airship.com/docs/developer/rest-api/ua/schemas/platform-overrides/) These are the steps to setting up your open channels integration: 1. Set up your webhook server. 1. Configure your new webhook in the Airship dashboard. 1. Register a channel to your Open Platform. 1. Send a push. ## Set Up Your Webhook Server > **Important:** You need to do this first because the Open Channel configuration in the next > step requires your webhook URL. **The webhook server must:** 1. Accept HTTPS connections. Accepted Cipher Suites: * TLS_CHACHA20_POLY1305_SHA256 * TLS_AES_256_GCM_SHA384 * TLS_AES_128_GCM_SHA256 * TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 1. When receiving an authorized `GET` request to `/validate`: * Return a 200 response code. * Return a `Content-Type` of `"application/json"`. * Return a JSON body with the form: `{"confirmation_code":"559384cd-6284-4e3e-9e4e-7c260019a251"}`. 1. When receiving an authorized POST request to `/push`: * Return a 200 response code. **The webhook server should:** 1. Expect to process payloads in the format of the samples below. 1. Point to an array of Send Objects with the top level `"values"` key. **Send Object:** `"send_id"` : Required, UUID uniquely identifying the send. Can be used for de-duplication in the event of a retry, logging, or tracing. `"app_key"` : Required, the 22-character identifier of the Airship project associated with the open channel. `"target"` : Required, a Target Object with the following attributes: * `"address"` Required, string. The address of the open channel. * `"channel_id"` Required, the Airship Channel ID of the Open Channel. * `"identifiers"` Optional, an Object with up to 100 string:string identifiers associated with the Open Channel. `"payload"` : Required, a Payload Object with the following attributes: * `"alert"` Required, string. The alert message for the notification. * `"title"` Optional, string. Optional title, useful for email subject lines or headers. * `"extra"` Optional, an object of user-supplied string:string key:value pairs associated with the push. **Sample Payload** ```json { "values": [ { "send_id": "ff76bb85-74bc-4511-a3bf-11b6117784db", "app_key": "YOUR_APP_KEY", "target": { "address": "SOME_INTERNAL_ID", "channel_id": "a61448e1-be63-43ee-84eb-19446ba743f0", "identifiers": { "cid": "1234567", "com.example.token": "a61448e1-be63-43ee-84eb-19446ba743f0" } }, "payload": { "alert": "Giant StayPuft Marshmallow Man On a Rampage", "title": "Breaking News!", "extra": { "url": "https://www.example.com/" } } }, { "send_id": "647e799e-3b15-46f0-b4f1-12360d51ce4a", "app_key": YOUR_APP_KEY", "target": { "address": "SOME_OTHER_INTERNAL_ID", "channel_id": "5b7e9f63-df28-43f4-8182-b762c628c4c4", "identifiers": { "cid": "7654321", "com.example.token": "503640e8-88f7-4dee-9245-7479ac1a8501" } }, "payload": { "alert": "Giant StayPuft Marshmallow Man On a Rampage", "title": "Breaking News!", "extra": { "url": "https://www.example.com/" } } } ] } ``` ### Signature Hash and Security {#signature-security}

Rather than basic authentication, you can configure a signature that your webhook server can use to verify that requests come from Airship. To enable this signature, select Signature Hash authorization and set a secret_key when configuring your webhook or open channel.

When you enable and set a secret_key, outgoing requests include a hash-based authentication code computed using the sha256 hash function in an X-UA-SIGNATURE header. You can use this same algorithm to verify the signature on the receiving server.

X-UA-SIGNATURE is composed of the secret_key and a message, both of which must be UTF-8 encoded. The message is a concatenation of the following string values:

To prevent replay attacks, you should validate the X-UA-TIMESTAMP within a threshold of the current time. We recommend that you use a 5-minute threshold to account for time drift, though Airship uses NTP and we recommend that your webhook server does the same. To prevent timing attacks, you should employ a constant time-compare function when checking signatures.

**Request headers with secret key** ```http POST /yourWebhookServer/push HTTP/1.1 Content-Type: application/vnd.urbanairship+json; version=3 Content-encoding: gzip X-UA-TIMESTAMP: 1536947409 X-UA-SIGNATURE: 68688b9dbd5c381851d3cd51dba3093c6633ceef58e6fee6ad4757f857f59aea Data-Attribute: values ``` ## Airship Setup Begin by configuring your new webhook in the dashboard. 1. Next to your project name, select the dropdown menu (▼), then **Settings**. 1. Under **Channels**, select **Open Channels**. 1. Click **+ Configure new Open Channel** and complete the form. All fields are required. * **Display Name:** Enter a user-friendly name for the channel, e.g., "Alexa," "Smart Toaster Dev." This is the name of the channel as it will appear in the Airship dashboard. * **Name:** Enter a name indicative of the platform, e.g., `slack` or `sms`. This is the canonical name that will be used for programmatic use through our API. 20-character maximum. A-Z, a-z, 0-9, _, and - only. * **Webhook URL:** Enter the URL + path to which we will deliver message payloads, e.g., `https://example.com/api/channels/production`. * **Authentication:** Select the authentication mechanism for your webhook server. * **None** * **Basic:** Enter the username and password for the webhook server. * **Signature Hash:** Enter a secret key for use as a part of the `X-UA-SIGNATURE` header. See [Signature Hash and Security](https://www.airship.com/docs/developer/api-integrations/open/getting-started/#signature-security) for more information. 1. Click **Save**. After saving, a Validation Code field appears, containing a 36-character UUID. This code must be returned by the webhook server at `/validate`. See: [Set Up Your Webhook Server](#set-up-your-webhook-server). ![Validation code displayed after saving an open channel configuration](https://www.airship.com/docs/images/services-open-channels-code_hu_ed7ff784ac293292.webp) *Validation code displayed after saving an open channel configuration* 1. Check the *Enabled* box to enable the open channel for use, then click **Update**. > **Important:** If the channel > is not enabled, you will be able to register a new open > channel with the corresponding platform type, but you will not be able to > send a push to that platform using our API. > **Note:** We do not validate the endpoint until you enable and save the configuration. We will revalidate it each time you update the configuration, as long as it remains enabled. ## Register a Channel to Your Open Platform Next, you'll need to populate your audience in our system. This registration step is handled automatically in our mobile and web SDKs, but you are responsible for populating the Airship system with users on open platforms. You can register channels using [Create and Send](https://www.airship.com/docs/reference/glossary/#create_and_send) or by sending a request to the [Open Channel Registration API](https://www.airship.com/docs/developer/rest-api/ua/operations/open-channels/#createorupdateopenchannel). When using the Open Channel Registration API, the request body must contain the following keys: `"type"` : Required, string. Currently the only only valid value for `type` is `"open"`. `"opt_in"` : Required, boolean. A flag to determine if the owner of this device still wants to receive notifications. If false, no open channels payloads will be delivered to the webhook for this channel. `"address"` : Required, string. The primary identifier of a record. For example, in an SMS integration, it could be the end user's phone number. 128 character maximum. `"tags"` : Optional, array of strings. Can be used for audience segmentation. `"timezone"` : Optional, string. An IANA tzdata identifier for the timezone as a string, e.g., `"America/Los Angeles"`. Will set the `timezone` tag group tag with the specified value. `"locale_country"` : Optional, string. The two-letter country locale short code. Will set the `ua_locale_country` tag group to the specified value. `"locale_language"` : Optional, string. The two-letter language locale short code. Will set the `ua_locale_language` tag group to the specified value. `"open"` : Required, object. Open Platform Options Object. Contains the following keys: * `"open_platform_name"`: Required, string. The name of the open platform to which you are registering this channel. * `"identifiers"` - Optional map of string values. These will be delivered in open channels payloads, but cannot be used for segmentation. Maximum of 100 pairs of string values. This map should be exhaustive whenever this key is present. Values will not be unioned with existing identifiers; they will replace them. **Sample Payload** ```json { "channel": { "type": "open", "opt_in": true, "address": "Number Four", "tags": [ "toaster", "caprica" ], "timezone": "America/Los_Angeles", "locale_country": "US", "locale_language": "en", "open": { "open_platform_name": "cylon", "identifiers": { "model": "4" } } } } ``` ## Push To Your New Channel To push to your channel, simply push like you would to any other channel, using the `open_channel` identifier as your audience selector. See [Audience Selection](https://www.airship.com/docs/developer/rest-api/ua/schemas/audience-selection/#audienceselector1000) for more detail. The key difference in an Open Channels API push is the namespacing of the `device_types` identifier for your configured platform. Prepend the new `device_types` identifier with `open::`, e.g., for your new toaster's channel, use `"open::toaster"`. **Example Request** ```json { "notification": { "alert": "Pop!" }, "audience": { "open_channel": "32c99a88-0df1-4eed-9ac3-abc8ee5314ed" }, "device_types": [ "open::toaster" ] } ``` ### Associate a Named User You can also associate your channel with a [Named User](https://www.airship.com/docs/reference/glossary/#named_user) using the [Association](https://www.airship.com/docs/developer/rest-api/ua/operations/named-users/#associatenameduser) endpoint, and then use that for targeting. **Associate Channel ID with Named User** ```http POST /api/named_users/associate HTTP/1.1 Authorization: Basic Accept: application/vnd.urbanairship+json; version=3 Content-Type: application/json { "channel_id": "5b7e9f63-df28-43f4-8182-b762c628c4c4", "named_user_id": "igorstravinsky" } ``` ### Fan out Now that you have registered your channel, and mapped a Named User to it, you need only target the named user and enumerate the configured `device_types` on which you would like to reach your Named User. The Named User mapping will fan out to all devices on supported platforms for the given Named User. **Fan out a message to all devices associated with the Named User** ```json { "notification": { "alert": "Pop!" }, "audience": { "named_user": "igorstravinsky" }, "device_types": [ "ios", "android", "open::toaster" ] } ``` ### View Send Counts After you've sent a push notification to your open channel, use the [Push Response Report](https://www.airship.com/docs/guides/reports/engagement/#push-response) endpoint to retrieve send counts broken out by open platform. **Example Push Response. Use the ``push_id`` in your request** ```json { "ok": true, "operation_id": "6b5e94f5-9c85-486a-a76e-67d18b3eaf05", "push_ids": [ "362b7e8d-af82-4a67-ac76-49e5ea2f7f59" ], "message_ids": [], "content_urls": [] } ``` **Response API request, using ``push_id`` from previous example** ```http GET /api/reports/responses/362b7e8d-af82-4a67-ac76-49e5ea2f7f59 HTTP/1.1 Authorization: Basic ``` **Example response returns the ``open_channels_sends``, broken out by open platform** ```json { "push_uuid": "362b7e8d-af82-4a67-ac76-49e5ea2f7f59", "push_time": "2017-08-08 16:41:59", "push_type": "SEGMENTS_PUSH", "direct_responses": 0, "sends": 0, "open_channels_sends": { "platforms": [ { "id": "sms", "sends": 1 }, { "id": "toaster", "sends": 1 } ] } } ``` # Use Cases > Explore common use cases for Open Channels.

The simplest use case for a notification is the one we are all familiar with: displaying the text of an alert. But there are many other uses for a notification payload, which, depending on the target interface or OS, may be handled in different ways. For example, our SDKs for iOS and Android support the interactive features of those operating systems through our API. Our API also supports an extra field, which lets you to pass any key/value pair to handle how you see fit, e.g., update a config file or trigger a different process.

An open channel can be any non-native platform or interface where you’d like to reach users, or for that matter any client capable of receiving a payload over the Internet. The end message doesn’t need to be human-readable alert text as you might see on an iPhone. Alerts are usually intended for people, but in the case of a machine, you could tell it to update its firmware, increment a counter in a database, or perform some other action. Use cases include:

  • Automated Slack Message using Slack incoming webhooks
  • Chatbot notifications
  • Firmware updates for IOT devices
  • Integrate with third-party messaging APIs, e.g., Twitter
# Integration Points > A new Open Channel requires three integration points.There are three integration points required to set up a new Open Channel: 1. **Webhook Server**
Accepts the Airship Open Channels payload, translates and routes your request. 1. **Channel Registration API**
Because Open Channels aren't supported by a client SDK, you must register new open channels in the Airship system directly. 1. **Push API**
Deliver message payloads using our [API](https://www.airship.com/docs/developer/rest-api/ua/), specifying open channels in your request. # Open Delivery Payload > View webhook request body examples and details for Open Channels.## Webhook POST Request Body The request body itself is a JSON object containing a single top level key, `"values"`, pointing to an array of up to 1,000 JSON objects. Airship will break up large pushes into groups of 1,000. Keys for each object in the array: * `"send_id"` — Required, a UUID version 4 string. Uniquely identifies the object. * `"app_key"` — Required, a 22-character string containing the characters: [-_A-Za-z0-9]. * `"payload"` — Required, a push payload with all `"open"` overrides for the delivery type applied. * `"target"` — Required, a target object containing the `address` and a string->string map of alternative identifiers. * `"push_id"` — Optional, a UUID version 4 string. Uniquely identifies the push. **An example request body with two objects, each containing all possible keys** ```http POST /hooks/ua/example_hook/push HTTP/1.1 Content-encoding: gzip Data-Attribute: values Content-Type: application/vnd.urbanairship+json; version=3 { "values": [ { "send_id": "ff76bb85-74bc-4511-a3bf-11b6117784db", "app_key": "YOUR_APP_KEY", "target": { "address": "221B Baker Street", "channel_id": "a61448e1-be63-43ee-84eb-19446ba743f0", "identifiers": { "cid": "1234567", "com.example.test_token": "a61448e1-be63-43ee-84eb-19446ba743f0" } }, "payload": { "alert": "Giant StayPuft Marshmallow Man On a Rampage", "title": "Breaking News!", "extra": { "url": "https://www.example.com/" } } }, { "send_id": "647e799e-3b15-46f0-b4f1-12360d51ce4a", "app_key": "YOUR_APP_KEY", "target": { "address": "1600 Pennsylvania Avenue", "channel_id": "5b7e9f63-df28-43f4-8182-b762c628c4c4", "identifiers": { "cid": "7654321", "com.example.test_token": "503640e8-88f7-4dee-9245-7479ac1a8501" } }, "payload": { "alert": "Giant StayPuft Marshmallow Man On a Rampage", "title": "Breaking News!", "extra": { "url": "https://www.example.com/" } } } ] } ``` **An example request body with one object, containing only the required keys** ```http POST /hooks/ua/example_hook/push HTTP/1.1 Content-encoding: gzip Data-Attribute: values Content-Type: application/vnd.urbanairship+json; version=3 { "values": [ { "send_id": "ff76bb85-74bc-4511-a3bf-11b6117784db", "app_key": "YOUR_APP_KEY", "target": { "address": "test@example.com", "channel_id": "a61448e1-be63-43ee-84eb-19446ba743f0", }, "payload": { "alert":"Giant StayPuft Marshmallow Man On a Rampage", } } ] } ``` ## Target Object Information pertaining to the target related to a webhook payload is defined under the `"target"` key in each response item. Keys for each target object: * `"channel_id"` — Required, string. The channel identifier for the target. * `"address"` — Required, string. The customer-provided delivery address for the target. * `"identifiers"` — Optional, a JSON object with identifiers specified by the app. Common uses are IDFA or the primary key in your CMS. The values of the keys and values in this object are up to you, however Airship may make additional functionality available using keys prefixed with "com.urbanairship." so keys using that prefix should be avoided. * `"opt_in"` — Optional, boolean. True if the target has opted in, false otherwise. **Example target object** ```json { "identifiers": { "com.urbanairship.aaid": "94b0c28e-0f00-4601-af28-e70322f46a75", "friend": "ship", "ice": "cream", "session_id": "5abe6b52-7dcf-4fec-b0a5-d24cb4deaafe", "com.urbanairship.limited_ad_tracking_enabled": "false" }, "channel_id": "1e215090-e692-4d89-ab7f-1f2ace2a229b", "address": "+1 5558675309" } ``` ## Payload Object The payload to deliver to the target. Possible keys: * `"alert"` — Required, string. The primary message to deliver to the target. * `"title"` — Optional, string. The title of the payload. A good example use case would be an email header for an open email notification. * `"extra"` — Optional, a string-to-string map of additional values to deliver to the target. Can contain any additional information that users want to deliver to the target. * `"summary"` — Optional, string. A text summary of the payload contents, as supplied in the push. * `"media_attachment"` — Optional. A URL for an image or video to include with the payload. * `"interactive"` — Optional. An interactive payload object.