# Branded calling

Not available yet. Show your business name, logo and reason for calling on the callee's phone when you call from US numbers. Register the business, pass vetting, attach numbers.

> **Not available yet:**
> 
> Branded calling is not available yet: [creating a caller identity](https://pozy.ai/docs/api/createBrandedCallingIdentity) answers `403` with `code: "feature_not_available"`. Registering your business still works. The rest of this page describes branded calling as it will work.

With branded calling, the person you call sees your business name, logo and reason for calling instead of a plain number or a "Spam Likely" warning. It applies to calls from US numbers to US mobile phones. Attach a number to a verified caller identity and all its calls carry the brand; you dial exactly as before.

## Where it shows

The carriers verify that you are eligible. They do not promise the display on every phone.

| Shows | Does not show |
| --- | --- |
| Calls from US numbers to US mobiles on T-Mobile and Verizon | Landlines and international destinations |
| Samsung, Motorola and TCL phones on Android 14 or later | Most unlocked, bring-your-own and prepaid-brand phones (may show less or nothing) |
| iPhone XS or newer on iOS 18.5 or later | Other carriers |

Outbound calls placed through the API, the [browser](https://pozy.ai/docs/telephony/browser-calling) or a [SIP trunk](https://pozy.ai/docs/telephony/sip-trunks) are all branded, because the identity belongs to the number.

## What it costs

| Item | Price |
| --- | --- |
| Caller identity | $100 a month for as long as it is verified. You pay the first month only once the carrier verifies it, and nothing while it is in review or vetting, or if it is turned down. |
| Branded call | $0.10 for each outbound call from an attached number to a US number, added to the per-minute rate. Carriers do not say which calls showed the brand, so all of those calls are counted. |
| Registering the business, attaching numbers | Free |

Deleting the identity ends the monthly fee. The month in progress is not prorated.

## Before you start

- A voice-enabled US number.
- A payment method on file. Without one, creating an identity returns `403 usage_billing_required`.
- A business registered in the US or Canada, with a federal tax id.

Vetting involves people: the carrier phones three references you name. Expect days, not minutes.

### Register the business
`POST /v1/branded-calling/enterprises` with the legal entity. Nothing is filed with the carrier yet. The tax id is stored encrypted, and only its last four digits are ever returned (`feinLast4`). One business can have any number of identities.

```bash cURL
curl -X POST https://api.pozy.ai/v1/branded-calling/enterprises \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "legalName": "Acme Plumbing LLC",
    "doingBusinessAs": "Acme Plumbing",
    "organizationType": "commercial",
    "organizationLegalType": "llc",
    "countryCode": "US",
    "jurisdictionOfIncorporation": "Illinois",
    "website": "https://acmeplumbing.example",
    "fein": "12-3456789",
    "industry": "home services",
    "numberOfEmployees": "11-50",
    "organizationContact": { "firstName": "Sam", "lastName": "Rivera", "email": "sam@acmeplumbing.example", "jobTitle": "Owner", "phoneNumber": "+13125550100" },
    "billingContact": { "firstName": "Pat", "lastName": "Lee", "email": "billing@acmeplumbing.example", "phoneNumber": "+13125550101" },
    "physicalAddress": { "streetAddress": "100 N State St", "city": "Chicago", "administrativeArea": "IL", "postalCode": "60602", "country": "US" },
    "billingAddress": { "streetAddress": "100 N State St", "city": "Chicago", "administrativeArea": "IL", "postalCode": "60602", "country": "US" }
  }'
```
```ts Node
const businessRes = await fetch("https://api.pozy.ai/v1/branded-calling/enterprises", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.POZY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    legalName: "Acme Plumbing LLC",
    doingBusinessAs: "Acme Plumbing",
    organizationType: "commercial",
    organizationLegalType: "llc",
    countryCode: "US",
    jurisdictionOfIncorporation: "Illinois",
    website: "https://acmeplumbing.example",
    fein: "12-3456789",
    industry: "home services",
    numberOfEmployees: "11-50",
    organizationContact: { firstName: "Sam", lastName: "Rivera", email: "sam@acmeplumbing.example", jobTitle: "Owner", phoneNumber: "+13125550100" },
    billingContact: { firstName: "Pat", lastName: "Lee", email: "billing@acmeplumbing.example", phoneNumber: "+13125550101" },
    physicalAddress: { streetAddress: "100 N State St", city: "Chicago", administrativeArea: "IL", postalCode: "60602", country: "US" },
    billingAddress: { streetAddress: "100 N State St", city: "Chicago", administrativeArea: "IL", postalCode: "60602", country: "US" },
  }),
});
const business = await businessRes.json();
if (!businessRes.ok) throw new Error(business.error);
console.log(business.id, business.feinLast4);
```
```python Python
import os, requests

address = {"streetAddress": "100 N State St", "city": "Chicago", "administrativeArea": "IL", "postalCode": "60602", "country": "US"}
resp = requests.post(
    "https://api.pozy.ai/v1/branded-calling/enterprises",
    headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
    json={
        "legalName": "Acme Plumbing LLC", "doingBusinessAs": "Acme Plumbing",
        "organizationType": "commercial", "organizationLegalType": "llc", "countryCode": "US",
        "jurisdictionOfIncorporation": "Illinois", "website": "https://acmeplumbing.example",
        "fein": "12-3456789", "industry": "home services", "numberOfEmployees": "11-50",
        "organizationContact": {"firstName": "Sam", "lastName": "Rivera", "email": "sam@acmeplumbing.example", "phoneNumber": "+13125550100"},
        "billingContact": {"firstName": "Pat", "lastName": "Lee", "email": "billing@acmeplumbing.example", "phoneNumber": "+13125550101"},
        "physicalAddress": address, "billingAddress": address,
    },
    timeout=30,
)
print(resp.json()["id"])
```

If you already registered the same business for [10DLC](https://pozy.ai/docs/telephony/10dlc), copy the legal name, tax id, address and contacts from that registration instead of asking again.

### Create the caller identity
`POST /v1/branded-calling/identities` describes what the callee sees and what the carrier vets. Send an `Idempotency-Key` so a retry does not create a second identity.

```json
{
  "enterpriseId": "66f1a2b3c4d5e6f7a8b9c0d1",
  "displayName": "Acme Plumbing",
  "callReasons": ["Appointment Reminder", "Customer Service"],
  "logoUrl": "https://acmeplumbing.example/logo.png",
  "authorizer": { "name": "Sam Rivera", "email": "sam@acmeplumbing.example" },
  "references": {
    "business": [
      { "fullName": "Dana Reyes", "jobTitle": "Operations Manager", "organization": "Reyes Supply", "relationshipToRegistrant": "Supplier", "phoneNumber": "+14155550123", "email": "dana@reyessupply.example", "timezone": "America/Chicago" },
      { "fullName": "Lee Park", "jobTitle": "Owner", "organization": "Park Realty", "relationshipToRegistrant": "Client", "phoneNumber": "+14155550124", "email": "lee@parkrealty.example", "timezone": "America/New_York" }
    ],
    "financial": { "fullName": "Morgan Cole", "jobTitle": "CPA", "organization": "Cole Accounting", "phoneNumber": "+14155550125", "email": "morgan@coleaccounting.example", "timezone": "America/Chicago" }
  }
}
```

| Field | Rules |
| --- | --- |
| `displayName` | Between 1 and 35 characters, without emoji: the name people know the business by. Using some other brand's name is refused as impersonation. |
| `callReasons` | 1 to 10 reasons, up to 64 characters each. Reasons from `GET /v1/branded-calling/call-reasons` pass automatically. Other wording is vetted by hand and takes longer. |
| `logoUrl` | HTTPS PNG, JPEG, WebP or SVG. Use the mark on the business's own website. Pozy converts and hosts it in the format carriers need. |
| `authorizer` | A real person at the business. The carrier emails them a 6-digit code after review. Avoid free-mail addresses. |
| `references` | Two business references (senior contacts at a supplier, partner or client) and one financial reference (the company's accountant or bank contact). The vetting team phones each one during their local business hours, so give direct numbers, monitored inboxes and the right IANA timezone. |

### Preflight the body
`POST /v1/branded-calling/identities/preflight` applies the review's checks without creating anything, and returns `ok` with a list of `findings`. A `block` finding means review would fail; a `warn` finding means vetting will take longer. Codes include `display_name_differs_from_legal_name`, `call_reason_not_in_catalogue`, `duplicate_reference_phone`, `reference_inside_business`, `invalid_timezone`, `free_mail_authorizer` and `logo_unreachable`.

### Pass review and confirm the code
The identity starts in `requested` while Pozy reviews it. When it passes, it is filed with the carrier and moves to `pending_email_verification`. The authorizer receives a 6-digit code, and `branded_calling.identity.action_required` fires with `reason: "email_code"`. Confirm it:

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

Now the identity is `in_review`, and the carrier's vetting team will call your references, so warn them first. If the email code ran out before it was used, `POST /v1/branded-calling/identities/{id}/verify-email` sends another.

### Attach numbers
Once the identity is `verified`, attach up to 15 active US numbers per call. Attaching files a letter of authorization with the carrier, so you include a signature image and the signer's name. Send an `Idempotency-Key` here too.

```bash
curl -X POST https://api.pozy.ai/v1/branded-calling/identities/66f1a2b3c4d5e6f7a8b9c0d2/numbers \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Idempotency-Key: brand-attach-2026-10-30" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberIds": ["6650d2e1b3c4d5e6f7081923"],
    "signature": { "imageBase64": "data:image/png;base64,iVBORw0KGgo...", "signerName": "Sam Rivera" }
  }'
```

Numbers are attached together or not at all: if any one is not eligible, the request fails with `422`. Every number begins as `submitted` and displays the identity when it becomes `verified`.

## Identity statuses

| Status | Meaning | What to do |
| --- | --- | --- |
| `requested` | In Pozy review | Wait. Review usually finishes the same day. |
| `changes_requested` | Review needs something from you | Answer the points (below) |
| `rejected` | Declined by review or by the carrier | Fix and resubmit |
| `pending_email_verification` | Filed. Waiting for the authorizer's code. | Confirm the code |
| `in_review` | With the carrier's vetting team | Wait. Warn the references. |
| `verified` | Live | Attach numbers |
| `suspended` | Someone filed a trademark or impersonation claim | Wait for the claim to close. Until then branding is off and the identity cannot be deleted. |
| `expired` | The yearly renewal failed | Edit and resubmit |
| `permanently_rejected` | Final | Create a new identity |

Number statuses are `submitted`, `in_review`, `verified`, `unsuccessful`, `suspended`, `expired` and `permanently_rejected`.

> **Important:**
> 
> Once the carrier sets a number to `permanently_rejected`, your workspace can never brand it again, so check the display name and references carefully before filing.

## Answer a change request

When an identity is `changes_requested`, `reviewRequest.points` lists what to fix, one point each. A point has an `id`, a `title`, a `detail` and the `answer` type it expects: `text`, `link`, `file` or `link_or_file`. Reply to all points in a single `PATCH /v1/branded-calling/identities/{id}`, putting the replies in `reviewAnswers` under each point's id along with any fields you edited. Points left unanswered come back.

```json
{
  "logoUrl": "https://acmeplumbing.example/logo-official.png",
  "reviewAnswers": {
    "p1": { "text": "Changed to morgan@coleaccounting.example, the firm address." },
    "p2": { "url": "https://acmeplumbing.example/logo-official.png" }
  }
}
```

## Fix a rejection

- **Rejected in Pozy review** (before filing): `reviewNote` explains why and `rejectionReasons` is empty. Impersonation, prohibited content and businesses that cannot be verified stop here. Fix the fields and `PATCH`.
- **Rejected by the carrier**: `rejectionReasons` lists each reason with a `code`, `title`, `detail`, and a `message` from the vetting team on the first entry. `PATCH` the named fields and the identity goes straight back to `in_review`.

Rejections and resubmissions cost nothing.

## Renewal

A verified identity lasts one year (`expiringAt`). Pozy resubmits it 30 days before that date, and the branding stays live during the renewal review. You only see `expired` if renewal failed.

Changing a verified identity's display name, logo or call reasons returns it to vetting. The monthly fee stops until it is verified once more.

## Let the business fill it in

> **Not available yet:**
> 
> Hosted identity forms are not available yet: `POST /v1/branded-calling/share` answers `403` with `code: "feature_not_available"`.

When the business behind the identity is your customer, `POST /v1/branded-calling/share` returns a single-use link (valid 7 days) where they complete the identity themselves, with no Pozy login. Scope the link with an `identityId` (to finish or correct one), an `enterpriseId` (to add a new identity to a registered business), or neither (the business registers itself and its first identity together). What they submit arrives under your workspace as `requested` and goes through the same review.

## Remove numbers or the identity

- `DELETE /v1/branded-calling/identities/{id}/numbers` with `phoneNumbers` (E.164, up to 100) detaches numbers. They can then join another identity.
- `DELETE /v1/branded-calling/identities/{id}` detaches every number, removes the identity at the carrier and stops the monthly fee. It returns `409` while a claim is open.

## Errors

| Status | Code | Cause | Fix |
| --- | --- | --- | --- |
| `422` | `feature_not_available` | The business is not in the US or Canada, or one of the numbers is not an active US number | Register a US or Canadian business, with active US numbers |
| `409` | `invalid_resource_state` | The identity's status does not allow the action (editing outside `requested`, `changes_requested` or `rejected`, attaching before `verified`, a number already on an identity, deleting during a claim) | Check `status` first |
| `400` | | The 6-digit code is incorrect or too old | Ask for another code |
| `403` | `usage_billing_required` | The workspace has no payment method | Add one |
| `422` | | `logoUrl` could not be downloaded or is not an image | Use a reachable HTTPS image |

## Endpoints

| Endpoint | What it does |
| --- | --- |
| [`GET /v1/branded-calling/enterprises`](https://pozy.ai/docs/api/listBrandedCallingEnterprises) | List registered businesses |
| [`POST /v1/branded-calling/enterprises`](https://pozy.ai/docs/api/createBrandedCallingEnterprise) | Register a business for Branded Calling |
| [`GET /v1/branded-calling/enterprises/{id}`](https://pozy.ai/docs/api/getBrandedCallingEnterprise) | Get a registered business |
| [`DELETE /v1/branded-calling/enterprises/{id}`](https://pozy.ai/docs/api/deleteBrandedCallingEnterprise) | Delete a registered business |
| [`POST /v1/branded-calling/share`](https://pozy.ai/docs/api/shareBrandedCallingIdentityForm) | Create a caller identity share link (not available yet) |
| [`GET /v1/branded-calling/call-reasons`](https://pozy.ai/docs/api/listBrandedCallingCallReasons) | List pre-approved call reasons |
| [`GET /v1/branded-calling/identities`](https://pozy.ai/docs/api/listBrandedCallingIdentities) | List caller identities |
| [`POST /v1/branded-calling/identities`](https://pozy.ai/docs/api/createBrandedCallingIdentity) | Create a caller identity (not available yet) |
| [`POST /v1/branded-calling/identities/preflight`](https://pozy.ai/docs/api/preflightBrandedCallingIdentity) | Dry-run a caller identity before creating it |
| [`GET /v1/branded-calling/identities/{id}`](https://pozy.ai/docs/api/getBrandedCallingIdentity) | Get a caller identity |
| [`PATCH /v1/branded-calling/identities/{id}`](https://pozy.ai/docs/api/updateBrandedCallingIdentity) | Edit or resubmit a caller identity |
| [`DELETE /v1/branded-calling/identities/{id}`](https://pozy.ai/docs/api/deleteBrandedCallingIdentity) | Delete a caller identity |
| [`POST /v1/branded-calling/identities/{id}/verify-email`](https://pozy.ai/docs/api/resendBrandedCallingAuthorizerCode) | Resend the authorizer's code |
| [`POST /v1/branded-calling/identities/{id}/verify-email/confirm`](https://pozy.ai/docs/api/confirmBrandedCallingAuthorizerEmail) | Confirm the authorizer's code |
| [`GET /v1/branded-calling/identities/{id}/numbers`](https://pozy.ai/docs/api/listBrandedCallingIdentityNumbers) | List the numbers on a caller identity |
| [`POST /v1/branded-calling/identities/{id}/numbers`](https://pozy.ai/docs/api/attachBrandedCallingNumbers) | Attach numbers to a verified identity |
| [`DELETE /v1/branded-calling/identities/{id}/numbers`](https://pozy.ai/docs/api/detachBrandedCallingNumbers) | Detach numbers from an identity |

## Webhook events

| Event | When it fires |
| --- | --- |
| [`branded_calling.identity.status_updated`](https://pozy.ai/docs/webhooks/events#branded-calling-identity-status-updated) | Caller identity status updated. |
| [`branded_calling.identity.action_required`](https://pozy.ai/docs/webhooks/events#branded-calling-identity-action-required) | Caller identity action required. |
| [`branded_calling.number.status_updated`](https://pozy.ai/docs/webhooks/events#branded-calling-number-status-updated) | Branded number status updated. |
