---
title: "Get what a registration needs"
method: GET
path: "/v1/compliance/requirements"
tags: ["compliance"]
---

# Get what a registration needs

`GET /v1/compliance/requirements`

## Request

- Base URL: `https://us1.platform.bird.com`
- URL: `https://us1.platform.bird.com/v1/compliance/requirements`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `bird_session`

Returns everything a country requires before a registration can be approved, in the order to
present it, along with what you have already supplied and where each item stands.

Everything you need to answer an item comes back with it. That covers the accepted values
where an item takes a fixed set, the constraints a value must satisfy, and guidance on what
a good answer looks like. Items that take a document say so, and some offer a blank form to download and
complete. An unsupported country returns `422` rather than an empty result.

This answers one country for one registration you already hold. Omit `subject_id` and it
answers the form alone, unanswered: every requirement reads `not_supplied`, nothing is
satisfied, and there is no submission behind it, which is the state a registration you
have not started is in anyway. Reading it that way needs `program`, since the coordinate
is otherwise resolved from the registration.

For a number you hold, pass its ID from `GET /v1/numbers` as `subject_id`. For an SMS sender,
call `GET /v1/sms/senders/{sender_id}/requirements` and pass a row's `registration_id` as
`subject_id`.

## Query parameters

- `subject_kind` 'sms_sender' | 'number' | 'identity', required: What is being registered. - `sms_sender`: a sender registered to send to one country. - `number`: a phone number you hold that needs ownership paperwork before it can carry traffic. - `identity`: a business you operate as, registered once and reused by later registrations that name it.
- `subject_id` string: What is being registered. For `sms_sender` this is the `scr_` id returned when you register a sender for a country. For `number` it is the `nda_` id of a dedicated number you hold, as returned by `GET /v1/numbers`. A shared short code (`nal_`) is not accepted: it is shared, so its ownership paperwork is not yours to file. For `identity` it is the `cid_` id of the party being registered, picked from the parties your workspace holds, as returned by `GET /v1/compliance/identities`.
- `country_code` string, required: ISO 3166-1 alpha-2 country code.
- `program` string: The registration program a country runs. Available programs depend on the registered resource. An SMS sender registers under an authority regime (`alpha` or `numeric`). A phone number proves ownership under its number type (`mobile`, `local`, `national`, `short_code`, `short_code_fteu`, or `toll_free`), matching the values of `NumberType`. An identity registers your business itself under `business`, internationally: its coordinate's country is always `ZZ`. A value is therefore only meaningful alongside the subject it describes. More are added as coverage grows, so treat this as an open set rather than a fixed list.
- `identity_id` string

## Headers

- `X-Workspace-Id` string
- `X-Organization-Id` string

## Response `200`

What this country requires, and where you stand with it.

- ComplianceRequirement
  - `next` NextAction[]: What to do next about this country's requirements, given the state it is in. Each entry names one action and says why it is worth taking, so you can act on this response without working out the order yourself. Present on reads that compute it: an empty list means there is nothing to do, and the field is absent entirely on responses that do not report next actions. Whether anything is asked of you is `needs_input`, and this says what to do about it: send your answers where none have been filed, or replace the ones that were refused. Which items those are, and why each was refused, is on the item in `fields`. For feedback about the whole submission, read `reason` and `general_reasons` and update the details that need correction.
    - `kind` string, required: What you do about this step. - `operation`: call the operation named in `operation`, then read again. - `external`: act somewhere this API does not reach, then read again. - `wait`: nothing is asked of you, so read again later. - `terminal`: nothing you do resolves this, so stop retrying. Tolerate a value you do not recognize: show the `description` and offer no action.
    - `description` string, required: A short, human-readable label for the step, suitable for display.
    - `operation` string: The operationId to call. Present only when `kind` is `operation`. The operation's own schema says how to call it; this says only which one, and what to address it with.
    - `params` object: The parameters that address the operation, by name: `{"sender_id": "…"}` for an operation on `/v1/sms/senders/{sender_id}/requirements`. A parameter the operation takes in its query string is given the same way, so an operation addressed as `?subject_id=` carries `{"subject_id": "…"}`. Every parameter the call needs is here, whether its value came from the thing you were acting on or is fixed for this step, so you can make the call from this object alone. Present only when `kind` is `operation` and the operation names a subject. A request body, when the operation takes one, is described by the operation's own schema and never appears here.
    - `url` string, uri: A URL to open. Present only when `kind` is `external`, and only when the step has one. An external step whose `description` says to go and do something with no URL to open is normal.
  - `subject_kind` 'sms_sender' | 'number' | 'identity', required: What is being registered. - `sms_sender`: a sender registered to send to one country. - `number`: a phone number you hold that needs ownership paperwork before it can carry traffic. - `identity`: a business you operate as, registered once and reused by later registrations that name it.
  - `subject_id` string, required: What is being registered. For `sms_sender` this is the `scr_` id returned when you register a sender for a country. For `number` it is the `nda_` id of a dedicated number you hold, as returned by `GET /v1/numbers`. A shared short code (`nal_`) is not accepted: it is shared, so its ownership paperwork is not yours to file. For `identity` it is the `cid_` id of the party being registered, picked from the parties your workspace holds, as returned by `GET /v1/compliance/identities`.
  - `program` string, required: The registration program a country runs. Available programs depend on the registered resource. An SMS sender registers under an authority regime (`alpha` or `numeric`). A phone number proves ownership under its number type (`mobile`, `local`, `national`, `short_code`, `short_code_fteu`, or `toll_free`), matching the values of `NumberType`. An identity registers your business itself under `business`, internationally: its coordinate's country is always `ZZ`. A value is therefore only meaningful alongside the subject it describes. More are added as coverage grows, so treat this as an open set rather than a fixed list.
  - `country_code` string, required: ISO 3166-1 alpha-2 country code.
  - `satisfied` boolean, required: Whether this country's requirements are met. `true` when no requirements apply, or once the submission is approved and every required requirement is approved or marked not applicable. This can remain true when an external verifier requests a correction. Once you submit that correction, it must pass review before this becomes true again, including any optional answers you change.
  - `needs_input` boolean, required: Whether anything is waiting on you. True when a required requirement has no answer, its answer was refused or has gone stale, or the registration needs correction as described by `reason`. False does not imply that review is pending: a closed verifier correction can leave the requirements unsatisfied with no editable answers. Read `review_pending` to determine whether an answer is awaiting review. Read this independently of `satisfied`, which reports whether your paperwork is accepted. An unresolved verifier correction also sets it while the matching grant is live and the correction deadline has not passed, until you supply updated details. At the deadline or after grant withdrawal, an unresolved rejection alone does not set it because accepted answers can no longer be replaced. A corrected optional answer that is rejected or expires still needs your input through ordinary resupply, including after that deadline.
  - `review_pending` boolean, required: Whether any submitted answer is awaiting or undergoing review. False after all answers have received verdicts. A closed verifier correction can remain unsatisfied with no review pending and no editable answers.
  - `reason` string, nullable, required: What to correct about the registration as a whole, or null when no registration-wide correction is requested. Reasons about individual answers are on the entries in fields.
  - `guidance` string, nullable, required: What this country expects of you before and while you fill in the form, written by Bird's compliance team. It may point you to a registration you must complete elsewhere first. `null` when the form needs no introduction, or when no program applies.
  - `submission_id` string, required
  - `obligation` ComplianceObligation, required
    - `reason` string, required: Why a registration that is already authorised has been asked for something more. - `policy_change` means the country published a newer version of its form and your answers were given under an older one. - `evidence_expiry` means an answer we accepted has gone stale and needs supplying again. - `verdict_withdrawn` means this registration was relying on an approval earned on another registration, and that approval has since been taken back, so the answer needs checking again here. Your answer has not changed and has not expired. - `verifier_rejected` means an outside party we filed your details with reviewed them and refused them. Your answer has not changed and has not expired, and we did not overrule it. Treat this as an open set rather than a fixed list. More reasons are added as more of a registration is kept under review, so a value you do not recognise is one this server added rather than an error.
    - `state` string, required: Where an obligation stands. - `open`: the due date has not passed and nothing has been supplied. - `satisfied`: you supplied what was asked. - `lapsed`: the date passed unmet and the registration is no longer authorised. - `extended`: someone here gave you more time, and `due_at` reports the later date.
    - `due_at` string, date-time, required: The date to supply this by. Where more time has been given, this is the later date rather than the one first asked for.
    - `target_version` integer, required: The version of the country's form your answers have to reach. For an expiry it is the version you already answered, filled in again.
  - `general_reasons` string[], required: Feedback about the submission as a whole from an external verifier. It can remain visible while corrections are under review. Empty when no unresolved verifier feedback applies. On requirements responses, read `needs_input` to determine whether action is needed and `editable_for_verifier_repair` on each field to determine whether an approved or not-applicable answer can be replaced.
  - `fields` ComplianceRequirementField[], required: Every requirement for this country, in the order to present them.
    - `parent_key` string: Parent field grouping this named document. Absent for an ordinary field.
    - `document_key` string: Stable document key within the parent field. Absent for an ordinary field.
    - `parent_label` string: Display name of the parent field grouping this document. Absent for an ordinary field.
    - `parent_help_text` string: The parent field's own description, shared by every document in the group. Each document's `help_text` describes that document alone. Absent for an ordinary field and when the parent has no description.
    - `key` string, required: Identifies this requirement. Use it as the key when you submit a value.
    - `label` string, required: What to call this requirement when you ask someone for it.
    - `help_text` string, nullable, required: Guidance on what a good answer looks like, including anything the destination country expects. `null` when the label speaks for itself.
    - `data_type` 'string' | 'text' | 'enum' | 'number' | 'boolean' | 'date' | 'url' | 'country' | 'document', required: The kind of value a requirement takes. The `string` value is a single line, while `text` runs to several. The `enum` value accepts only the values listed with the requirement. The `number`, `boolean`, and `date` values take their corresponding data types. The `url` value takes a link. The `country` value takes an uppercase ISO 3166-1 alpha-2 code, such as `NL`. The `document` value means a file you upload first and then reference. All other values are supplied inline.
    - `required` boolean, required: Whether an answer is needed before the registration can be approved. Optional requirements are still reviewed when you supply them.
    - `section` string, required: A stable key grouping related requirements together. Use it to keep your own grouping consistent across requests; use section_label for what to show someone.
    - `section_label` string, required: What to call this requirement's group when you present it.
    - `options` ComplianceRequirementFieldOption[], required: The accepted values, already resolved, when the data type is `enum`. Empty for every other type.
      - `value` string, required: What to send.
      - `label` string, required: What to show.
    - `validation` ComplianceFieldValidation, required: Constraints a value must satisfy, where the requirement sets any. Which of these apply follows from its data type: `pattern`, `min_length` and `max_length` constrain `string` and `text` values, `minimum` and `maximum` constrain `number` values, and everything else is `null`. Check these before submitting and you avoid a round trip.
      - `pattern` string, nullable: A regular expression the value must match. `null` when the requirement takes neither `string` nor `text`, or sets no pattern.
      - `min_length` integer, nullable: Shortest accepted value. `null` when the requirement takes neither `string` nor `text`, or sets no minimum length.
      - `max_length` integer, nullable: Longest accepted value. `null` when the requirement takes neither `string` nor `text`, or sets no maximum length.
      - `minimum` number, nullable: Smallest accepted number. `null` when the requirement does not take `number`, or sets no minimum.
      - `maximum` number, nullable: Largest accepted number. `null` when the requirement does not take `number`, or sets no maximum.
    - `template_url` string, nullable, required: A blank form to download, complete and upload back, for requirements that need a signed document. `null` when the requirement has no form to download.
    - `max_items` integer, nullable, required: How many answers this requirement takes, when it takes more than one. `null` for a requirement answered once, which is most of them. Where it is set, answer with `values` or `attachment_ids` and read your answer back from the same pair; `value` and `attachment_id` stay `null`. Order is kept as you send it, and it is part of the answer: a keyword list beginning with `STOP` is not the same declaration as one ending with it.
    - `value` string, nullable, required: Your answer, for a requirement answered inline. Every answer travels as a string whatever its data type, so a number reads back as `"1500"` and a yes-or-no as `"true"`. Use the data type to parse it. `null` for a requirement that takes a document, and before you have answered.
    - `prefilled` boolean, required: `true` when `value` comes from the party this registration is for. Accept it as it stands or replace it; either way it becomes your answer when you submit. Only a requirement that asks about the party is ever prefilled.
    - `attachment_id` string, required
    - `values` string[], nullable, required: Your answers, for a requirement that takes several and is answered inline. Set only when `max_items` is, and `null` otherwise, including before you have answered. Each answer travels as a string whatever the data type, the same as `value`.
    - `attachment_ids` AttachmentID[], nullable, required: The documents you supplied, for a requirement that takes several. Set only when `max_items` is and the requirement takes documents, and `null` otherwise.
    - `state` string, required: Where one requirement stands. The `not_supplied` state means nothing has been given for it yet. The `supplied` state means we have your answer and review has not started. The `in_review` state means someone is looking at it. The `approved` and `rejected` states are decisions. You can replace a rejected item without refiling the rest. The `not_applicable` state means this requirement does not apply to you. The `expired` state means the value was accepted but has since gone stale. An item only ever reports its state. Treat this as an open set because review can gain stages. A value you do not recognise is a valid state that this server added.
    - `decided_at` string, date-time, nullable, required: When this was decided. `null` while no decision has been made.
    - `expires_at` string, date-time, nullable, required: When this answer goes stale and must be supplied again. `null` when it does not expire.
    - `editable_for_verifier_repair` boolean, required: Whether you may replace this accepted answer to correct the submission after external verification. This permission does not change its `state` or `reason`. Submit only answers whose content or attachment identity you change.
    - `reason` string, nullable, required: Why this requirement was rejected, when it was. `null` otherwise.
  - `closed_at` string, date-time, nullable: When the submission for these requirements was closed. Null while open or not yet submitted.

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Insufficient permissions
- `404`: Resource not found
- `422`: The request has invalid field values, violates a business rule, or carries a query parameter the endpoint does not declare. Field validation errors use `type: validation_error` and include the affected fields in `details`. Business-rule errors identify the failed rule in `type`.
- `429`: Rate limit exceeded
- `500`: Internal server error

## Changes

- **2026-10-20** `a1977645a499`: 1 info
  - endpoint added
- **2026-10-20** `6cec81ac4862`: 1 breaking
  - api path removed without deprecation
- **2026-10-20** `3e2a50466454`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/messagebird/apis/bird-api/changes/v1/compliance/requirements/get.md)

---

[API](https://skmtc.dev/messagebird/apis/bird-api.md) · [All operations](https://skmtc.dev/messagebird/apis/bird-api/llms.txt) · [OpenAPI document](https://skmtc.dev/messagebird/apis/bird-api/revisions/483bb7bfdc89?raw)
