---
title: "File a number's ownership paperwork"
description: "File the ownership paperwork a country asks for on a phone number, from the dashboard or with the API, follow its review, and correct rejected answers."
canonical: "https://bird.com/docs/guides/numbers/ownership-paperwork"
---

# File a number's ownership paperwork

Some countries ask who holds a number before it can carry traffic. Until that paperwork is accepted and the number's registration completes, the number is allocated to you and billed, but its `status` is `pending_ownership_registration`: it carries no incoming or outgoing voice calls and sends no SMS. The number carries traffic once its `status` is `active` and its `ownership.blocked_at` is `null`. You file the paperwork from the dashboard or with the API, and both paths use the same requirements, review rules, and registration process. The number's `ownership.next` names each step, including when to file a new submission.

The answers you file are a legal representation made in your business's name. Once accepted, they are passed on to the carrier or regulator for that country under the name of the business they describe, so confirm them with whoever is responsible for them before you file, and do not let an automated job file answers nobody has checked.

## Before you start

- To file from the dashboard, your workspace role must allow editing compliance details. Without it, the number shows its ownership status but no button to file.
- To file through the standalone compliance endpoints, an [API key](/docs/guides/authentication) with the `compliance` scope at write level. A key with read level can check requirements and review progress but not file. Reading the number also needs the `numbers` scope at read level. In the dashboard key picker, `compliance` is under **Compliance**.
- The number's `nda_` identifier, from [`GET /v1/numbers`](/docs/api/reference/list-workspace-numbers). [Find a number in your list](/docs/guides/numbers/managing-numbers#find-a-number-in-your-list) shows how to look it up.

The API examples read your key from `BIRD_API_KEY`, its [regional host](/docs/api/regions) from `BIRD_API_URL`, and the number's identifier from `NUMBER_ID`. Each later step names the variable it sets. The `jq` commands extract one field from a response; read the field by hand if you do not use `jq`.

## Check whether a number needs paperwork

Read the number with [`GET /v1/numbers/{number_id}`](/docs/api/reference/get-workspace-number):

```bash
curl "$BIRD_API_URL/v1/numbers/$NUMBER_ID" \
  --header "Authorization: Bearer $BIRD_API_KEY"
```

Keep the number's `country_code` as `COUNTRY_CODE`; the requirements read and the submission both take it:

```bash
COUNTRY_CODE=$(curl -s "$BIRD_API_URL/v1/numbers/$NUMBER_ID" \
  --header "Authorization: Bearer $BIRD_API_KEY" | jq -r .country_code)
```

`ownership` is `null` when the number's country asks for no paperwork. It is also `null` when we could not read the paperwork's progress and no block is recorded on the number; read the number again. Otherwise it carries:

- `status`: `needs_input` means answers are missing or need correcting, `under_review` means your answers are being reviewed, `approval_pending` means the paperwork is accepted and registration is still pending; calls and outgoing SMS stay blocked while `blocked_at` is set. `approved` means registration is approved, though calls and outgoing SMS stay blocked while `blocked_at` is set. `not_required` means nothing more is asked. `rejected` means the submission was closed, or a correction deadline passed, and it takes no more corrections. Contact support to have it reopened. `unknown` means the status could not be read; read the number again.
- `next`: the steps that move the paperwork forward, in order. A `wait` step means nothing is asked of you now. Read it again after each change.
- `submission_id`: the most recent submission for the number, once one exists.
- `blocked_at`: when the ownership block began, or `null` once it is clear. The block stops incoming and outgoing voice calls and outgoing SMS.

[The status of an allocated number](/docs/guides/numbers/overview#the-status-of-an-allocated-number) explains how `ownership` relates to the number's own `status`.

## File from the dashboard

1. Open the number from the [**Numbers**](https://bird.com/dashboard/w/numbers) page. Its **Ownership** row shows the paperwork's status and the next steps.
2. When the status is **Details needed**, select **Update ownership details**. The **Prove ownership of this number** form opens.
3. Choose the business that holds the number, or describe a new one, then answer each item and upload the documents it asks for. Items that offer a blank form link it for you to download, complete, and upload back.
4. Select **Submit answers**.

The **Ownership** row moves to **Under review**. If a reviewer rejects an answer, the row returns to **Details needed**: select **Update ownership details** again, correct the answers the form shows, then select **Update ownership details** at the end of the form to send them.

If the number's country has no form yet, the form page says **Ownership form unavailable**. Contact support to ask for that country.

## File with the API

To file with the API, read what the country asks for, upload each document, submit every answer at once, then read the number to follow the review.

### Read what the country asks for

Read the requirements for the number with [`GET /v1/compliance/requirements`](/docs/api/reference/get-workspace-compliance-requirements). Set `subject_kind` to `number`, `subject_id` to the number's `nda_` identifier, and `country_code` to the number's own `COUNTRY_CODE`:

```bash
curl "$BIRD_API_URL/v1/compliance/requirements?subject_kind=number&subject_id=$NUMBER_ID&country_code=$COUNTRY_CODE" \
  --header "Authorization: Bearer $BIRD_API_KEY"
```

The response names the `program` the number registers under, which follows its number type; keep it as `PROGRAM`. It lists each item to answer in `fields`, in the order to present them. For each field:

- `key` is what you send the answer under.
- `data_type` says how to answer it. A `document` field takes an uploaded file; every other type takes a string, so a number goes as `"1500"` and a yes-or-no as `"true"`. An `enum` field accepts one of its `options`.
- `required` says whether approval waits on it, and `help_text` says what a good answer looks like.
- `max_items` is set on a field that takes more than one answer.
- `template_url` links a blank form to download, complete, and upload back, where the field has one.
- `state` is where the item stands: `not_supplied` before you answer, then `supplied`, `in_review`, `approved`, or `rejected`, with the reviewer's `reason` on a rejected item. An accepted answer can later read `expired` and needs supplying again, and `not_applicable` marks an item that does not apply to you.

`submission_id` is `null` until you file. `needs_input` is `true` while any item waits on you.

A `422` with [`E19001`](/docs/api/errors/E19001) means we have no ownership form for that country yet. Contact support to ask for it.

### Upload each document

Upload each file a `document` field asks for with [`POST /v1/compliance/attachments`](/docs/api/reference/create-compliance-attachment), as a `multipart/form-data` body with the bytes in a `file` part. Keep the `id` from the response, the attachment's `tca_` identifier, as `ATTACHMENT_ID`:

```bash
curl --request POST "$BIRD_API_URL/v1/compliance/attachments" \
  --header "Authorization: Bearer $BIRD_API_KEY" \
  --form "file=@registration-certificate.pdf"
```

PNG, JPEG, and PDF files up to 10 MB are accepted, and the type is read from the file's contents. A `201` response returns the new attachment. Uploading the same file again returns the first attachment with `200`, so retrying an upload does not create a duplicate. An attachment no submission cites expires after seven days.

The attachment's `download_url` is a signed link valid for 24 hours from when you fetched the attachment. List your attachments with [`GET /v1/compliance/attachments`](/docs/api/reference/list-compliance-attachments) for a fresh one, or download the bytes directly with [`GET /v1/compliance/attachments/{attachment_id}`](/docs/api/reference/get-compliance-attachment).

### Submit every answer

File the answers with [`POST /v1/compliance/submissions`](/docs/api/reference/create-workspace-compliance-submission). Send `subject_kind` and `subject_id`, the `program` the requirements read reported, and the number's `country_code`. In `answers`, send one entry for every field whose `required` is `true`, and one for each optional field you have a real answer for; leave an optional field out rather than invent a value for it. A typed field takes `value`, a document field takes `attachment_id`, and a field with `max_items` takes `values` or `attachment_ids`. Save the body as `submission.json`, with your values in place of `<NUMBER_ID>`, `<PROGRAM>`, `<COUNTRY_CODE>`, and `<ATTACHMENT_ID>`. The example shows three of the answers a form asks for:

```json
{
  "subject_kind": "number",
  "subject_id": "<NUMBER_ID>",
  "program": "<PROGRAM>",
  "country_code": "<COUNTRY_CODE>",
  "answers": [
    { "key": "legal_entity_name", "value": "Goldcrest Communications Inc" },
    { "key": "business_registration_number", "value": "90012768" },
    { "key": "business_registration_certificate", "attachment_id": "<ATTACHMENT_ID>" }
  ]
}
```

Send it with an `Idempotency-Key`. Reuse the key only to retry the same body: a rejection can be retained and replayed, so after a `422` correct the body and send it under a new key. [Idempotency](/docs/guides/idempotency) explains what is retained.

```bash
curl --request POST "$BIRD_API_URL/v1/compliance/submissions" \
  --header "Authorization: Bearer $BIRD_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: ownership-$NUMBER_ID" \
  --data-binary @submission.json
```

There are no drafts: this request files the answers for review, so it must carry every required answer. A required field you leave out, or an answer the form refuses, comes back as a `422` with [`E01001`](/docs/api/errors/E01001) and one entry in `details` per field, named in `param`, and nothing is filed. A `201` response returns the submission with every answer on it. Keep its `id`, the submission's `csb_` identifier, as `SUBMISSION_ID`.

A business your workspace describes is an identity. Create one in the dashboard's **Identity Center** or with [`POST /v1/compliance/identities`](/docs/api/reference/create-compliance-identity), sending its display `name`. A number submission can also carry an inline `identity` instead of an `identity_id`. The submission response's `identity_id` names the new identity, which `POST /v1/compliance/identities` returns as `id`; reuse it for later numbers rather than creating another one. To file for an identity, add its `identity_id`, and the answers it holds fill in the ones you leave out. [`GET /v1/compliance/identities`](/docs/api/reference/list-compliance-identities) lists the business identities. The single-value answers you file are written back onto the identity whatever the review decides, so the next submission that names it starts from them; documents and multi-value answers are asked again each time. Use one identity per business: if you file for several end customers, give each its own identity, or one customer's approved answers fill in another's.

Follow `ownership.next` rather than filing again. A number has one submission per version of its country's form, so filing again while that submission is open answers `409` with [`E19009`](/docs/api/errors/E19009): correct it instead, as [Correct a rejected answer](#correct-a-rejected-answer) shows. When we reopen a closed submission after the form changes, `next` asks for a new submission to `POST /v1/compliance/submissions`.

### Follow the review

Each answer is reviewed on its own. Read the number again and check `ownership.status` and `ownership.next`, as in [Check whether a number needs paperwork](#check-whether-a-number-needs-paperwork). To see how each answer was judged, read the submission with [`GET /v1/compliance/submissions/{submission_id}`](/docs/api/reference/get-workspace-compliance-submission), or read the requirements again: each field carries its `state` and, when it is rejected, its `reason`.

When a review completes, we email the result to your organization's owners and the last recorded person who filed or corrected the submission, when one exists. A first filing by API key goes to the owners. A later API-key correction keeps the previously recorded person as a recipient. Your integration learns the result by reading `ownership.status`.

### Correct a rejected answer

Send the replacement answers to [`POST /v1/compliance/submissions/{submission_id}/resupply`](/docs/api/reference/update-workspace-compliance-submission). Include only the answers you are replacing; the others stay as they are. Take the `submission_id` from the number's `ownership` or from the requirements read:

```bash
curl --request POST "$BIRD_API_URL/v1/compliance/submissions/$SUBMISSION_ID/resupply" \
  --header "Authorization: Bearer $BIRD_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: ownership-fix-1-$NUMBER_ID" \
  --data '{"answers": [{"key": "business_registration_number", "value": "90012769"}]}'
```

A `200` response returns the submission with your replacements, which go back to review. Once no required answer is still rejected, expired, or missing, the number's `ownership.status` returns to `under_review`. Replace answers whose `state` is `rejected`, `expired`, or `not_supplied`. When we ask for a correction after accepting your answers, an answer whose `editable_for_verifier_repair` is `true` can also be replaced until that correction closes. An answer in any other state, such as one still under review or accepted outside a correction we requested, answers `422` with [`E19003`](/docs/api/errors/E19003). A replacement document is a new upload: upload it first and send its `attachment_id`.

## File the paperwork with the order

If you know the answers when you buy the number, send them in the order's `compliance` block on [`POST /v1/numbers/orders`](/docs/api/reference/create-numbers-order), in the same `answers` shape the submission takes. To read what the country asks for before you hold the number, call the requirements read without `subject_id`, with `COUNTRY_CODE` and `NUMBER_TYPE` set to the `country_code` and `number_type` of the number in [`GET /v1/numbers/available`](/docs/api/reference/list-available-numbers):

```bash
curl "$BIRD_API_URL/v1/compliance/requirements?subject_kind=number&country_code=$COUNTRY_CODE&program=$NUMBER_TYPE" \
  --header "Authorization: Bearer $BIRD_API_KEY"
```

An order with a `compliance` block uses the order's existing `numbers` scope at write level.

Once the order is accepted, it completes either way: if the filing in the `compliance` block is refused, the number is still yours, and you file with `POST /v1/compliance/submissions` as in [Submit every answer](#submit-every-answer). When the answers are filed, the new number reads `under_review` with its `submission_id`. [Buy and release a number](/docs/guides/numbers/buying-numbers) covers the order itself.

## Reuse a business identity

Use [`GET /v1/compliance/identities/{identity_id}`](/docs/api/reference/get-compliance-identity) to read the business and its saved answers. Saved answers can include a review `state`, `reason`, and `decided_at`; a value with no review decision can omit its state. Rename the business with [`PATCH /v1/compliance/identities/{identity_id}`](/docs/api/reference/update-compliance-identity), or remove it with [`DELETE /v1/compliance/identities/{identity_id}`](/docs/api/reference/delete-compliance-identity). Reads need `compliance:read`; creation, renaming, and deletion need `compliance:write`.

To verify the business itself, create the identity first. Read requirements with `subject_kind=identity`, its `cid_` identifier as `subject_id`, `program=business`, and `country_code=ZZ`. File against that same identity. An inline identity on a number submission does not replace this identity-verification flow.

The review uses your submitted business details, declared contacts, and verification evidence. Filing through an API key or the dashboard does not establish a different business relationship. Keep contact details accurate and provide the evidence requested by the form.

## File for an SMS sender instead

An SMS sender's paperwork uses the same requirements, attachments, submission and correction requests, with the sender's registration as the subject. [Register an SMS sender over the API](/docs/guides/sms/sender-registration-api) covers getting that registration and checking its price first.

## When a request is refused

| Response            | What it means                                                                                           | What to do                                                                                         |
| ------------------- | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `403` with `E02035` | For a standalone compliance write, the key lacks the `compliance` scope or holds it at read level only. | Use a key with `compliance` at write level.                                                        |
| `422` with `E19001` | We have no ownership form for the number's country yet.                                                 | Contact support to ask for that country.                                                           |
| `422` with `E19013` | The requirements read had no `subject_id` and no `program`.                                             | Send the number's `nda_` identifier, or `program` when you read before buying.                     |
| `422` with `E01001` | The submission leaves out a required field or has an invalid answer.                                    | Fix each field named in `details` and send the whole submission again under a new idempotency key. |
| `409` with `E19009` | The number already has a submission for its current form.                                               | Replace the answers that need it with the resupply request.                                        |
| `409` with `E01009` | The resupply targets a closed submission.                                                               | Contact support. If we reopen it, file what `ownership.next` names.                                |
| `422` with `E19003` | A replacement targets an answer that is under review, or accepted outside a correction we requested.    | Replace only answers whose `state` is `rejected`, `expired`, or `not_supplied`.                    |
| `404` with `E01008` | The number is not in this workspace, or `country_code` is not the number's country.                     | Send the `country_code` that `GET /v1/numbers/{number_id}` reports.                                |

[Errors](/docs/guides/errors) explains the error body and its `remediation`.

## Next steps

- [Numbers overview](/docs/guides/numbers/overview)
- [Buy and release a number](/docs/guides/numbers/buying-numbers)
- [Managing your phone numbers](/docs/guides/numbers/managing-numbers)
- [Migrate from Telserv to Bird](/docs/guides/numbers/migrate/telserv)

## Related resources

- [What is a virtual phone number (VMN)?](/explained/numbers/what-is-a-virtual-phone-number) (answer)
- [SMS numbers](/sms-api/features/numbers) (product)
- [Number types](/docs/guides/numbers/number-types) (docs)

[Get an implementation brief](/learn/workspace?topic=phone-numbers)
