A2P Brand & Campaign registration via the API consists of the following steps:
The present guide addresses troubleshooting of failures that can happen at Step 4, Campaign creation/submission. The process can also fail at prior steps 1 or 3. Troubleshooting these for Sole Proprietor Brands is covered in this guide; troubleshooting these for Standard or LVS Brands is covered in this guide. Finally, Phone Numbers added to successfully-created Campaigns (Step 5) can themselves fail to be successfully registered, or their successful registration can take longer than expected. Troubleshooting these phone number issues is addressed in this guide.
Since Campaigns can be rejected by TCR for a wide variety of reasons, if you are an ISV registering multiple secondary customer Campaigns, you may find these approved at different times, or you may find that some are approved and others are rejected (FAILED). For this reason, both ISVs and direct customers sometimes find it easier to track the status of Campaigns via the Console, whether they were originally submitted via Console or via API. Going to Messaging > Regulatory Compliance > Campaigns will show a list of all your Campaign submissions, with a status indicated for each. If you click on the name or Campaign SID of a FAILED Campaign, you will see a Campaign Details page with something like the following:
In this case, if you look at the Campaign Information panel (you may need to zoom in on this screenshot), you'll see that two separate failure reasons are indicated. One is that the Campaign description was found too be invalid, probably because it was not detailed enough. The second failure reason concerns the content of the first Sample message. This would be a reasonable opt-out message, but it is not an appropriate sample message for a Campaign whose basic use case is Marketing.
If you click on the blue Edit Campaign link, to the left of the red Delete Campaign link above, you will be taken to the following modal:
As we see, the modal begins with a banner confirming that this Campaign was failed upon review, and inviting you to fix whatever issues were flagged in the previous screen. Below this you will see text entry boxes corresponding to most of the text-entry fields in the original Campaign submission flow: Campaign description, Sample messages (you'll see that there are boxes for up to five different sample messages, but only the first two are required), then Message contents checkboxes to indicate whether any of your messages will contain embedded links, phone numbers, content related to direct lending or other loan arrangements, or any age-gated content; and finally a box for a description of the opt-in process (how end users give their consent to receiving text messages). All of these will be pre-populated with the information entered in the original Campaign submission. In our example, we have two things to fix here: first, the Campaign Description needs to be more detailed; second, the two sample messages need to be rewritten so they actually reflect the designated purpose of the Campaign: sending marketing messages about sales and offers (as opposed to indicating a successful opt-out, which is an entirely different use case).
Whatever changes you need to make to address your own failure_reason(s)
, once you have rectified the necessary information, click the blue Update button and your Campaign will be resubmitted for approval. Please note that this essentially kicks off a new Campaign vetting process, involving the same time and labor on the part of our A2P ecosystem partners as an original Campaign submission, so it's not feasible to allow an indefinite number of free resubmissions. At present, Twilio allows three free resubmissions of the same Campaign. The number of allowed resubmissions remaining is indicated to the right of the Update button.
Clicking the "Delete Campaign" link will launch a confirmation modal; this Delete Campaign link is active for APPROVED Campaigns as well as FAILED ones, and you definitely do not want to delete an approved Campaign unless you have very good reason to do so. Also NOTE: since you will want to use either most or all of the original Campaign details in the new submission, it might be a good idea to duplicate the tab with the original Campaign details screen, so that you can refer back to these Campaign details when you recreate the Campaign.
Once the FAILED Campaign has been deleted, you can then go back to the Brand for which you submitted this Campaign (you can find this via Messaging > Regulatory Compliance > Brands in the left navigation, which will allow you to click on the appropriate Brand and launch the Brand details page). If you just need to resubmit the Campaign with a new use case indicated, use the blue Register New Campaign button in the Brand details screen, which will launch a new Campaign creation workflow and allow you to enter whatever original and new Campaign information is appropriate.
On the other hand, if the Campaign's failure reason lies with the Brand information itself (which ultimately always means some aspect of the Brand's underlying business profile or trust bundle), you will need to refer to Section 2 above for how to remediate Brand issues. But the Campaign deletion still needs to happen first; a Brand cannot be edited if it has a Campaign associated with it. Once the Brand has been resubmitted, then on the Brand details screen you can use the Register New Campaign button to launch the new Campaign creation workflow. In this case it's likely that all of the original Campaign detail information can be used as-is.
If you present a business website URL in any part of your Campaign submission (such as sample messages) that uses a shortened URL, be aware that only certain forms of shortened URL are acceptable to The Campaign Registry. Specifically, you must use a dedicated, branded short domain that belongs to your business. You cannot use the sort of randomly-shortened URL typically furnished by a free service like bit.ly or TinyUrl; this will lead to rejection of the Campaign by TCR. For more information see this support article on using shortened URLs in Campaign submissions.
In Step 5 of the guide to registering Standard/Low-Volume Standard Brands via API as well as the guide to registering Sole Proprietor Brands, you created a new messaging Campaign to go with your new A2P Brand. In the Sole Proprietor guide, Step 5.1 directs you to do a fetch
call on the newly-created Campaign to check its status.
It's important to remember that, like new A2P Brand registration, new Campaign verification is never an instantaneous process. Sole-Proprietor Campaigns tend to be approved (or rejected) most quickly, while Standard Campaigns must go through several distinct layers of vetting and this process can take up to several weeks. If your fetch
call to the new Campaign returns a campaign_status
of IN_PROGRESS
, this vetting process is not yet complete. Once the process is complete, your fetch call will return a campaign_status
of either VERIFIED
or FAILED
(or in some rare cases SUSPENDED. On Suspended Campaigns, see section 3.2.1 below)
A code sample for this fetch
call follows. This call requires two parameters: the messaging_service_sid
(i.e., the SID of the Messaging Service you're using in this Campaign), and a hardcoded compliance type of QE2c6890da8086d771620e9b13fadeba0b
(see code sample for how these are used in your code library of choice).
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 fetchUsAppToPerson() {11const usAppToPerson = await client.messaging.v112.services("MGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")13.usAppToPerson("QEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")14.fetch();1516console.log(usAppToPerson.sid);17}1819fetchUsAppToPerson();
1{2"sid": "QEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",3"account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",4"brand_registration_sid": "BNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",5"messaging_service_sid": "MGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",6"description": "Send marketing messages about sales to opted in customers.",7"message_samples": [8"EXPRESS: Denim Days Event is ON",9"LAST CHANCE: Book your next flight for just 1 (ONE) EUR"10],11"us_app_to_person_usecase": "MARKETING",12"has_embedded_links": true,13"has_embedded_phone": false,14"subscriber_opt_in": true,15"age_gated": false,16"direct_lending": false,17"campaign_status": "PENDING",18"campaign_id": "CFOOBAR",19"is_externally_registered": false,20"rate_limits": {21"att": {22"mps": 600,23"msg_class": "A"24},25"tmobile": {26"brand_tier": "TOP"27}28},29"message_flow": "End users opt-in by visiting www.example.com and adding their phone number. They then check a box agreeing to receive text messages from Example Brand. Additionally, end users can also opt-in by texting START to (111) 222-3333 to opt in.",30"opt_in_message": "Acme Corporation: You are now opted-in. For help, reply HELP. To opt-out, reply STOP",31"opt_out_message": "You have successfully been unsubscribed from Acme Corporation. You will not receive any more messages from this number.",32"help_message": "Acme Corporation: Please visit www.example.com to get support. To opt-out, reply STOP.",33"opt_in_keywords": [34"START"35],36"opt_out_keywords": [37"STOP"38],39"help_keywords": [40"HELP"41],42"date_created": "2021-02-18T14:48:52Z",43"date_updated": "2021-02-18T14:48:52Z",44"url": "https://messaging.twilio.com/v1/Services/MGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Compliance/Usa2p/QE2c6890da8086d771620e9b13fadeba0b",45"mock": false,46"errors": []47}
If you do receive a campaign_status of FAILED, the errors[]
object in the call's json return will not be empty (as it will for Campaigns in a non-failed state, and as shown in the code sample return) but will instead be populated with information. (However, please note that this is only the case for Campaigns submitted since May 31, when this feature was implemented; for previously-submitted Campaigns the errors[] attribute will be empty on failed Campaigns as well as those in other states). The format of the populated errors[]
object is illustrated below:
1"errors": [2{3"error_code": 30897,4"fields": [ "MESSAGE_FLOW" ],5"url": "https://www.twilio.com/docs/api/errors/30897",6"description": "The campaign submission has been reviewed and it was rejected due to Disallowed Content."7}8]
For a FAILED Campaign, there will always be at least one such error listed, but there could be multiple errors, each detailed in the same format. Each error will have a distinct error_code
, which you will find enumerated in this support article. The description
field in this error format corresponds roughly to the Rejection Category associated with that error code in the support article, and the url
of the error will lead to a more detailed explanation of that failure reason and the steps to remedy it, if any. Below is an example of an error[] return showing multiple errors:
1"errors": [2{3"url": "https://www.twilio.com/docs/api/errors/30886",4"fields": [5"USE_CASE_DESCRIPTION"6],7"error_code": 30886,8"description": "The campaign submission has been reviewed and it was rejected because of invalid campaign description."9},10{11"url": "https://www.twilio.com/docs/api/errors/30892",12"fields": [13"SAMPLE_MESSAGE_1"14],15"error_code": 30892,16"description": "The campaign submission has been reviewed and it was rejected because of URL shortener in the sample message."17},18{19"url": "https://www.twilio.com/docs/api/errors/30893",20"fields": [21"SAMPLE_MESSAGE_2"22],23"error_code": 30893,24"description": "The campaign submission has been reviewed and it was rejected because of invalid sample message content."25}26]
It's important to note that there are two categories of errors laid out in the linked support article, and only the first type of error can be remedied. For example, error code 30893
maps to a Rejection Category of "Invalid Sample Message Use Case" with the following Rejection Reason: "Sample messages are either not provided, unclear, or content does not match the campaign use case." This is one of 12 rejection reasons that can be remedied, i.e. the information supplied in the original Campaign submission can be corrected, as follows:
Verify that sample messages are accurate and detailed. Sample messages should reflect actual messages to be sent under campaign and indicate templated fields with brackets. At least one of the sample messages needs to include your business name. Use case and campaign description need to match campaign description.
In the case of an error like 30893, then, such a Campaign could be deleted and recreated. Learn how to delete and create a Campaign in the UsAppToPerson Resource API Reference doc.
First, however, we need to consider some examples of the second category of Campaign failure error, which cannot be remedied (through either an edit or a delete/recreate) by improving the submission detail:
Error Code | Rejection Category | Rejection reason |
---|---|---|
30883 | Content Violation - SHAFT - Sex | Submission included content such as nudity, pornography, sex toys, or other adult content |
30883 | Content Violation - SHAFT - Hate | Submission included speech that is hateful, profanity, violent, incites violence, or similar speech |
30883 | Content Violation - SHAFT - Alcohol | Submission includes content referring to alcohol |
The 30883
error code represents a Content Violation, which means that your proposed Campaign has been deemed to deal with content that is prohibited under the terms of A2P Campaign registration, such as sexual references, hate speech, or references to alcohol, firearms, tobacco products or marijuana. As shown here, the Rejection Category and Reason will specify the content reference that is deemed to be in violation. In addition to Content Violations, your Campaign use case could be disallowed because it is deemed to represent a high risk for a spam/phishing attack (30884
), other potentially fraudulent activity (30885
), violation of Twilio's general Terms & Conditions (30882
), or several other reasons enumerated in the Support article, including the use of the same EIN for too many Brand registrations (By default, a single EIN/Tax ID can only be used in a maximum of 50 different Brands; any brands beyond this limit using the same EIN are invalid, and therefore their associated Campaign(s) will be rejected even if the Campaign submission itself is entirely valid otherwise).
As the support article notes, customers who disagree with a Campaign rejection for such a non-resubmittable reason may submit an appeal to the Twilio support desk; but outside of this route, there is no remedy for this kind of Campaign rejection except to materially change the nature or content of the proposed Campaign, or in some cases the associated Brand.
It is possible for a Campaign to be suspended on its own, but it's also possible for a Campaign to be suspended because the Brand it's associated with is suspended. You can check the Brand status to understand which case it is. If it's a Brand suspension situation, go to Section 1.1 above to check out what it means for you. If your Brand is still in an Approved state but your Campaign is suspended, keep reading.
If you have a suspended campaign, it means the campaign may have violated one or more of the following rules, causing Carriers / ecosystem partners to suspend it:
The Twilio team should be reaching out to you to provide guidance on how to fix the suspended campaign. Please check your email or the Twilio Support Center. If you don't see anything, please raise a ticket.
While your campaign is suspended, you will experience the following restrictions: