A toll-free verification is a dossier a carrier reviews, and its status will tell you the carrier said no without telling you what it objected to. That answer is on the verification itself, in a field called `denial_reasons`, and it arrives in the carrier's own words.

The place people look first is the requirements list, and it cannot answer this. Understanding why saves a lot of time.

## Where is the reason for the rejection?

On the verification, from [`bird sms tfn verifications get`](/docs/cli/reference/sms-tfn-verifications-get). It returns the state the verification is in, the sender it licenses, and what the carrier said about it, with `denial_reasons` carrying the carrier's reasons as text.

One detail to plan for: reasons come with a rejection. When a carrier asks for changes instead of declining outright, the verification moves to `info_requested` and records the new status without reasons attached. So a verification asking you for more information will not tell you what, and the requirements list is where you look then, to see which items it is still missing.

## Why can't the requirements list say which answer was wrong?

Because the carrier does not decide answer by answer. It decides the dossier as a whole, and Bird projects that single verdict onto every item you supplied.

The consequence is worth being concrete about. On a rejected verification, every item you had filled in reads `rejected`, whether or not it was the problem, and every item you left blank reads `not_supplied`. Nothing in the list is more rejected than anything else. If you go looking for the culprit there, you will find twenty rejected items and no signal, which is exactly why `denial_reasons` is the field that matters.

What the requirements list is genuinely for is the shape of the dossier: what is asked, what you have answered, and what is still missing.

## What does the carrier actually ask for?

Ask for the requirements with no verification named and you get the blank form: every item the carriers ask for, in the order to present it. Name one with `--verification-id` and you get the same list carrying its own answers.

Each item comes with a `key` to submit it under, a `label` to put in front of whoever has to answer it, `help_text` describing what a good answer looks like, and whether an answer is `required`. Optional items are still reviewed when you supply them.

Two answers are closed sets worth knowing before you start:

- **Legal structure**, one of `sole_proprietor`, `private_profit`, `public_profit`, `non_profit` or `government`. These are spelled the same as [10DLC's five structures](/docs/guides/sms/10dlc) and are deliberately a separate list, because each authority decides for itself what it accepts.
- **Monthly volume**, as a band rather than a number: eleven of them, from `up_to_10` through `up_to_1m` and `up_to_5m`, ending at `above_5m`.

Each item also reports a `state`, and a toll-free read emits five of them: `not_supplied`, `supplied`, `in_review`, `approved` and `rejected`. Treat the set as open, since review can gain stages.

## How do I tell whether it is waiting on me or on the carrier?

Two booleans on the requirements read answer it, and only one of them is about you.

`satisfied` is true only once the verification is approved. Read it as "is this finished", not as "have I filled everything in".

`needs_input` is true when the next move is yours. That covers four situations: a required item has no answer, the carrier has asked for changes, your draft is complete but nobody has submitted it, or a rejection is still inside its resubmission window.

Both false is the combination worth recognising, because it has two meanings. Either the carrier is holding the dossier and there is nothing to do but wait, or your verification was rejected and its resubmission window has already closed. `resubmit_allowed` is what separates those two, which is a good reason to read it whenever you read a rejection.

## What do the six verification states mean?

| State            | What it means                                                                  |
| ---------------- | ------------------------------------------------------------------------------ |
| `draft`          | You can edit or submit the business and messaging details                      |
| `submitted`      | The verification went to the carrier for review                                |
| `under_review`   | The carrier is reviewing it                                                    |
| `info_requested` | The carrier needs changes before deciding, and you can edit and resubmit       |
| `approved`       | The number is licensed for sending in the United States, and approval is final |
| `rejected`       | The carrier declined it                                                        |

## Can I fix a rejected verification?

Sometimes, and one field answers it: a rejected verification can be corrected and resubmitted only while `resubmit_allowed` is true. That flag outlives the window it was granted with, so store it when you read a rejection rather than deriving it later.

A verification is editable while it is a draft, when the carrier has asked for more information, and while a rejection is still inside its resubmission window. Everything else is locked, which includes `submitted` and `under_review` as well as `approved`, so the two states you spend the most time waiting in are both states you cannot edit from. Trying anyway returns a conflict.

Correcting one answer does not mean re-entering the others. An update applies only the fields you send, so a single bad answer costs you that answer rather than the dossier.

## Which commands do I use?

Six commands cover the lifecycle, and one step is missing from them on purpose.

[`bird sms tfn verifications requirements`](/docs/cli/reference/sms-tfn-verifications-requirements) reads the item-by-item view, and `get`, `create`, `update`, `list` and `cancel` do what their names say. Submitting a verification for review is not among them: it happens in the dashboard.

One shortcut is worth knowing while you fill the form in. Passing `--identity-id` prefills the business and contact requirements from a party you have already described, and those come back marked as prefilled. The messaging and opt-in requirements never prefill, because you write those fresh for each verification, and anything you have already filed for this verification wins over the party's answer.

There is also no public webhook event for toll-free verification state, so a subscription cannot tell you when a decision lands. Polling the get command is the way to find out.