SMS short code lookup API
Bewary's short code API tells you which company sends texts from a US short code, such as 86006 for Bank of America, and whether the code is legitimate, shared by several senders or used for scams. Scam texts often name a real bank's code, so a real code mentioned inside a message is never proof on its own. A call costs 1 credit, a free key gets 1,000 credits a month, no card, and it answers in median 113 ms.
- Endpoint
- GET
https://api.bewary.app/v1/shortcode/{country}/{code} - Price
- 1 credit
- Free key
- 1,000 credits a month, no card
- Speed
- Median 113 ms, measured
- Returns
- verdict, p_scam, entities with typed facts, reason codes
- MCP tool
lookup_shortcode- Free tool
- Short code directory
Try it
Free from this page: 10 lookups a dayCall it
curl "https://api.bewary.app/v1/shortcode/US/86006" import requests
r = requests.get("https://api.bewary.app/v1/shortcode/US/86006", timeout=10)
result = r.json()
print(result["verdict"], result["p_scam"], result["reason_codes"]) const res = await fetch("https://api.bewary.app/v1/shortcode/US/86006")
const result = await res.json()
console.log(result.verdict, result.p_scam, result.reason_codes) Act on the result
Copy-paste code that turns the answer into a decision. It runs with or without BEWARY_API_KEY. TypeScript uses bewary.d.ts.
import os, requests
def short_code_sender(code):
key = os.environ["BEWARY_API_KEY"] # a free key: bewary.app/account
headers = {"Authorization": f"Bearer {key}"}
r = requests.get(f"https://api.bewary.app/v1/shortcode/US/{code}", headers=headers, timeout=10)
r.raise_for_status()
facts = r.json()["entities"][0]["facts"]
return facts["status"], (facts["operator"] or {}).get("name")
print(short_code_sender("86006")) # ('legitimate', 'Bank of America') import type { Envelope } from "./bewary"
export async function shortCodeSender(code: string) {
const key = process.env.BEWARY_API_KEY! // a free key: bewary.app/account
const headers: Record<string, string> = { Authorization: `Bearer ${key}` }
const res = await fetch(`https://api.bewary.app/v1/shortcode/US/${encodeURIComponent(code)}`,
{ headers, signal: AbortSignal.timeout(10_000) })
if (!res.ok) throw new Error(`Bewary ${res.status}`)
const e = (await res.json() as Envelope).entities[0]
if (e.type !== "shortcode") throw new Error("unexpected entity")
return { status: e.facts.status, sender: e.facts.operator?.name ?? null } // operator is null for shared codes
} Response
The fields you will use
entities[0].facts.status- legitimate, mixed (shared), scam or unknown.
entities[0].facts.operator- The company that sends from it, with its brand id.
verdict- safe for a legitimate code, scam for a scam code, unknown for a shared or unlisted code.
{ "schema_version": "1.7.0", "request_id": "req_01M69WHRF89N0KE4G2QYZ013GE", "checked_at": "2026-10-31T21:06:18Z", "engine": "bewary-engine/3.0.0", "models": { "calibration": "interim-band-v0" }, "input": { "kind": "lookup", "channel": "unknown", "language": null, "region": null }, "verdict": "safe", "p_scam": 0.0013, "risk_score": 0, "confidence": 1, "classification": null, "reason_codes": [ "SHORTCODE_LEGITIMATE" ], "entities": [ { "id": "e1", "type": "shortcode", "value": "86006", "normalized": "86006", "role": "mentioned", "verdict": "safe", "p_scam": 0.0013, "risk_score": 0, "reason_codes": [ "SHORTCODE_LEGITIMATE" ], "facts": { "code": "86006", "country": "US", "status": "legitimate", "operator": { "name": "Bank of America", "brand_id": "bankofamerica" }, "legit_uses": null, "reports_30d": null }, "related": [], "datasets": [ { "dataset": "shortcodes", "coverage": "US", "in_coverage": true }, { "dataset": "community_reports", "coverage": "WW", "in_coverage": true } ] } ], "signals": [ { "code": "SHORTCODE_LEGITIMATE", "entity": "e1", "severity": "info", "weight": 0, "source_class": "first_party", "p": null, "dataset": "shortcodes", "coverage": "US", "evidence": {} } ], "degraded": false, "degraded_reasons": [], "cached": false, "explanation": null} Real responses, captured from the live API on 2026-10-31. Every response has this shape: see Response format.
SMS short code facts
Every key is in every response, null when unknown. A key marked Coming stays null until its source ships, so you can code against it now.
| Key | Type | Meaning |
|---|---|---|
code | string or null | The short code. |
country | ISO code or null | The country it is registered in. |
status | legitimate | mixed | scam | unknown or null | mixed: a shared code used by several senders. |
operator | object or null | The company that sends from it, with its brand id. null when no single company does, which today is every shared and scam code in the directory. |
legit_usesComing | array or null | What the operator sends: otp, fraud_alert, account_alert, marketing, delivery and more. |
reports_30dComing | integer or null | Reports in 30 days. |
Parameters
| Name | Type | Description |
|---|---|---|
countrypath, required | string | ISO country code. US only for now. |
codepath, required | string | The 5 or 6 digit short code. |
Questions
How do I find out who sends texts from a short code?
GET /v1/shortcode/US/{code}. facts.operator names the company and facts.status says whether the code is legitimate, shared (mixed) or a scam code.
Which short codes are covered?
US codes in the directory at bewary.app/shortcodes, which grows every week. An unlisted code answers status unknown and verdict unknown, never safe.
What about shared short codes?
A code that several companies send from has status mixed and answers unknown: the code alone cannot tell you who sent a message. operator is null when no single company sends from it.
A message names my bank's real short code. Is it safe?
Not on its own. Scam texts copy real codes to look genuine. Look up the link or the number the text asks you to use: that is where a scam text gives itself away.
Used for
- Verifying the sender of a one-time code or a fraud alert.
- Messaging platforms labelling short-code senders.
- Support teams answering "is 86006 really my bank?"
Reason codes it can return
| Code | Meaning | Severity |
|---|---|---|
LISTED_BLOCKLIST | On scam blocklist | Critical |
SHORTCODE_LEGITIMATE | A short code a real company sends from | Info |
SHORTCODE_MIXED_USE | A shared short code used by several senders | Medium |
SHORTCODE_SCAM | A short code known for scam texts | High |
SHORTCODE_UNREGISTERED | A short code not in the directory | Low |
LISTED_CAUTION | On a broad threat list that also holds spam and malware hosts | Medium |
PLATFORM_TAKEDOWN | The hosting platform took it down | High |
PLATFORM_WARNING | The platform shows a phishing or malware warning in front of it | High |
Reserved codes are in the contract, not emitted yet. All reason codes
Updated · This page as Markdown · Changelog