# Migrate from Vonage Number Insight to Bird

Identify whether your application uses Number Insight Basic, Standard or Advanced, then list the fields that influence its next action. Replace the result interpretation along with the HTTP call.

This guide covers Number Insight. Vonage also documents an [Identity Insights transition](https://developer.vonage.com/en/identity-insights/guides/number-insights-transition); an integration already using that API has a different request and response contract. Check the actual endpoint before applying a mapping.

## Map the integration

| Existing integration                  | Bird migration action                                                                   |
| ------------------------------------- | --------------------------------------------------------------------------------------- |
| Number and country input              | Resolve the customer's country context, then send an international `phone_number`.      |
| Basic, Standard or Advanced selection | Choose a base lookup plus the optional properties needed by the application.            |
| Current and original carrier          | Read the separately identified current and original networks.                           |
| Porting, reachability and roaming     | Preserve each property's status before interpreting its answer.                         |
| Asynchronous completion               | Consume the Bird HTTP result in your application worker; retain your own task identity. |
| Caller-name data                      | Keep a separately verified source where the application depends on caller identity.     |

Use the [Number Insight reference](https://developer.vonage.com/en/api/number-insight) to inventory fields, then check Bird's [phone-number reference](/docs/api/reference/create-phone-number-lookup):

- Map the normalized international number to `phone_number`. Bird does not guess the country for a national-format number.
- Map `current_carrier` and `original_carrier` to `network_info` and `original_network_info`. Read carrier names and MCC/MNC when present. Store network codes as strings so leading zeros survive; an absent network is not an empty carrier match.
- Replace the old network-type enum checks with Bird's `line_type` vocabulary. A number's type or valid format alone does not prove present reachability or ownership.
- Vonage `ported` includes assumed and unknown states. Request Bird `porting` for a conclusive `ported` value and any supplied history. Require `status: ok`; retain approximate dates as approximate.
- Vonage `reachable` is a multi-state field. Bird `presence` separates `status` from the Boolean `reachable`. An unanswered property cannot be mapped to `false`.
- Vonage `roaming` can be an object or an unknown result. Bird `roaming` has its own status and, when answered, `is_roaming`. Read visited-network codes only when supplied.

The [CNAM guide](https://developer.vonage.com/en/number-insight/guides/cnam) describes caller-name fields. The Bird phone-number lookup operation has no CNAM request property. Keep a caller-name dependency separate from phone validation; do not fill it with a carrier name or infer identity from a reachability check.

## Build and test the receiving path

Vonage's [asynchronous example](https://developer.vonage.com/en/use-cases/number-insight-async-tutorial) first acknowledges a request, then posts the lookup result to a callback. Bird returns the lookup result in the HTTP response. If your application already queues these tasks, let its worker call Bird, store the result and complete the original task. Do not wait for a Number Insight callback on the Bird path.

Create a key with the Lookup scope. Install `messagebird-sdk`, then set `BIRD_API_KEY`, `BIRD_TEST_PHONE` and `LOOKUP_REQUEST_ID`. The request ID is one UUID retained with this attempt's unchanged number and properties. The SDK selects the API region from the key. This example performs a billed lookup; review [pricing](/products/lookup/pricing) and use a number you control.

Save as `lookup.py`:

```python
import json
import os

from bird import Bird

with Bird(api_key=os.environ["BIRD_API_KEY"]) as client:
    result = client.lookup.phone_number(
        phone_number=os.environ["BIRD_TEST_PHONE"],
        type=["porting", "presence", "roaming"],
        options={"idempotency_key": os.environ["LOOKUP_REQUEST_ID"]},
    )

print(json.dumps({
    "line_type": result.line_type,
    "porting_status": result.porting.status if result.porting else "missing",
    "ported": result.porting.ported
    if result.porting and result.porting.status == "ok" else None,
    "presence_status": result.presence.status if result.presence else "missing",
    "reachable": result.presence.reachable
    if result.presence and result.presence.status == "ok" else None,
    "roaming_status": result.roaming.status if result.roaming else "missing",
    "is_roaming": result.roaming.is_roaming
    if result.roaming and result.roaming.status == "ok" else None,
}, indent=2))
```

Run `python lookup.py`. A conclusive `false` remains false; an unanswered result prints `null` with its status. This script reads the observations and does not send a message or verification challenge. Build the customer-facing path with the [FastAPI form](/docs/get-started/quickstarts/python/fastapi/lookup) or [Next.js form](/docs/get-started/quickstarts/typescript/next-js/lookup).

Test the application with these cases before changing traffic:

1. A national-format input requires correction or explicit country normalization before the billed request.
2. A ported number preserves the distinction between its current and original network.
3. Conclusive false, unavailable, inconclusive and unfamiliar statuses remain different outcomes.
4. An absent carrier, missing roaming network or approximate porting date does not become invented detail.
5. An operational error remains a failed lookup task, not a rejected customer or an unreachable number.
6. A lost response retries with the same body and key under the [idempotency rules](/docs/guides/idempotency).
7. A late callback from an older Vonage task cannot overwrite the newer task's result or trigger a second customer action.

## Switch traffic and reconcile

Keep existing callbacks available for Number Insight requests already in flight. Store the provider and provider request ID beside your own application task ID so the two integrations cannot finish each other's work. A provider request ID is a correlation value; it does not replace a Bird idempotency key.

Route a controlled cohort to the Bird worker. Compare the application decision, response time, unanswered properties and billed property selection for the destinations you actually serve. Treat live observations as time-specific, so different query times can yield different answers.

Move new tasks only after the fallback behavior is acceptable. If you roll back, change routing for new work and reconcile existing attempts before repeating them. Keep one owner for the resulting verification or customer action. A successful lookup does not demonstrate possession; use [Verify](/verification-api) when that is required.

## References and next steps

- [FastAPI application](/docs/get-started/quickstarts/python/fastapi/lookup) and [Next.js application](/docs/get-started/quickstarts/typescript/next-js/lookup)
- [Phone-number fields and property statuses](/docs/guides/lookup/phone-numbers)
- [Lookup troubleshooting](/docs/guides/lookup/troubleshooting)
- [Compare Bird and Vonage Number Insight](/products/lookup/compare/bird-vs-vonage)
- [All migration guides](/docs/guides/lookup/migrate) and [Lookup resources](/lookup/resources)
- [Pricing](/products/lookup/pricing), [start now](/dashboard/signup?returnTo=%2Fdashboard%2Fw%2Flookup) or [talk to sales](/demo?product=lookup)

## Related resources

- [Phone number lookup: check a number before you send](/learn/lookup/phone-number-lookup-check-a-number-before-you-send) (video)
- [Lookup](/lookup) (product)
- [Lookup overview](/docs/guides/lookup/overview) (docs)

[Get an implementation brief](/learn/workspace?topic=lookup)
