Lookup API FAQ
What is Bird Lookup?
Lookup answers questions about a recipient before you send to them. Give it a phone number and it tells you what the number is: the network serving it, the country, whether it has moved network, and what kind of line it is. Give it an email address and it tells you whether the address is worth sending to.
What can I look up?
Two things, one operation each. A phone number lookup returns the country, the network serving the number, the network that issued it, whether it has moved between the two, and the line type, plus any property you ask for. An email address lookup returns one verdict, a confidence score, and the flags behind it.
How much work is it to integrate?
Each lookup is one request and one answer. There is nothing to create, nothing to poll, and nothing to clean up afterwards. Typed methods ship in the Go, TypeScript, Python, and PHP SDKs, and bird lookup phone-number and bird lookup email do the same job from the CLI.
Can I run a lookup without writing code?
Yes. The Lookup page in the dashboard runs the same two operations one at a time, which is the fastest way to see what an answer looks like before you build on it.
What do I need before my first lookup?
An API key with the lookup scope, and an organization wallet that can cover the charge. Pricing is per query with no seat fee, so there is no plan to choose first.
When should I use Lookup instead of just sending?
Use it when you want to decide before you commit: gating a signup, screening a lead before you act on it, or routing a message differently depending on what the line turns out to be. You get an answer you can act on without sending anything first.
How is Lookup priced?
Per query. Every lookup is charged to your organization's wallet. A phone number lookup bills once for the base lookup, plus one charge for each property that comes back answered. An email address lookup bills once per answered address. There is no seat fee.
Where do I find the rates?
The Lookup pricing page lists the rate for the base lookup, for every property, and for an email address lookup. Rates vary by property, because each one comes from a different data source.
Do I pay for a property that comes back empty?
No. A property is billed only when it is delivered. One that could not be answered comes back with a status saying so and costs you nothing, and the base lookup is still served alongside it.
What happens to my bill when a lookup fails?
Nothing is billed. A malformed number, an address we refuse, and a data source that cannot be reached all cost nothing.
Am I billed for an address that turns out to be undeliverable?
Yes. Every answered address bills, undeliverable included. That is the answer you asked for, and it is the one that saves you a bounce.
Can a retry bill me twice?
Not if you send an Idempotency-Key. A repeat of the same request replays the stored answer instead of running a new lookup. The GET forms, which put the number or the address in the URL, cannot carry an idempotency key, so use POST for anything automated.
How many lookups can I run a minute?
The lookup rate limit starts at 10 requests a minute, counted per acting credential, so one busy key cannot starve another. Each lookup reaches an outside data source and charges your wallet for the answer, which is why it starts where the send limits start.
Is there a batch or bulk lookup?
Not today. Neither operation has a batch form, so checking a whole list is not what this is sized for. Ask us to raise the limit if that is what you need, rather than working around it.
What scope does a lookup need?
The lookup scope at write level. It has no read level: every lookup endpoint needs write, including fetching a result you have already paid for. Owners and admins hold it by default, and members do not.
Which errors can a lookup return?
Four that matter. E22000 when the number is not valid in international format, E22003 when the address is not a valid email address, E22001 when the organization's wallet cannot cover the lookup, and E22002 when Lookup is temporarily unavailable. None of them charge you.
Does a property that cannot be answered fail my request?
No. A failing property comes back as a status on its own block, with the base lookup served alongside it. Only the base lookup failing fails the request, and then it fails outright rather than returning a half-empty answer you would have to inspect to discover was empty.
What does a phone number lookup answer?
The base lookup answers the number's country, the network serving it today, the network that issued its range, whether it has ever moved network, and a coarse line type. It always runs, and if it cannot be answered the whole request fails rather than returning a half-empty answer.
How should I write the number?
Country calling code first, then the national number. The leading plus is optional and 00 works in its place, so +31612345678, 31612345678 and 0031612345678 are all the same number.
Why was my number rejected?
A number written for dialling inside one country, with no country code, returns E22000 rather than being guessed at. Prefixing a country code onto 0612345678 would name a real number somewhere else and bill you for looking that one up instead.
Which line types can it return?
mobile, fixed_line, voip, toll_free, premium_rate, satellite, pager, payphone, m2m, service, other, or unknown. unknown means the carrier platform holds no classification for the range, and other means it holds one with no equivalent here. Request the classification property for the allocated service at finer precision.
How do I tell whether a number has been ported?
network_info is the network serving the number today and original_network_info is the network that issued its range. The two differ once a number has been ported, and flags contains ported in that case. Request the porting property when you also need the date and the full record.
Why is country_code missing from my answer?
Because the number belongs to no single country, as a non-geographic range does. Fields with no value are omitted rather than returned as null, so every field present in the answer was resolved.
Does a lookup call or message the number?
No. A lookup never contacts the number itself. It reads carrier and number-intelligence data, and the presence and roaming properties query the network the number is registered on, so nothing rings and nothing arrives on the handset.
Which properties can I add to a phone number lookup?
Six, named in type. classification for the precise allocated service of the range, porting for when the number last moved network and every move on record, presence for whether it is live on the network right now, roaming for whether it is roaming and on which network, sim_swap for when its SIM last changed, and score for a credibility score from 0 to 100.
Are some properties slower than others?
Yes. classification, porting and score read stored data and return quickly. presence, roaming and sim_swap reach the live network, so they are slower and their coverage varies by operator. Expect unavailable or inconclusive for those three more often than for the stored ones.
What do the property statuses mean?
ok means the property was answered, its value is in the response, and it was billed. unavailable means no answer arrived, and it was not billed. inconclusive means an answer arrived but does not resolve the property, which is a real finding, and it was not billed either.
Can new statuses appear later?
Yes, status is an open vocabulary. Branch on ok and treat everything else as not answered, and your code stays correct however the vocabulary grows.
What do porting and classification add over the base answer?
porting gives you the date and the full history where the base lookup's ported flag only says whether a move ever happened. classification resolves line_type to the exact allocated service, from a different source with a wider vocabulary, and is reported separately so you can always tell the two apart.
Why did sim_swap return a range instead of a date?
Because the network would not release an exact figure. sim_swap returns min_days and max_days instead of last_swapped_at when only a recency band is known. porting does something similar: it sets last_ported_at_is_approximate when a registry records the period of a move but not the day.
Does porting.ported set to false mean the check failed?
No. It means the registry was consulted and holds no move for this number, which is a finding about the number rather than a gap in the answer. The status on the block is what tells you whether the check ran at all.
How should I read the score?
As one signal among several. It runs from 0 for low credibility to 100 for high, it is a composite, and you cannot derive it from the other properties. Weigh it against the rest of the answer instead of gating on it alone.
What does an email address lookup answer?
Whether the address will accept mail. One call returns a verdict in result, a delivery_confidence score, the flags that describe the kind of address, and a correction when the address reads like a misspelling.
What are the five verdicts?
valid means the address exists and accepts mail, so send. neutral means it could not be confirmed either way, usually because the receiving domain answers every recipient the same way. risky means it probably accepts mail but is likelier than most to bounce or complain. undeliverable means it does not accept mail. typo means the address looks misspelled.
Why is an address undeliverable?
reason says which of three things is wrong: invalid_syntax for a malformed address, invalid_domain when the domain does not accept mail at all, and invalid_recipient when the domain accepts mail but this mailbox does not exist.
What should I do with a typo verdict?
Offer did_you_mean to whoever typed the original rather than sending to it unasked. The correction is a guess, and the address they meant may be neither one.
How does delivery_confidence differ from result?
It runs from 0, certain not to be delivered, to 100, certain to be. The same score can sit under different verdicts for different reasons, so read it alongside result instead of in place of it. It is the field to lean on when you want one threshold across every verdict, including verdicts added later.
There is also a valid field. Is that the valid verdict?
No, and the difference matters. The valid field is narrower: it says whether the address is well-formed and its domain is set up to receive mail at all. It says nothing about the mailbox, so an address with a working domain and no such mailbox is true there and undeliverable in result.
What do the flags mean?
role means the address names a function rather than a person, such as support@ or info@, so replies and consent are ambiguous and complaints are likelier. disposable means a throwaway-address provider, so the address will typically stop existing. free_provider means a consumer mailbox provider such as Gmail or Outlook.com, which is a signal only when you expected a business address.
How should I write the address?
Send a bare address, exactly as you hold it. A display-name form, with a name in front and the address in angle brackets, is rejected rather than unwrapped, because unwrapping it would look up an address you did not send. The part before the at sign is passed through as written, and changing its case can change the delivery_confidence you get back.
Do I need Lookup to stop sending to addresses that already bounced?
No. Suppressions do that automatically and for free, for addresses that have already bounced or complained. Use Lookup for the address you have not sent to yet, at signup or before you act on a lead.
Read the capability in full
Each operation has its own page, with the response fields laid out.
Phone number lookupCountry, both carriers, the ported flag, the line type, and five properties.Email address lookupThe five verdicts, the flags, the confidence score, and the typo correction.PricingThe per-query rate for the base lookup and for each property that answers.The Lookup APIBoth operations, the property statuses, and how the billing works.