# Branded calling

Show your business name, logo and reason for calling on the callee's phone: register the business, create a caller identity, pass vetting, then attach your US numbers.

import { Tab, Tabs } from 'fumadocs-ui/components/tabs';

By the end of this page, outbound calls from your US numbers show your business name, logo and reason for calling on the callee's phone. That replaces a bare number or "Spam Likely".

## What it costs

Branded Calling bills 2 lines to your usage invoice:

- $100 per caller identity per month while the identity is verified. The first month is charged when the carrier verifies the identity, never when Zernio files it: nothing is charged during review or carrier vetting, and a rejected identity is never charged. The fee then bills monthly while the identity stays verified. [Deleting the identity](#stop-paying) ends it.
- $0.10 per branded call: every outbound phone call placed from a number attached to a verified identity to a US number, on top of the [per-minute rate](/pricing/phone). The carrier charges Zernio per displayed call; Zernio bills per call placed, because the carriers do not report which calls displayed.

Registering a business and attaching numbers cost nothing extra.

On the prepaid balance, submitting an identity needs its first month in the balance, unless auto top-up can refill it. It stays set aside until the carrier verifies or rejects the identity.

The full table is in [Call rates](/pricing/phone#branded-calling).

## Where it displays

Branded Calling rides the STIR/SHAKEN signature of the call. Once a number is attached to a verified caller identity, every call from it carries the identity, and nothing changes on the dial.

The carriers verify eligibility. They do not guarantee display.

- Calls from US numbers to US mobiles on T-Mobile and Verizon.
- Samsung, Motorola and TCL phones on Android 14 or later, and iPhone XS or newer on iOS 18.5 or later. Carrier-provisioned phones display most reliably; unlocked, BYOD and MVNO phones may show less or nothing.
- Landlines, international destinations and other number types never display it.
- SIP trunk and browser-softphone calls from an attached number are branded too: the identity belongs to the number, not to the call.

## Before you start

You need a [voice-enabled US number](/platforms/voice/setup), usage-based billing, and a business registered in the US or Canada. Everything runs under `/v1/branded-calling`.

Vetting is asynchronous and involves people: the carrier phones the three references you name.

Track the identity with `GET /v1/branded-calling/identities/{id}` or the [webhooks](/webhooks/phone). Do not attach numbers until `status` is `verified`.

## Step 1: Register the business

Call `POST /v1/branded-calling/enterprises` with the legal entity behind the identity.

Only businesses registered in the US or Canada qualify (a FEIN or the Canadian equivalent is required). Any other country returns `422` with `code: "feature_not_available"`.

The tax id is stored encrypted. Only its last four digits are ever returned.

Nothing is filed with the carrier yet. The business is created there when its first identity passes review.

<Tabs items={['Node.js', 'Python', 'curl']}>
<Tab value="Node.js">
```typescript
import Zernio from '@zernio/node';

const zernio = new Zernio();

const { data: business } = await zernio.brandedcalling.createBrandedCallingEnterprise({
  body: {
    legalName: 'Acme Plumbing LLC',
    doingBusinessAs: 'Acme Plumbing',
    organizationType: 'commercial',
    organizationLegalType: 'llc',
    countryCode: 'US',
    jurisdictionOfIncorporation: 'Delaware',
    website: 'https://acmeplumbing.example',
    fein: '12-3456789',
    industry: 'business',
    numberOfEmployees: '11-50',
    organizationContact: { firstName: 'Sam', lastName: 'Owner', email: 'sam@acmeplumbing.example', jobTitle: 'CEO', phoneNumber: '+13125550100' },
    billingContact: { firstName: 'Pat', lastName: 'Bills', email: 'pat@acmeplumbing.example', phoneNumber: '+13125550101' },
    physicalAddress: { streetAddress: '1 Main St', city: 'Chicago', administrativeArea: 'IL', postalCode: '60601', country: 'US' },
    billingAddress: { streetAddress: '1 Main St', city: 'Chicago', administrativeArea: 'IL', postalCode: '60601', country: 'US' },
  }
});
const enterpriseId = business.id;
```
</Tab>
<Tab value="Python">
```python
from zernio import Zernio

client = Zernio()

business = client.branded_calling.create_branded_calling_enterprise(
    legal_name="Acme Plumbing LLC",
    doing_business_as="Acme Plumbing",
    organization_type="commercial",
    organization_legal_type="llc",
    country_code="US",
    jurisdiction_of_incorporation="Delaware",
    website="https://acmeplumbing.example",
    fein="12-3456789",
    industry="business",
    number_of_employees="11-50",
    organization_contact={"firstName": "Sam", "lastName": "Owner", "email": "sam@acmeplumbing.example", "jobTitle": "CEO", "phoneNumber": "+13125550100"},
    billing_contact={"firstName": "Pat", "lastName": "Bills", "email": "pat@acmeplumbing.example", "phoneNumber": "+13125550101"},
    physical_address={"streetAddress": "1 Main St", "city": "Chicago", "administrativeArea": "IL", "postalCode": "60601", "country": "US"},
    billing_address={"streetAddress": "1 Main St", "city": "Chicago", "administrativeArea": "IL", "postalCode": "60601", "country": "US"},
)
enterprise_id = business["id"]
```
</Tab>
<Tab value="curl">
```bash
curl -X POST "https://zernio.com/api/v1/branded-calling/enterprises" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "legalName": "Acme Plumbing LLC",
    "doingBusinessAs": "Acme Plumbing",
    "organizationType": "commercial",
    "organizationLegalType": "llc",
    "countryCode": "US",
    "jurisdictionOfIncorporation": "Delaware",
    "website": "https://acmeplumbing.example",
    "fein": "12-3456789",
    "industry": "business",
    "numberOfEmployees": "11-50",
    "organizationContact": { "firstName": "Sam", "lastName": "Owner", "email": "sam@acmeplumbing.example", "jobTitle": "CEO", "phoneNumber": "+13125550100" },
    "billingContact": { "firstName": "Pat", "lastName": "Bills", "email": "pat@acmeplumbing.example", "phoneNumber": "+13125550101" },
    "physicalAddress": { "streetAddress": "1 Main St", "city": "Chicago", "administrativeArea": "IL", "postalCode": "60601", "country": "US" },
    "billingAddress": { "streetAddress": "1 Main St", "city": "Chicago", "administrativeArea": "IL", "postalCode": "60601", "country": "US" }
  }'
```
</Tab>
</Tabs>

Response (`201`):

```json
{
  "id": "66f1a2b3c4d5e6f7a8b9c0d1",
  "legalName": "Acme Plumbing LLC",
  "doingBusinessAs": "Acme Plumbing",
  "countryCode": "US",
  "feinLast4": "6789",
  "registered": false,
  "createdAt": "2026-09-28T12:00:00.000Z"
}
```

One business serves any number of identities.

**Already on 10DLC?** When you hold a [10DLC registration](/platforms/sms/setup) for the same business, its brand carries the same legal name, tax id, address and contacts. Copy them from `GET /v1/sms/registrations/{id}` instead of asking twice.

[Register a business](/branded-calling/create-branded-calling-enterprise) lists every field.

## Step 2: Create the caller identity

A caller identity is what the callee sees, plus what the carrier vets.

Call `POST /v1/branded-calling/identities` with:

- `displayName`: 1 to 35 characters, no emoji. The name the public knows the business by; a name that is not the business's own (another brand, a bank, a government body) is rejected as impersonation.
- `callReasons`: 1 to 10 reasons you call, up to 64 characters each. Reasons taken from `GET /v1/branded-calling/call-reasons` (the carrier catalogue: "Appointment Reminder", "Order Confirmation", "Delivery ETA", "Customer Service" and 40 more) pass automatically; any other wording is vetted by hand and takes longer.
- `logoUrl` (optional): an HTTPS PNG, JPEG, WebP or SVG. Zernio converts it to the 256x256 BMP the carriers require and hosts it. Use the business's own mark, the one on its website.
- `authorizer`: a real person at the business who authorizes the registration. The carrier emails a 6-digit code to this address after review, and any trademark complaint later.
- `references`: two business references (senior contacts at a vendor, partner or client) and one financial reference (the company's CPA, or a contact at its bank). The carrier vetting team phones each of them, in their local 8am to 9pm window, so give a direct number, a monitored email and the right IANA timezone.

Send an `Idempotency-Key` header so a retried request returns the same identity instead of creating a second one ([idempotency](/guides/idempotency)).

<Tabs items={['Node.js', 'Python', 'curl']}>
<Tab value="Node.js">
```typescript
import { randomUUID } from 'crypto';
import Zernio from '@zernio/node';

const zernio = new Zernio();

const { data: identity } = await zernio.brandedcalling.createBrandedCallingIdentity({
  headers: { 'Idempotency-Key': randomUUID() },
  body: {
    enterpriseId: '66f1a2b3c4d5e6f7a8b9c0d1',
    displayName: 'Acme Plumbing',
    callReasons: ['Appointment Reminder', 'Customer Service'],
    logoUrl: 'https://acmeplumbing.example/logo.png',
    authorizer: { name: 'Sam Owner', email: 'sam@acmeplumbing.example' },
    references: {
      business: [
        { fullName: 'Dana Reyes', jobTitle: 'VP Operations', organization: 'Reyes Supply', relationshipToRegistrant: 'Supplier', phoneNumber: '+14155550123', email: 'dana@reyessupply.example', timezone: 'America/New_York' },
        { fullName: 'Lee Park', jobTitle: 'Owner', organization: 'Park Realty', relationshipToRegistrant: 'Client', phoneNumber: '+14155550124', email: 'lee@parkrealty.example', timezone: 'America/Chicago' },
      ],
      financial: { fullName: 'Morgan Cole', jobTitle: 'CPA', organization: 'Cole Accounting', phoneNumber: '+14155550125', email: 'morgan@coleaccounting.example', timezone: 'America/Los_Angeles' },
    },
  }
});
const identityId = identity.id;
```
</Tab>
<Tab value="Python">
```python
import uuid
from zernio import Zernio

client = Zernio()

identity = client.branded_calling.create_branded_calling_identity(
    enterprise_id="66f1a2b3c4d5e6f7a8b9c0d1",
    display_name="Acme Plumbing",
    call_reasons=["Appointment Reminder", "Customer Service"],
    logo_url="https://acmeplumbing.example/logo.png",
    authorizer={"name": "Sam Owner", "email": "sam@acmeplumbing.example"},
    references={
        "business": [
            {"fullName": "Dana Reyes", "jobTitle": "VP Operations", "organization": "Reyes Supply", "relationshipToRegistrant": "Supplier", "phoneNumber": "+14155550123", "email": "dana@reyessupply.example", "timezone": "America/New_York"},
            {"fullName": "Lee Park", "jobTitle": "Owner", "organization": "Park Realty", "relationshipToRegistrant": "Client", "phoneNumber": "+14155550124", "email": "lee@parkrealty.example", "timezone": "America/Chicago"},
        ],
        "financial": {"fullName": "Morgan Cole", "jobTitle": "CPA", "organization": "Cole Accounting", "phoneNumber": "+14155550125", "email": "morgan@coleaccounting.example", "timezone": "America/Los_Angeles"},
    },
    extra_headers={"Idempotency-Key": str(uuid.uuid4())},
)
identity_id = identity["id"]
```
</Tab>
<Tab value="curl">
```bash
curl -X POST "https://zernio.com/api/v1/branded-calling/identities" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Idempotency-Key: 8d1e5c1a-4b2f-4c6e-9f2a-3b7c1d9e0f11" \
  -H "Content-Type: application/json" \
  -d '{
    "enterpriseId": "66f1a2b3c4d5e6f7a8b9c0d1",
    "displayName": "Acme Plumbing",
    "callReasons": ["Appointment Reminder", "Customer Service"],
    "logoUrl": "https://acmeplumbing.example/logo.png",
    "authorizer": { "name": "Sam Owner", "email": "sam@acmeplumbing.example" },
    "references": {
      "business": [
        { "fullName": "Dana Reyes", "jobTitle": "VP Operations", "organization": "Reyes Supply", "relationshipToRegistrant": "Supplier", "phoneNumber": "+14155550123", "email": "dana@reyessupply.example", "timezone": "America/New_York" },
        { "fullName": "Lee Park", "jobTitle": "Owner", "organization": "Park Realty", "relationshipToRegistrant": "Client", "phoneNumber": "+14155550124", "email": "lee@parkrealty.example", "timezone": "America/Chicago" }
      ],
      "financial": { "fullName": "Morgan Cole", "jobTitle": "CPA", "organization": "Cole Accounting", "phoneNumber": "+14155550125", "email": "morgan@coleaccounting.example", "timezone": "America/Los_Angeles" }
    }
  }'
```
</Tab>
</Tabs>

Response (`201`):

```json
{
  "id": "66f1a2b3c4d5e6f7a8b9c0d2",
  "enterpriseId": "66f1a2b3c4d5e6f7a8b9c0d1",
  "displayName": "Acme Plumbing",
  "callReasons": ["Appointment Reminder", "Customer Service"],
  "callReasonsPreApproved": true,
  "status": "requested",
  "rejectionReasons": [],
  "reviewRequest": null,
  "numbers": [],
  "createdAt": "2026-09-28T12:05:00.000Z"
}
```

The identity starts in Zernio review (`requested`).

- A `403` with `code: "usage_billing_required"` means the team is not on usage-based billing.
- A `422` on `logoUrl` means the image could not be downloaded or is not an image.

### Check before you submit

Call `POST /v1/branded-calling/identities/preflight` with the same body first. It runs the checks our review runs, without creating anything, and returns every finding at once:

```bash
curl -X POST "https://zernio.com/api/v1/branded-calling/identities/preflight" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d @identity.json
```

Response (`200`):

```json
{
  "ok": false,
  "findings": [
    { "code": "call_reason_not_in_catalogue", "severity": "warn", "param": "callReasons", "message": "\"Billing questions\" is not in the carrier catalogue and will be vetted by hand; \"Account Services\" is." },
    { "code": "duplicate_reference_phone", "severity": "block", "param": "references", "message": "Two references share +14155550123." }
  ]
}
```

A `block` finding fails our review. A `warn` finding slows vetting.

The codes:

- `display_name_differs_from_legal_name`
- `call_reason_not_in_catalogue`
- `duplicate_reference_phone`
- `reference_inside_business`
- `invalid_timezone`
- `free_mail_authorizer`
- `logo_unreachable`

`ok: true` means the body would enter review with nothing flagged.

## Step 3: Review, then the authorizer's code

Zernio reviews every identity before filing it, the way it reviews [10DLC registrations](/platforms/sms/setup):

- the business is checked against the registry and its website
- the display name and logo must be the business's own
- the references must be credible

Nothing is filed or billed while it is in review.

- If something needs to change, the identity moves to `changes_requested` and [`branded_calling.identity.action_required`](/webhooks/phone/branded-calling-identity-action-required) fires with the request as points. [Answer the review](#answer-the-review) below.
- When it passes, Zernio registers the business and the identity with the carrier. Nothing is billed yet: the first month is charged when the carrier verifies the identity. The carrier emails a 6-digit code to the authorizer, the identity moves to `pending_email_verification`, and `action_required` fires with `reason: "email_code"`.

Confirm the code with `POST /v1/branded-calling/identities/{id}/verify-email/confirm`.

On success, Zernio files the references and submits the identity to carrier vetting in the same call. It comes back `in_review`.

**A later step fails.** The identity stays `pending_email_verification` with the email already verified. Calling again resumes from that step.

**New code.** `POST /v1/branded-calling/identities/{id}/verify-email` sends a fresh code (the previous one stops working).

```bash
curl -X POST "https://zernio.com/api/v1/branded-calling/identities/66f1a2b3c4d5e6f7a8b9c0d2/verify-email/confirm" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code": "482915"}'
```

The vetting team then phones the three references.

The carrier publishes no turnaround. Expect days rather than minutes, and tell the references to expect the call.

Track the outcome with `GET /v1/branded-calling/identities/{id}` or [`branded_calling.identity.status_updated`](/webhooks/phone/branded-calling-identity-status-updated):

| Status | Meaning | What to do |
| --- | --- | --- |
| `requested` | In Zernio review. | Wait; our review usually finishes the same day. |
| `changes_requested` | We need something from you. | [Answer the review](#answer-the-review). |
| `rejected` | Zernio declined it before filing, or the carrier rejected it. | [Fix the rejection](#fix-a-rejection). |
| `pending_email_verification` | Filed. | Confirm the authorizer's code. |
| `in_review` | With the carrier vetting team. | Wait; warn the references. |
| `verified` | Live. | [Attach numbers](#step-4-attach-numbers). |
| `suspended` | A trademark or impersonation claim is open against the identity. | Nothing on your side while it is open; branding is paused and the identity cannot be deleted until it resolves. |
| `expired` | The yearly verification lapsed and the [renewal](#renewal) failed. | Edit and `PATCH` to resubmit. |
| `permanently_rejected` | Terminal. | Create a new identity. |

## Step 4: Attach numbers

Once the identity is `verified`, attach up to 15 numbers per call with `POST /v1/branded-calling/identities/{id}/numbers`.

The numbers must be active US numbers you own (`phoneNumberIds` from [List phone numbers](/phone-numbers/list-phone-numbers)). A number belongs to one identity at a time.

Attaching files a Letter of Authorization with the carrier. It is the document that lets the carrier register these numbers under the identity, naming Zernio as the agent managing them.

The carrier renders it from the business and identity on file. You supply:

- the signature as a PNG (base64, a `data:image/png;base64,` prefix is accepted)
- the signer's printed name

Send an `Idempotency-Key` here too: a retry must not open a second batch for the same numbers.

```bash
curl -X POST "https://zernio.com/api/v1/branded-calling/identities/66f1a2b3c4d5e6f7a8b9c0d2/numbers" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Idempotency-Key: 1f4c9a7e-2d3b-4a5c-8e6f-7a8b9c0d1e2f" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberIds": ["66d4e5f6a7b8c9d0e1f2a3b4"],
    "signature": { "imageBase64": "iVBORw0KGgoAAAANSUhEUgAA...", "signerName": "Sam Owner" }
  }'
```

Response (`201`):

```json
{
  "numbers": [
    { "phoneNumberId": "66d4e5f6a7b8c9d0e1f2a3b4", "phoneNumber": "+13125550100", "status": "submitted", "rejectionReason": null, "verifiedAt": null, "addedAt": "2026-10-06T09:00:00.000Z" }
  ]
}
```

The batch is vetted as a unit and is all-or-nothing. One ineligible number refuses the whole request with `422` naming it.

Each number shows the identity once its own status reaches `verified`. [`branded_calling.number.status_updated`](/webhooks/phone/branded-calling-number-status-updated) fires on each change.

<Callout type="warn">A number the carrier marks `permanently_rejected` can never be attached to any identity again.</Callout>

Detach numbers with `DELETE /v1/branded-calling/identities/{id}/numbers` and `phoneNumbers` (E.164, up to 100). The carrier deregisters them, and they can join another identity.

## Hand the form off (white-label)

When the business behind the identity is your customer, not you, call `POST /v1/branded-calling/share`.

It returns a single-use link (valid 7 days) where that business fills in the caller identity itself, with no Zernio login:

- the display name, logo and call reasons
- the authorizer the carrier will email
- the three references the carrier will phone

What they submit lands under your team as `requested` and goes through the same review as an API submission. It fires [`branded_calling.identity.status_updated`](/webhooks/phone/branded-calling-identity-status-updated) so you know it arrived.

Scope the link with one of:

- `identityId`: an identity of yours that is `requested` or `changes_requested`, to be completed or corrected by the business.
- `enterpriseId`: a registered business, to add a new identity to.
- Neither: the business registers itself (legal name, tax id, contacts, addresses) and its first identity in one go.

```bash
curl -X POST "https://zernio.com/api/v1/branded-calling/share" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enterpriseId": "66f1a2b3c4d5e6f7a8b9c0d1"}'
```

Response (`200`):

```json
{
  "url": "https://zernio.com/branded-calling/9Fh2...",
  "expiresAt": "2026-10-05T12:00:00.000Z"
}
```

The person opening the link enters their email (so you know who filled it in). Then they walk the same stepped form as the dashboard.

If they are not the right person, "Send to someone else" on the page mints a fresh link for them to forward and retires theirs.

The link dies on submit; mint another for a second identity.

The same action lives on the dashboard's Branded calling page as "Send to the business".

## Answer the review

A `changes_requested` identity carries the request as points in `reviewRequest`, one per thing to change. Each point has:

- an `id`
- a `title`
- a `detail`
- the kind of `answer` it takes (`text`, `link`, `file` or `link_or_file`)

Read it from `GET /v1/branded-calling/identities/{id}`:

```json
{
  "status": "changes_requested",
  "reviewRequest": {
    "id": "5b1c0d3e-9f2a-4b8c-8d7e-6f5a4b3c2d1e",
    "intro": "Thanks for the Acme Plumbing caller identity. Two things before we file it.",
    "points": [
      { "id": "p1", "title": "Financial reference", "detail": "Morgan Cole's email is a free-mail address. Send the firm's own address, or a bank contact.", "answer": "text" },
      { "id": "p2", "title": "Logo", "detail": "The logo on file is not the one on acmeplumbing.example. Send the mark from your site.", "answer": "link_or_file" }
    ]
  }
}
```

Answer with `PATCH /v1/branded-calling/identities/{id}`: `reviewAnswers` keyed by point id, plus any field you edited in the same call.

- A `text` point takes `text`.
- A `link` point takes `url`.
- A `file` point takes `url` too, pointing at the file after a [media upload](/guides/media-uploads).

The identity goes back to `requested`, and the review resumes where it stopped.

<Tabs items={['Node.js', 'Python', 'curl']}>
<Tab value="Node.js">
```typescript
import Zernio from '@zernio/node';

const zernio = new Zernio();

await zernio.brandedcalling.updateBrandedCallingIdentity({
  path: { id: '66f1a2b3c4d5e6f7a8b9c0d2' },
  body: {
    references: { /* the same references, with the CPA's firm address */ },
    logoUrl: 'https://acmeplumbing.example/logo-official.png',
    reviewAnswers: {
      p1: { text: 'Updated to morgan@coleaccounting.example, the firm address.' },
      p2: { url: 'https://acmeplumbing.example/logo-official.png' },
    },
  }
});
```
</Tab>
<Tab value="Python">
```python
from zernio import Zernio

client = Zernio()

client.branded_calling.update_branded_calling_identity(
    id="66f1a2b3c4d5e6f7a8b9c0d2",
    logo_url="https://acmeplumbing.example/logo-official.png",
    review_answers={
        "p1": {"text": "Updated to morgan@coleaccounting.example, the firm address."},
        "p2": {"url": "https://acmeplumbing.example/logo-official.png"},
    },
)
```
</Tab>
<Tab value="curl">
```bash
curl -X PATCH "https://zernio.com/api/v1/branded-calling/identities/66f1a2b3c4d5e6f7a8b9c0d2" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "logoUrl": "https://acmeplumbing.example/logo-official.png",
    "reviewAnswers": {
      "p1": { "text": "Updated to morgan@coleaccounting.example, the firm address." },
      "p2": { "url": "https://acmeplumbing.example/logo-official.png" }
    }
  }'
```
</Tab>
</Tabs>

Response (`200`): the identity, with `status: "requested"` and `reviewRequest: null`.

Answer every point in one call: a point you skip is asked again.

## Fix a rejection

Two reviews can reject an identity, and `rejectionReasons` tells them apart.

- Our review, before anything is filed: the identity is `rejected` with the reason in `reviewNote`, `rejectionReasons` is empty, and nothing was billed. Impersonation, prohibited content and a business we could not verify end here. Fix the fields and `PATCH`; the identity goes back to `requested`.
- The carrier, after filing: the identity is `rejected` with `rejectionReasons`, each with a `code`, a `title`, a `detail`, and on the first entry a `message` written by the vetting team:

```json
{
  "status": "rejected",
  "rejectionReasons": [
    { "code": "documentation_incomplete", "title": "Documentation incomplete", "detail": "Provided documents do not establish business identity.", "message": "The registry lists the entity as Acme Plumbing Services LLC; the legal name on file must match exactly." }
  ]
}
```

`PATCH` the fields the reasons name.

On a carrier rejection, the edits are applied at the carrier and the identity is resubmitted straight away. It comes back `in_review` without a second Zernio review.

Nothing is charged for the rejection or the resubmission. The first month bills only once the carrier verifies the identity.

<Callout type="warn">A `permanently_rejected` identity is terminal: create a new one. Get the display name and references right before filing, because a number the carrier marks `permanently_rejected` can never be branded again on your account.</Callout>

## Renewal

A verified identity lasts one year. `expiringAt` on the identity is the date.

Zernio resubmits the identity to the carrier 30 days before that date on its own. The registration stays live during the renewal review.

[`branded_calling.identity.status_updated`](/webhooks/phone/branded-calling-identity-status-updated) reports the new `verifiedAt` and `expiringAt` when it passes.

You only see `expired` when that renewal failed. Edit whatever the carrier flagged in `rejectionReasons` and `PATCH` to resubmit.

## Stop paying

`DELETE /v1/branded-calling/identities/{id}` detaches its numbers, removes the identity at the carrier and ends the monthly fee.

The month in progress is not prorated.

A `409` means a claim is open against the identity (`suspended`). It can be deleted once the claim resolves.

## Common questions

**The identity is verified and the number is verified, but the callee sees a bare number.** Display is decided by the receiving carrier and phone, and the carrier only verifies eligibility.

Check the destination against [where it displays](#where-it-displays). A landline, an AT&T subscriber, an MVNO, an unlocked phone or an old OS shows nothing, and that is expected.

Calls to a T-Mobile or Verizon subscriber on a carrier-provisioned Samsung, Motorola, TCL or iPhone XS+ are the reliable case.

**How long does vetting take?** The carrier publishes no turnaround. Our review usually finishes the same day.

Carrier vetting takes days. The vetting team phones the three references in their local business hours and cannot proceed until it reaches them.

**What are the references asked?** Whether they know the business, in what capacity, and whether it is the business the identity describes.

Nothing about you: the calls confirm the business exists and operates as stated. Pick people who will answer a call from an unknown US number.

**Are SIP trunk and browser calls branded?** Yes. The identity belongs to the number, so every outbound call from an attached number carries it, whichever path placed the call.

**What happens to the fee on rejection?** Nothing is charged. The first month bills only when the carrier verifies the identity.

A rejection, by our review or by the carrier, bills nothing. Resubmitting costs nothing extra.

Editing the display name, logo or call reasons of a verified identity sends it back to carrier vetting. That pauses the monthly fee until it is verified again.

**Can I use one identity for several businesses?** No. The display name must be the registered business's own name, and the carrier vets that match. Register each business and give each its own identity.

## If it fails

- `422` with `code: "feature_not_available"` on the business: the country is not US or CA. On numbers: a number is not a US number, or is not active.
- `409` with `code: "invalid_resource_state"`: the identity is not in a status that allows the action (editing outside `requested`, `changes_requested` or `rejected`; attaching numbers before `verified`; a number already on an identity; deleting while a claim is open).
- `400` on `code`: the 6-digit code is wrong or expired. Request a new one.
- `400` on a field of the identity names the field in `param`; run [preflight](#check-before-you-submit) first to catch every gap at once.

Every error uses the envelope in [error handling](/guides/error-handling).

## Related

- [Outbound calls](/platforms/voice/outbound): placing the calls that carry the identity.
- [Phone webhooks](/webhooks/phone): every event, with payloads.
- [Call rates](/pricing/phone#branded-calling): the monthly and per-call prices.
- [Carrier registration (10DLC)](/platforms/sms/setup): the same business details, for SMS.
- [Create a caller identity](/branded-calling/create-branded-calling-identity): every field of the request.