Bird Lookup

Check the recipient before you send to them.

One call says what a phone number is: the network serving it, the network that issued it, whether it has moved between the two, and what kind of line it is. One call says whether an email address will accept mail. Same key, same error envelope, same idempotency contract as every other Bird channel, because the same engineering team built them all.

lookup.ts
200
import { BirdClient } from "@messagebird/sdk";

const bird = new BirdClient({
  apiKey: process.env.BIRD_API_KEY!,
});

const answer = await bird.lookup.phoneNumber({
  phone_number: "+31612345678",
  type: ["porting", "score"],
});

console.log(answer.country_code, answer.line_type);
// → "NL" "mobile"
console.log(answer.network_info?.carrier_name, answer.flags);
// → "KPN" ["ported"]

// Only a block whose status is ok carries a value,
// and only that one is billed.
if (answer.score?.status === "ok") console.log(answer.score.value);
// → 84

5 minutes from npm install to first lookup

Look up a number or an address from the language you already use.

Typed methods in the Go, TypeScript, Python, and PHP SDKs, and bird lookup on the CLI. The dashboard runs the same two operations one at a time, which is the fastest way to see an answer before you write any code.

1
2
3
4
5
6
7
const answer = await bird.lookup.phoneNumber({
  phone_number: "+31612345678",
  type: ["classification", "score"],
});
console.log(answer.country_code, answer.line_type);
// Only a block whose status is ok carries a value, and only that one is billed.
if (answer.score?.status === "ok") console.log(answer.score.value);

What a lookup answers, and what each answer costs.

Named fields from real data sources, not a model guessing. Every one of them tells you whether it was answered, and you are billed only for the ones that were.

  1. 01

    Country and both networks

    The number's country, the network serving it today, and the network that issued its range. They differ when the number has been ported.

  2. 02

    Line-type detection

    Mobile, fixed line, VoIP, toll-free, premium rate, satellite, pager, payphone, M2M, service. Decide whether SMS is even possible before you send.

  3. 03

    The ported flag, free with the base answer

    Whether the number has ever moved network arrives with every lookup. Request the porting property when you also need the dates and the full record.

  4. 04

    Six properties on request

    Name classification, porting, presence, roaming, sim_swap, or score in type. The allocated service of the range, the porting record, whether the line is live, whether it is roaming, when its SIM last changed, and a 0-100 credibility score.

  5. 05

    A status on every property

    Each block reports ok, unavailable, or inconclusive. Only ok carries a value, so you never have to inspect a response to discover it is empty.

  6. 06

    You pay for answers, not attempts

    The base lookup bills once. A property bills only when it is delivered, and a lookup that fails bills nothing at all.

  7. 07

    One field to decide an email address on

    result is valid, neutral, risky, undeliverable, or typo, with reason naming why an undeliverable address cannot receive mail.

  8. 08

    A correction for a misspelled address

    did_you_mean carries the address a typo looks like a misspelling of. flags marks a role, disposable, or free-provider address, and delivery_confidence grades all of it from 0 to 100.

  9. 09

    A retry cannot bill twice

    Send an Idempotency-Key and a repeated request replays the answer you already paid for instead of buying a second one.

  10. 10

    Same auth, same error envelope

    One API key for Lookup, SMS, Email, WhatsApp, and Verify. One error registry across all of them, and a rate-limit budget of its own so a lookup never eats into your sending.

Why we build Lookup

Because you shouldn't learn a number is a landline by watching the SMS fail.

The base answer comes off the same carrier platform that routes Bird SMS and Voice, which is why asking it costs so little: we were already running the query to pick a route in real time. Lookup is that query as a first-class endpoint, so you can gate a signup, screen a lead, or route a message differently without sending anything first. Same auth, same error envelope, same idempotency contract as the rest of the platform.

lookup.ts
200
import { BirdClient } from "@messagebird/sdk";

const bird = new BirdClient({
  apiKey: process.env.BIRD_API_KEY!,
});

const answer = await bird.lookup.phoneNumber({
  phone_number: "+31612345678",
  type: ["porting", "score"],
});

console.log(answer.country_code, answer.line_type);
// → "NL" "mobile"
console.log(answer.network_info?.carrier_name, answer.flags);
// → "KPN" ["ported"]

// Only a block whose status is ok carries a value,
// and only that one is billed.
if (answer.score?.status === "ok") console.log(answer.score.value);
// → 84

Two operations, one for each kind of recipient.

Both are a single request and a single answer. There is nothing to create, nothing to poll, and nothing to clean up afterwards.

Phone number.

phone-number

Country, both networks, the ported flag, and the line type, plus any property you name in type.

Email address.

email

One verdict, a confidence score, the flags that explain a risky address, and a correction when it reads like a typo.

Pay for the answers you get.

Priced per query: one charge per lookup, plus one for each property that comes back answered. A property we cannot answer, and a lookup that fails, cost nothing. No seat fee.

Start with one channel.
Add the others when you're ready.

A test API key is yours immediately. Production unlocks when you add a payment method and verify a sender.

Using Claude Code, Cursor, or Codex? Copy a setup prompt and your agent installs the Bird CLI and skills for you. Pick yours:

Cursor