This guide helps Twilio customers implement A2P Messaging for Brands, Campaigns, and 10DLC Phone Numbers. It details how to subscribe to and receive notifications on status changes using Twilio's Event Streams feature. By setting up a Sink (in this case, a webhook), users can receive real-time updates on Brand or Campaign submissions, approvals, rejections, and phone number status changes in the A2P registration process.
This document covers the following:
To set up webhook Sinks and event subscriptions via the Event Streams API, follow these steps:
Independent Software Vendors (ISVs) managing separate subaccounts for each client must configure the Event Stream (Sink and Subscription) individually for each subaccount.
Create a new Sink by making a POST/create
call to the sinks
endpoint of the Events API.
Sinks are destinations for events from a subscription. Each Sink has these properties:
sink_type
: currently supports three types: AWS Kinesis (
kinesis
), Webhooks (
webhook
), and Segment (
segment
).
sink_configuration
: defines the setup; see below.
description
: a friendly name.
If configuring for a secondary customer whose Profile/Brand/Campaign is in a subaccount, use its account_sid
and auth_token
for this and the Subscription creation call in Step 1.3.
sink_configuration
varies by Sink type. For Webhooks, it looks like this:
1"sink_configuration": {2"destination": "http://example.org/webhook",3"method": "<POST|GET>",4"batch_events": <true|false>5}
Parameter | Description |
---|---|
destination | The customer's URL endpoint, e.g., http://example.org/webhook |
method | The HTTP method for the webhook. Options are GET and POST . |
batch_events | Set to false for single events and true for batched events. Batch limit is 64kB. |
The sid
returned from this call is used as the sink_sid
in Step 1.3.
1// Download the helper library from https://www.twilio.com/docs/node/install2const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";34// Find your Account SID and Auth Token at twilio.com/console5// and set the environment variables. See http://twil.io/secure6const accountSid = process.env.TWILIO_ACCOUNT_SID;7const authToken = process.env.TWILIO_AUTH_TOKEN;8const client = twilio(accountSid, authToken);910async function createSink() {11const sink = await client.events.v1.sinks.create({12description: "My A2P Sink",13sinkConfiguration: {14destination: "http://example.org/webhook",15method: "<POST|GET>",16batch_events: "<true|false>",17},18sinkType: "webhook",19});2021console.log(sink.dateCreated);22}2324createSink();
1{2"status": "initialized",3"sink_configuration": {4"arn": "arn:aws:kinesis:us-east-1:111111111:stream/test",5"role_arn": "arn:aws:iam::111111111:role/Role",6"external_id": "1234567890"7},8"description": "My A2P Sink",9"sid": "DGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",10"date_created": "2015-07-30T20:00:00Z",11"sink_type": "webhook",12"date_updated": "2015-07-30T20:00:00Z",13"url": "https://events.twilio.com/v1/Sinks/DGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",14"links": {15"sink_test": "https://events.twilio.com/v1/Sinks/DGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Test",16"sink_validate": "https://events.twilio.com/v1/Sinks/DGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Validate"17}18}
You can fetch a list of all event types that you can subscribe to from the event_type
endpoint of the Events API. You can also see this list on the Event Types page. You must pass all of these inside the types
parameter object when you create your subscription in the next step.
Here is a list of the six event types linked to A2P Brand and Campaign registration. It includes their Event Type ID strings.
Event Type | Event Type ID |
---|---|
Brand Registration Failure | com.twilio.messaging.compliance.brand-registration.brand-failure |
Brand Registered Unverified | com.twilio.messaging.compliance.brand-registration.brand-unverified |
Brand Registered | com.twilio.messaging.compliance.brand-registration.brand-registered |
Campaign Registration Submitted | com.twilio.messaging.compliance.campaign-registration.campaign-submitted |
Campaign Registration Failed or Rejected | com.twilio.messaging.compliance.campaign-registration.campaign-failure |
Campaign Registration Approved | com.twilio.messaging.compliance.campaign-registration.campaign-approved |
This list includes all six event types linked to A2P phone number registration, along with their Event Type ID string.
Event type | Event type ID |
---|---|
Number Deregistration Failed | com.twilio.messaging.compliance.number-deregistration.failed |
Number Deregistration Pending | com.twilio.messaging.compliance.number-deregistration.pending |
Number Deregistration Successful | com.twilio.messaging.compliance.number-deregistration.successful |
Number Registration Failed | com.twilio.messaging.compliance.number-registration.failed |
Number Registration Pending | com.twilio.messaging.compliance.number-registration.pending |
Number Registration Successful | com.twilio.messaging.compliance.number-registration.successful |
To create a new subscription, make a POST/create
request to the subscriptions
endpoint of the Events API. This request links a set of event types with a Sink. The Sink will receive messages when these events occur.
The subscription creation request includes the following parameters:
description
- a short description of the subscription, linked to the Sink you're specifying.
sink_sid
- the SID of the Sink you created earlier in Step 1.
types
- a list of event type IDs you want to subscribe to. The format of this list depends on the library you're using. For Python, the format looks like this:
1types=[2{'type': 'com.twilio.messaging.message.delivered'},3{'type': 'com.twilio.messaging.message.sent', 'schema_version': 2}4],
In this example, you subscribe to two events: messaging.message.delivered
and messaging.message.sent
. Your request should include all 6 events mentioned earlier. The second event in the example specifies a schema_version
of 2. If not set, the default schema version 1 is used. Currently, only schema version 1 is available for A2P events.
1// Download the helper library from https://www.twilio.com/docs/node/install2const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";34// Find your Account SID and Auth Token at twilio.com/console5// and set the environment variables. See http://twil.io/secure6const accountSid = process.env.TWILIO_ACCOUNT_SID;7const authToken = process.env.TWILIO_AUTH_TOKEN;8const client = twilio(accountSid, authToken);910async function createSubscription() {11const subscription = await client.events.v1.subscriptions.create({12description: '"My A2P Subscription"',13sinkSid: '"DGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"',14types: [15{16type: "com.twilio.messaging.message.delivered",17},18{19type: "com.twilio.messaging.message.sent",20schema_version: 2,21},22],23});2425console.log(subscription.accountSid);26}2728createSubscription();
1{2"account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",3"date_created": "2015-07-30T20:00:00Z",4"date_updated": "2015-07-30T20:01:33Z",5"sid": "DFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",6"sink_sid": "\"DGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"",7"description": "\"My A2P Subscription\"",8"url": "https://events.twilio.com/v1/Subscriptions/DFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",9"links": {10"subscribed_events": "https://events.twilio.com/v1/Subscriptions/DFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/SubscribedEvents"11}12}
POST
. This endpoint should be a dedicated page on your public site, coded to parse and respond to the JSON payload.
Part 3
below provides example payloads for each event message.
If you are an ISV with secondary customer Brands and Campaigns created or phone numbers registered immediately within your own top-level account, you would only need to perform this Event Streams setup once. Your Sink will capture Brand and Campaign registration events subscription for any and all of your clients (you will be able to identify which client a given event message pertains to by way of the Brand or Campaign/Messaging SID indicated in the message payload).
If you are an ISV whose architecture features a separate subaccount for Brand, Campaign, and Number registration for each of your secondary clients, then you will need to do both Event Sink and Subscription setup in each subaccount. Prior to the first step under Part 2 above, you would need to switch from your main account to the relevant subaccount, then perform all of the steps indicated in the workflow above.
As mentioned in Section 1, you will subscribe to 12 events for A2P Brand, Campaign, and Number registration. Below are the JSON payloads for these 12 events. We include explanations for important return parameters when needed.
This message means you have submitted a Brand for registration, but the verification is still pending. For instance, in the case of a Sole Proprietor Brand, the contact hasn't completed the OTP request.
1[2{3"data": {4"accountsid": "ACXXXXXXXXX",5"brandsid": "BNXXXXXXXXX",6"brandstatus": "registered",7"createddate": 1686837061258,8"externalbrandid": "XXXXXXX",9"identitystatus": "unverified",10"updateddate": 168683706125811},12"datacontenttype": "application/json",13"dataschema": "https://events-schemas.dev.twilio.com/A2P.BrandRegisteredUnverified/1",14"id": "CE000000000000000000000000000000",15"source": "CA000000000000000000000000000000",16"specversion": "1.0",17"time": "2023-06-15713:51:04.528Z",18"type": "com. twilio.messaging compliance.brand-registration.brand-unverified"19}20]
Here, accountsid
is the account or subaccount where this Brand was registered. brandsid
is the SID given when the Brand was created. type
is the Event Type ID, here com.twilio.messaging compliance.brand-registration.brand-unverified
.
After the customer completes the OTP request, the Brand will be approved. Its status will change to Registered, triggering the next event message.
This message tells you that the Brand is now registered. This means all steps, like OTP or other customer actions, are complete. Now, you should check the Campaign's status linked to this Brand.
1[2{3"data": {4"accountsid": "ACXXXXXXXXX",5"brandsid": "BNXXXXXXXXX",6"brandstatus": "registered",7"createddate": 1686837061258,8"externalbrandid": "XXXXXXX",9"identitystatus": "verified",10"updateddate": 1686837061258,11},12"datacontenttype": "application/ison",13"dataschema": "https://events-schemas.dev.twilio.com/A2P.BrandRegisteredUnverified/1",14"id": "CE000000000000000000000000000000",15"source": "CA000000000000000000000000000000",16"specversion": "1.0",17"time": "2023-06-15713:51:04.528Z",18"type": "com. twilio.messaging compliance.brand-registration.brand-registered"19}20]
accountsid
will be the main account or subaccount where this Brand was registered. brandsid
is the SID you got when creating the Brand. type
shows the full event type ID, here it is com.twilio.messaging compliance.brand-registration.brand-registered
.
This event triggers if the initial Brand submission fails (i.e., it does not pass the Twilio API data check). It also occurs if the submission passes but TCR rejects the brand after review.
1[2{3"data": {4"accountsid": "ACXXXXXXXXX",5"brandsid": "BNXXXXXXXXX",6"brandstatus": "registration_failed",7"createddate": 1687789009019,8"updateddate": 16877890090199},10"datacontenttype": "application/json",11"dataschema": "https://events-schemas.stage.twilio.com/A2P.BrandRegistrationFailure/1",12"id": "CE000000000000000000000000000000",13"source": "CA000000000000000000000000000000",14"specversion": "1.0",15"time": "2023-06-26T14:16:50.481Z",16"type": "com.twilio.messaging.compliance.brand-registration.brand-failure"17}18]
The event type
is com.twilio.messaging.compliance.brand-registration.brand-failure
.
Soon, we will add a brand_failure_reason
parameter to this payload. It will explain why the Brand failed. For now, you can find out why a Brand failed by fetching the BrandRegistration resource.
This message means that you have successfully submitted the Campaign. It is now waiting for approval from TCR. The customer does not need to do anything at this time.
1[2{3"data": {4"a2pusecase": "MIXED",5"accountsid": "ACXXXXXXXXX",6"brandsid": "BNXXXXXXXXX",7"campaignregistrationstatus": "pending",8"campaignsid": "CMXXXXXXXXX",9"createddate": 1687892791272,10"messagingservicesid": "MGXXXXXXXXX",11"timestamp": 1687892792294,12"updateddate": 168789279127213},14"datacontenttype": "application/json",15"dataschema": "https://events-schemas.stage.twilio.com/A2P.CampaignRegistrationSubmitted/1",16"id": "CE000000000000000000000000000000",17"source": "CA000000000000000000000000000000",18"specversion": "1.0",19"time": "2023-06-27T19:06:32.294Z",20"type": "com.twilio.messaging.compliance.campaign-registration.campaign-submitted"21}22]
Use brandsid
and/or campaignsid
to find out which customer's Campaign this Event is about. The event's type
is com.twilio.messaging.compliance.campaign-registration.campaign-submitted
.
This event occurs after the Campaign receives all necessary approvals. After this, the system adds all numbers to the number pool of the Messaging service for that Campaign. Once the system registers these phone numbers, the new Campaign is ready to start.
1[2{3"data": {4"a2pusecase": "MIXED",5"accountsid": "ACXXXXXXXXX",6"brandsid": "BNXXXXXXXXX",7"campaignregistrationstatus": "success",8"campaignsid": "CMXXXXXXXXX",9"createddate": 1687892791272,10"externalcampaignid": "XXXXXXX",11"messagingservicesid": "MGXXXXXXXXX",12"timestamp": 1687892792294,13"updateddate": 1687892791272,14},15"datacontenttype": "application/json",16"dataschema": "https://events-schemas.stage.twilio.com/A2P.CampaignRegistrationApproved/1",17"id": "CE000000000000000000000000000000",18"source": "CA000000000000000000000000000000",19"specversion": "1.0",20"time": "2023-06-27T19:06:32.294Z",21"type": "com.twilio.messaging.compliance.campaign-registration.campaign-approved"22}23]
Use brandsid
and/or campaignsid
to determine which customer campaign this event belongs to. The event type
is com.twilio.messaging.compliance.campaign-registration.campaign-approved
.
Currently, this event message appears in two situations. First, when a Campaign fails to submit successfully due to an issue with the initial Twilio API call. Second, when a Campaign submits successfully but is later rejected during the vetting process.
To identify the affected customer's Campaign, use brandsid
and/or campaignsid
.
1[2{3"data": {4"a2pusecase": "MIXED",5"accountsid": "ACXXXXXXXXX",6"brandsid": "BNXXXXXXXXX",7"campaignregistrationstatus": "failure",8"campaignsid": "CMXXXXXXXXX",9"createddate": 1687892791272,10"messagingservicesid": "MGXXXXXXXXX",11"timestamp": 1687892792294,12"updateddate": 168789279127213},14"datacontenttype": "application/json",15"dataschema": "https://events-schemas.stage.twilio.com/A2P.CampaignRegistrationFailure/1",16"id": "CE000000000000000000000000000000",17"source": "CA000000000000000000000000000000",18"specversion": "1.0",19"time": "2023-06-27T19:06:32.294Z",20"type": "com.twilio.messaging.compliance.campaign-registration.campaign-failure"21}22]
Like the failed Brand event message, future updates will add a campaignfailurereason
parameter. This will explain why a Campaign's registration failed.
For further troubleshooting, please review Troubleshooting and Rectifying Campaigns.
This event message indicates that number deregistration has failed. Below is an example of what the event payload might look like.
accountsid
is the account or subaccount where you registered this phone number.
campaignsid
is the Campaign SID from which the system attempted to remove the number.
externalstatus
field points to the current registration status for the phone number, which in this case indicates a failure.
failurereason
provides the customer with more information about this failure. At this point, the system failed to deregister your phone number, and you cannot use it to send messages, nor can you use it in another messaging service.
type
is the full event type ID, in this case
com.twilio.messaging.compliance.number-deregistration.failed
.
1[2{3"specversion": "1.0",4"type": "com.twilio.messaging.compliance.number-deregistration.failed",5"source": "CA000000000000000000000000000000",6"id": "CE000000000000000000000000000000",7"dataschema": "https://events-schemas.twilio.com/A2P.NumberDeregistrationFailed/1",8"datacontenttype": "application/json",9"time": "2024-03-13T15:51:10.552Z",10"data": {11"accountsid": "ACXXXXXXXXXXXXXXXXXXXXXXXX",12"timestamp": 1710345070552,13"id": "fd902aed-ca5a-8e26-85ee-35bdbf3503ea",14"campaignsid": "CMXXXXXXXXXXXXXXXX",15"externalstatus": "failure",16"failureReason": "https://www.twilio.com/docs/api/errors/30126",17"phonenumbersid": "PNXXXXXXXXXXXXXXXX",18"updateddate": 1710345070476,19"phonenumber": "1234567890"20}21}22]
This event message indicates that the number deregistration process is pending. Below is an example of what the event payload might look like.
accountsid
is the account or subaccount where you registered this phone number.
campaignsid
is the Campaign SID from which the system is attempting to remove the number.
externalstatus
field points to the current registration status for the phone number, which in this case indicates it is pending. At this point, the system is in the process of removing this phone number from a Campaign, and you cannot use it to send messages, nor can you use it in another Messaging Service.
type
is the full event type ID, in this case
com.twilio.messaging.compliance.number-deregistration.pending
.
1[2{3"specversion": "1.0",4"type": "com.twilio.messaging.compliance.number-deregistration.pending",5"source": "CA000000000000000000000000000000",6"id": "CE000000000000000000000000000000",7"dataschema": "https://events-schemas.twilio.com/A2P.NumberDeregistrationPending/1",8"datacontenttype": "application/json",9"time": "2024-03-13T15:51:10.552Z",10"data": {11"accountsid": "ACXXXXXXXXXXXXXXXXXXXXXXXX",12"timestamp": 1710345070552,13"id": "fd902aed-ca5a-8e26-85ee-35bdbf3503ea",14"campaignsid": "CMXXXXXXXXXXXXXXXX",15"externalstatus": "pending_deregistration",16"phonenumbersid": "PNXXXXXXXXXXXXXXXX",17"updateddate": 1710345070476,18"phonenumber": "1234567890"19}20}21]
This event message indicates that the number deregistration process is successful. Below is an example of what the event payload might look like.
accountsid
is the account or subaccount where you registered this phone number.
campaignsid
because the number doesn't currently belong to any Campaign.
externalstatus
field points to the current registration status for the phone number, which in this case indicates that the system has unregistered it. At this point, the system has completed the deregistration process for your phone number, and you can no longer use it to send messages. You can now use this number in another Messaging Service/Campaign or re-add it to the same Messaging Service/Campaign.
type
is the full event type ID, in this case
com.twilio.messaging.compliance.number-deregistration.successful
.
1[2{3"specversion": "1.0",4"type": "com.twilio.messaging.compliance.number-deregistration.successful",5"source": "CA000000000000000000000000000000",6"id": "CE000000000000000000000000000000",7"dataschema": "https://events-schemas.twilio.com/A2P.NumberDeregistrationSuccessful/1",8"datacontenttype": "application/json",9"time": "2024-03-13T15:51:10.552Z",10"data": {11"accountsid": "ACXXXXXXXXXXXXXXXXXXXXXXXX",12"timestamp": 1710345070552,13"id": "fd902aed-ca5a-8e26-85ee-35bdbf3503ea",14"externalstatus": "unregistered",15"phonenumbersid": "PNXXXXXXXXXXXXXXXX",16"updateddate": 1710345070476,17"phonenumber": "1234567890"18}19}20]
This message tells you that a number registration did not succeed. Here's a sample of what the event details might include:
accountsid
shows the main or secondary account where you listed this number.
campaignsid
is the SID for the attempt to remove the number.
externalstatus
shows the current status of the number's registration, which indicates a failure in this case.
failurereason
gives more details on why the registration failed. The system has not successfully registered your number, and you cannot use it to send messages or in another messaging service.
type
is the specific event type ID. Here it's
com.twilio.messaging.compliance.number-registration.failed
.
1[2{3"specversion": "1.0",4"type": "com.twilio.messaging.compliance.number-registration.failed",5"source": "CA000000000000000000000000000000",6"id": "CE000000000000000000000000000000",7"dataschema": "https://events-schemas.twilio.com/A2P.NumberRegistrationFailed/1",8"datacontenttype": "application/json",9"time": "2024-03-13T15:51:10.552Z",10"data": {11"accountsid": "ACXXXXXXXXXXXXXXXXXXXXXXXX",12"timestamp": 1710345070552,13"id": "fd902aed-ca5a-8e26-85ee-35bdbf3503ea",14"campaignsid": "CMXXXXXXXXXXXXXXXX",15"externalstatus": "failure",16"failureReason": "https://www.twilio.com/docs/api/errors/30126",17"phonenumbersid": "PNXXXXXXXXXXXXXXXX",18"updateddate": 1710345070476,19"phonenumber": "1234567890"20}21}22]
This message means the Number registration is still in progress. Here's a sample of how the event details might appear:
accountsid
refers to the specific account or subaccount to which you are registering this phone number.
campaignsid
is the ID of the Usa2p Resource linked to the phone number.
externalstatus
shows the current registration status of the phone number.
type
represents the unique event type ID. Here, it's
com.twilio.messaging.compliance.number-registration.pending
.
In the given example, the externalstatus
indicates that the phone number registration is incomplete and the number is not ready for message sending.
1[2{3"specversion": "1.0",4"type": "com.twilio.messaging.compliance.number-registration.pending",5"source": "CA000000000000000000000000000000",6"id": "CE000000000000000000000000000000",7"dataschema": "https://events-schemas.twilio.com/A2P.NumberRegistrationPending/1",8"datacontenttype": "application/json",9"time": "2024-03-13T15:51:10.552Z",10"data": {11"accountsid": "ACXXXXXXXXXXXXXXXXXXXXXXXX",12"timestamp": 1710345070552,13"id": "fd902aed-ca5a-8e26-85ee-35bdbf3503ea",14"campaignsid": "CMXXXXXXXXXXXXXXXX",15"externalstatus": "pending_registration",16"phonenumbersid": "PNXXXXXXXXXXXXXXXX",17"updateddate": 1710345070476,18"phonenumber": "1234567890"19}20}21]
This message confirms the Number registration was successful. Here's an example of the event payload:
accountsid
shows the account or subaccount where you registered this phone number.
campaignsid
is the SID to which you added the number.
externalstatus
shows the phone number's current registration status, which is
registered
. Now, your phone number is fully registered and ready to send messages to your customers.
type
is the event type ID. Here, it is
com.twilio.messaging.compliance.number-registration.successful
.
1[2{3"specversion": "1.0",4"type": "com.twilio.messaging.compliance.number-registration.successful",5"source": "CA000000000000000000000000000000",6"id": "CE000000000000000000000000000000",7"dataschema": "https://events-schemas.twilio.com/A2P.NumberRegistrationSuccessful/1",8"datacontenttype": "application/json",9"time": "2024-03-13T15:51:10.552Z",10"data": {11"accountsid": "ACXXXXXXXXXXXXXXXXXXXXXXXX",12"timestamp": 1710345070552,13"id": "fd902aed-ca5a-8e26-85ee-35bdbf3503ea",14"campaignsid": "CMXXXXXXXXXXXXXXXX",15"externalstatus": "registered",16"phonenumbersid": "PNXXXXXXXXXXXXXXXX",17"updateddate": 1710345070476,18"phonenumber": "1234567890"19}20}21]