Skip to content

2026-09-24

Phone intelligence round four, from an SMS policy to Poland's and Italy's number blocks

The phone answer grows to 49 fields: an SMS policy's ok_to_send, signals from your own traffic, carrier codes and brands, pooled US numbers read from their own thousands-block, the local time, US complaint counts, two SMS-receiving lists synced daily, Polish and Italian number blocks, classified SMS outcomes, deduplicated bulk runs and monitors that flag changes.

  • 49 fields. POST /api/v1/phone, the batch, the browser endpoint, monitors and the MCP verify-phone tool now answer sixteen more fields after roaming: carrier_code, carrier_brand, block_pooled, block_assigned_at, region_level, local_time, utc_offsets, in_call_window, did_you_mean, range_seen_by_you, client_velocity, destination_new_for_you, complaints_90d, complaints_last_at, ok_to_send and blocked_by. The published weights gain five signals: range_burst 40, numbers_per_client 30, disposable_range 30, international_network 30 and reported_unwanted_calls 20. The full guide is at /docs/phone-intelligence.
  • An SMS policy decides ok_to_send. Every phone answer ends with ok_to_send and blocked_by from your account's SMS policy: the countries you send to or never send to, the line types you refuse, the signals that block, a ceiling on the score, whether a number your suppression list holds as opted out is blocked (block_opted_out) and, if you want one, a live check that reached the handset. Set it with GET, PUT and DELETE /api/v1/phone/policy or the SMS policy tab on the phone page. The defaults block fictional, disposable, reported_abuse, reported_abuse_widely and premium_rate, any score over 60 and a number your suppression list holds as opted out, and send to every country and line type; blocked_by names the rule that decided, in a fixed order that starts with invalid. It is a fraud and deliverability decision, not consent and not a do-not-call scrub, and a country list is a business choice about where you send, not a verdict on a country. The guide Gate SMS verification codes with the SMS policy walks through a signup flow.
  • Signals from your own traffic. range_seen_by_you counts the distinct numbers your account looked up in the same 1,000-number range in the last hour, and five or more add range_burst (+40). client_velocity does the same for one client address: send client_ip on POST /api/v1/phone, which is counted and never looked up or billed, and a browser lookup counts the visitor's address on its own; five or more add numbers_per_client (+30), unless Spaw's own IP data places the address on a mobile carrier or a corporate proxy, where many people share one. destination_new_for_you says whether the country is new for your account in the last 30 days. Only single and browser lookups are counted, a browser answer carries the three fields null, and no other account's lookups are ever read. The account owner is emailed about range bursts, destination spikes and enumeration runs, and the Usage page shows the last seven days of phone lookups by country. destination_new_for_you and the spike alert start once a week of the account's own lookups has been counted, and until 14 days have been counted a spike is measured against the days counted so far; the enumeration alert watches from the first counted hour.
  • Who holds the block. carrier_code is the regulator's code for the block holder: the NANPA or CNAC operating company number, ARCEP's operator code, UKE's operator ID. carrier_brand names the network behind a legal name — AT&T for New Cingular Wireless PCS — from a bundled, versioned map cited as carrier-brands in sources. block_pooled marks North American codes split into thousands-blocks that other carriers may hold, 71.8% of the assigned codes in NANPA's file of 24 September 2026. In the United States the lookup reads NANPA's daily thousands-block report too, so in a pooled code carrier, carrier_code, carrier_brand, a settled line_type and is_virtual describe the holder of the number's own block of a thousand, and a block the pool holds free answers unassigned_block; in Canada, and for a block the report does not settle, they describe the code holder. block_assigned_at is the date the regulator assigned the code or range, from NANPA, CNAC and ARCEP, or in a pooled US code the date NANPA assigned the number's own block; it is never the code's date for a pooled code. GET /api/v1/phone/block adds each holder's brand, a brand breakdown, the pooled count and the span of assignment dates, and now answers Guernsey, Jersey and the Isle of Man from the UK table.
  • Poland and Italy. Phone lookups read UKE's numbering tables for Poland and MIMIT's assigned-numbering workbook for Italy, synced weekly: the operator behind Polish and Italian fixed and mobile blocks, a Polish number in the space the regulator holds in reserve answered unassigned_block from that row itself, and mobile ranges assigned to messaging platforms flagged is_virtual. Neither table lists every block, so a number missing from one is never called unassigned. The footer credits both, UKE with its retrieval date on the status page.
  • SMS-receiving numbers, kept as they age. Two open lists of the numbers SMS-receiving websites publish are merged and synced daily now. A listed number scores disposable (70) for a year after it was last seen; one that leaves them is kept at its last-seen date for two years and scores disposable for 90 days after it was last seen, then disposable_stale (40), instead of vanishing. disposable_range (+30) flags a number that is not listed itself in a 1,000-number range holding ten or more listings that still score disposable (still listed and seen within the year, or dropped and seen within 90 days); GET /api/v1/phone/block reports the same count under disposable, and +1 202 555 0113 is its test number, the eighth.
  • Complaints about callers. For North American numbers, complaints_90d and complaints_last_at count the consumer complaints in the Federal Trade Commission's published reported-calls data that name the number as the caller over 90 days, and reported_unwanted_calls (+20) fires at three or more complaints on at least two days. The reports are unverified and caller ID is often spoofed: this is context about a caller, not proof of wrongdoing, and not a do-not-call scrub.
  • The clock and a typo check. region_level says how specific region is: locality, area or country. local_time gives the time at the number now where its time zones agree, utc_offsets their current offsets, and in_call_window answers when you send call_window ("09:00-20:00" in the number's local time) on POST /api/v1/phone or /phone/batch — clock arithmetic, not compliance advice. On an invalid answer to a number sent with a country, did_you_mean suggests the one valid reading of what was typed, such as a missing + or a foreign international prefix left in; it is never applied, and the answer stays free. A reading in a range reserved for fiction is offered even where the regulator's table lists its block as protected, as the lookup answers such a number valid. international_network (+30) scores the international-network and satellite codes +870, +881, +882 and +883, on top of voip for the last two.
  • SMS outcomes that say what failed. Delivery receipts from the SMS providers whose webhooks Spaw reads are classified by the provider's error code, and POST /api/v1/phone/feedback takes an optional failure_class: permanent, transient, not_sms_capable or sender_side. Only failures about the number count against it: one permanent failure suppresses it at once, a transient or unclassified one after two, and a carrier filter, an unregistered campaign or a sender limit is recorded without scoring your recipient. GET /api/v1/phone/feedback/summary splits failures by class. Two more outcomes: verified (the recipient entered the code) counts as a delivery, and the summary's verified_share reads as your code conversion, overall and per block; opted_out never scores, keeps the number on your suppression list with reason opted_out until you remove it, and a single lookup reports it as meta.opted_out: true and, under the default SMS policy (block_opted_out, on by default; an OTP sender may switch it off), answers ok_to_send: false with blocked_by: "opted_out". Honouring an opt-out stays your obligation. Every feedback endpoint, for all four products, refuses an occurred_at more than five minutes in the future.
  • Suppression entries stay until you say. A valid lookup now clears only an entry an unassigned block added. An import, an opt-out, an abuse report, or an entry your own failure reports added stays — including when somebody types the number into your public form — until you remove it or, for a failure report, a later delivery or verification clears it.
  • Bulk runs. Bulk phone runs mark every repeated number (is_duplicate, duplicate_of_row), add up a finished run in a summary (verdicts, reasons, line types, the top countries and carriers, signals, suppressed rows, what the live check found, and the rows your SMS policy held back), and download as deduped, mobile, ok or blocked as well as by validity and risk. The result file carries every new field a run fills, which leaves out the three own-traffic fields and in_call_window.
  • Monitors. Phone monitors save each number once, in E.164, read against the monitor's country where it has no calling code: two spellings of one number are one entry, counted and billed once, the 500-number limit counts distinct numbers, and an entry that does not parse is kept as typed and answers invalid. Existing monitors were converted in place and keep their baselines, and results on GET /api/v1/phone/monitors/{id} is keyed by E.164. A monitor now flags numbers that still answer but changed — listed by an SMS-receiving website, reported for abuse by three or more accounts, risen to high risk, a new line type, and with the live check ported or served by another network — in their own email, in the webhook's flags and on the monitor itself. A line type is compared only with one read from the same basis, so a type now read from another block holder, or from the number's own thousands-block, sets a new baseline rather than a flag. A number on your suppression list answers suppressed, which never counts as decay. Phone monitors stay weekly or monthly: most regulator tables refresh weekly (NANPA's and the SMS-receiving lists daily), a weekly run already catches a number that stopped being valid or started being listed within days, and with the live check a daily run would pay for the network check seven times a week.
  • Fixes. Phone inputs accept a full-width plus, a 00 international prefix and up to 64 characters everywhere. Ofcom's drama ranges answer valid and fictional, including 07700 900xxx, 01632 960xxx and 0115 496 0xxx, and including where Ofcom's own table lists the drama block as protected. The Northern Ireland drama range is 028 9649 6xxx: real Belfast numbers on 028 9018 0xxx no longer read as fictional. timezones names the zones of the number's own country: a Jamaican mobile answers America/Jamaica instead of every zone of +1, and a Lithuanian or Moroccan number its own zone instead of a neighbour's. A fictional number is never sent to the live check. A repeated live check is free while the network's day-long answer is held; after that the repeat asks the network again and bills the premium, reserved first and refused with 402 when the balance cannot cover it, and resuming a live-check bulk run more than a day after it stopped does the same for the rows it had answered. The base credit is charged once per number every seven days whether or not a lookup asked for the live check: a check after a plain lookup of the same number costs only the check, and a plain lookup after a check costs nothing. The hlr-live-status source is dated when the network answered. UK 084 and 087 numbers answer shared_cost (+20) instead of premium_rate (+60), as Ofcom's numbering plan classes them as service numbers with a capped charge, so the default SMS policy, which blocks premium_rate, no longer blocks them; 0871 to 0873 still fall under Ofcom's premium-rate-services rules, so add shared_cost to blocked_line_types to keep refusing them. Erasing a phone number also drops the shared live-check answer, its FTC complaints and any listing the SMS-receiving sites no longer publish.
  • Clients. The Python, Node and PHP SDKs (0.5.0, unreleased) carry the new fields and the SMS policy calls, and their phone lookup takes client_ip and call_window. The Zapier, Make, n8n and Google Sheets connectors return the new fields, with call window and client IP inputs where a step can use them. The footer credits UKE, MIMIT, the FTC and the second SMS-receiving list.

markdown version: /changelog/2026-09-24-phone-intelligence-round-four.md · atom feed: /changelog.atom

All releases