Bird

Migrate from Twilio Lookup to Bird

Move the phone-number checks your application actually uses, then verify the next action: ask for a corrected number, offer verification or continue a customer task. Start with a number you control and an API key with the Lookup scope.
Use the Next.js lookup form or FastAPI lookup form to run the receiving application. Both preserve an attempt's request key and distinguish an unanswered score from zero.

Map the integration

Existing integrationBird migration action
Basic-auth credentialsUse a Bird API key on the server; the SDK selects its region from the key.
Number in the request URLSend phone_number in a POST body. Resolve national-format input before calling Bird.
Requested data packagesChoose the optional properties needed by your application; see the mapping below.
Line type and carrierRead line_type and identified networks, then update your application's enum checks.
Missing or failed packagePreserve the individual property status and an unanswered value.
Risk thresholdRecalibrate the decision for the particular signal; scores are not interchangeable.
Twilio's v2 request uses Fields to select packages and accepts national-format input with country context. Bird's phone-number operation takes an international number and a type array. A malformed number is an API error; a successful lookup is not proof that someone controls the number.
Map only the fields your application consumes:
  • Line type: Twilio's line-type vocabulary includes landline, fixedVoip and nonFixedVoip. Bird uses fixed_line and a single voip base category. Preserve an explicit unknown branch; a fixed-versus-non-fixed VoIP distinction needs a separate decision.
  • Carrier: read network_info for the current network and original_network_info for the number range's original network. Either may be absent. Read each network's carrier name, MCC and MNC only when supplied.
  • SIM swap: Twilio reports a date or a change within a period in its SIM Swap package. Request Bird sim_swap, require status: ok, then evaluate the returned date or recency bounds. A band that crosses your policy threshold cannot support an exact yes/no conclusion.
  • Risk: Twilio's SMS Pumping Risk Score rises with pumping risk. Bird's credibility score rises with credibility. They measure different things. Neither copying the threshold nor subtracting one score from 100 establishes equivalent protection.
  • Other packages: the phone-number request supports classification, porting, presence, roaming, SIM swap and score. Caller-name, identity-match, reassignment and call-forwarding dependencies need a separately verified replacement. Do not silently substitute presence or a credibility score for those answers.

Build and test the receiving path

This server-side example requests presence, SIM-swap and score observations. Review Lookup pricing before running it: the base lookup is billed, with additional charges for answered requested properties.
Install @messagebird/sdk and tsx. Set BIRD_API_KEY, BIRD_TEST_PHONE and LOOKUP_REQUEST_ID in your shell. Use one UUID as the request ID for this attempt and keep it with the unchanged phone number and property selection while recovering a failed response. Save as lookup.mts:
Exemple de code
import { BirdClient } from "@messagebird/sdk";

function required(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`Set ${name}`);
  return value;
}

const bird = new BirdClient({ apiKey: required("BIRD_API_KEY") });
const result = await bird.lookup.phoneNumber(
  {
    phone_number: required("BIRD_TEST_PHONE"),
    type: ["presence", "sim_swap", "score"],
  },
  { idempotencyKey: required("LOOKUP_REQUEST_ID") },
);

console.log(
  JSON.stringify(
    {
      line_type: result.line_type,
      presence_status: result.presence?.status ?? "missing",
      reachable: result.presence?.status === "ok" ? result.presence.reachable : null,
      score_status: result.score?.status ?? "missing",
      credibility: result.score?.status === "ok" ? result.score.value : null,
      sim_swap: result.sim_swap ?? { status: "missing" },
    },
    null,
    2,
  ),
);
Run npx tsx lookup.mts. The output keeps status beside the observation. A conclusive false or zero remains a value; an unanswered observation remains null. SIM-swap dates and bounds remain intact for your application's policy. See property interpretation before using them.
Test these cases in the complete form with controlled responses where a live number cannot reproduce the condition:
  1. A mobile, fixed-line and VoIP result choose the intended verification or channel path.
  2. Missing carrier data does not crash the page or select an invented carrier.
  3. An unanswered or unrecognized property status stays unknown; a conclusive zero score remains zero.
  4. A SIM-swap date, a bounded result and an unavailable result each follow the policy you defined.
  5. Invalid input produces a correction step. Authentication, balance and service failures remain operational errors.
  6. A lost response is retried with the original body and key under the idempotency rules. It does not trigger two customer actions.
The code reads observations; your application still owns verification, consent and the next business action. Follow Verify when the customer must demonstrate control of a destination.

Switch traffic and reconcile

Record the requested properties, observation time, provider and resulting application decision for an authorized test cohort. Compare unanswered-result rates by destination as well as successful requests. Recalibrate any risk thresholds before allowing the new result to control customer traffic.
Choose one provider's result to drive each customer task during the transition. Comparative lookups may incur two charges; prevent the comparison from sending two verification challenges. Keep the previous integration available until its outstanding work is reconciled.
For rollback, route new tasks back to the previous integration and preserve unresolved Bird attempts with their original keys. Retrying an old attempt replays an observation; deliberately requesting fresh data is a new lookup. Apply your retention policy to stored number data and avoid placing API keys or full provider responses in browser logs.

References and next steps

Ressources associées

Poursuivez avec la documentation, les guides et les exemples sur ce sujet. Les ressources sont en anglais.

Obtenir un guide d'implémentation