
If you need a quick way to check whether a US phone number has been reported as spam, SkipCalls exposes a free spam lookup API at https://spam.skipcalls.com.
It is intentionally simple: send a phone number, get JSON back, and decide what your app should do next. You can use it for a phone number spam check before an outbound dial, for spam caller detection inside a CRM, or as a lightweight spam prevention API in a contact-center workflow.
What the Spam Number API Does
The API checks a normalized US phone number against the SkipCalls spam database. The database is rebuilt from multiple spam-number sources and served from memory, so lookups are fast enough to run inline before showing a caller warning, cleaning a contact list, or deciding whether to block spam calls before they reach a person.
Good fits include:
- Showing a "possible spam" warning next to unknown inbound callers.
- Screening outbound lists before sales, reminders, or support callbacks.
- Adding a spam phone API integration to a CRM, dialer, support desk, or call-screening app.
- Running batch checks on uploaded contact lists before a campaign.
The API currently focuses on US numbers. It accepts common phone-number formats and normalizes them to 10 digits in the response.
Base URL
https://spam.skipcalls.com
No account is required for normal use.
Endpoint 1: Check a Single Phone Number
Use GET /check/:number when you want to look up one number in real time.
curl https://spam.skipcalls.com/check/2125551234
Example response when the number is in the spam database:
{
"number": "2125551234",
"is_spam": true,
"response_time_ms": 0.01,
"status_code": 180,
"status_description": "other"
}
Example response when the number is not found:
{
"number": "4155559876",
"is_spam": false,
"response_time_ms": 0.01
}
Use is_spam as the primary decision field. status_code and status_description are included only when the number is found in the database.
Endpoint 2: Batch Phone Number Spam Check
Use POST /check/batch when you need to check several numbers at once. A batch can include up to 100 numbers.
curl -X POST https://spam.skipcalls.com/check/batch \
-H "Content-Type: application/json" \
-d '{"numbers":["2125551234","4155559876"]}'
Example response:
{
"results": [
{
"number": "2125551234",
"is_spam": true,
"status_code": 180,
"status_description": "other"
},
{
"number": "4155559876",
"is_spam": false
}
],
"count": 2,
"response_time_ms": 0.08
}
Batch lookup is the better choice for contact-list cleanup, CRM imports, and any workflow where you already have a group of numbers. It reduces request overhead and makes the integration easier to reason about.
Endpoint 3: Database Statistics
Use GET /stats to inspect the current database size, update timestamp, status breakdown, and memory footprint.
curl https://spam.skipcalls.com/stats
Example fields:
{
"total_numbers": 2700387,
"last_updated": "2026-06-05T17:01:37.333Z",
"breakdown_by_status": [
{ "status_description": "scam", "count": 1278627 },
{ "status_description": "other", "count": 795891 }
],
"memory_usage_mb": 556.99
}
Use this endpoint for monitoring and status pages, not for per-call decisions.
Endpoint 4: Health Check
Use GET /health to verify that the API is available and has a database loaded.
curl https://spam.skipcalls.com/health
Example response:
{
"status": "ok",
"timestamp": "2026-06-05T17:55:14.884Z",
"numbers_loaded": 2700387,
"last_updated": "2026-06-05T17:01:37.333Z"
}
JavaScript Example
async function checkSpamNumber(phoneNumber) {
const response = await fetch(
`https://spam.skipcalls.com/check/${encodeURIComponent(phoneNumber)}`
);
if (!response.ok) {
throw new Error(`Spam lookup failed: ${response.status}`);
}
const result = await response.json();
return result.is_spam === true;
}
const isSpam = await checkSpamNumber("2125551234");
if (isSpam) {
console.log("Show a spam warning before connecting the call.");
}
Python Example
import requests
def check_spam_number(phone_number: str) -> bool:
response = requests.get(
f"https://spam.skipcalls.com/check/{phone_number}",
timeout=5,
)
response.raise_for_status()
return response.json().get("is_spam") is True
if check_spam_number("2125551234"):
print("Show a spam warning before connecting the call.")
Best Practices for Spam Caller Detection
Cache repeat lookups for a short period. Spam status does change, but the same number may appear many times in a day across your call logs, CRM, or dialer queue.
Use batch checks for imports and list cleaning. If you already have 20 or 100 numbers, POST /check/batch is cleaner than making one request per number.
Do not make spam lookup the only signal. A number missing from the database is not proof that the caller is safe; it only means the number is not currently known to this database.
Keep the user experience clear. "Possible spam" or "Reported spam number" is better than silently dropping calls unless your product has explicit blocking rules.
Run checks before outbound dialing. A phone number spam check can help teams avoid wasting time calling obvious scam, collector, advertising, or other reported spam numbers.
When to Use SkipCalls Instead of Building Your Own
Use the free spam lookup API when you need a simple number-level signal. It is a good fit when your product already has the call flow and only needs a spam number API decision point.
Use SkipCalls itself when you want the call handled end to end. SkipCalls can answer, screen, summarize, route, book appointments, and block spam calls before they interrupt the business owner. The API is the lookup layer; the AI receptionist is the full phone workflow.
Quick Reference
| Task | Endpoint |
|---|---|
| Check one number | GET /check/:number |
| Check up to 100 numbers | POST /check/batch |
| View database stats | GET /stats |
| Verify uptime | GET /health |
For most spam phone API integration work, start with GET /check/:number, switch to POST /check/batch for list cleanup, and cache results where repeated lookups are likely.