# Why your Vapi calls show Spam Likely, and how to check

**If your Vapi assistant's outbound calls mostly end as `customer-did-not-answer`, or fail to connect, your number may be labeled or blocked by the carriers.** Vapi's logs can't show a label. A check can: your Vapi number calls our test lines, and real phones on AT&T, Verizon and T-Mobile report the label, the caller name and a screenshot, about 5 seconds after the call rings.

*Platform details checked October 2026. Spam I Am isn't affiliated with Vapi.*

## What it looks like in Vapi

Every Vapi call ends with an `endedReason`, shown in the call logs and on the Call object. Vapi has **no spam-specific ended reason**. Spam shows up indirectly:

- **Labeled calls** ring normally and usually end as `customer-did-not-answer`, or as short calls ending in `customer-ended-call`. Nothing in the log says "spam."
- **Blocked calls** never ring. Depending on your telephony, they end as `twilio-failed-to-connect-call`, `call.in-progress.error-sip-outbound-call-failed-to-connect`, or a SIP-coded reason such as `call.in-progress.error-providerfault-outbound-sip-403-forbidden`. Vapi notes it doesn't have a code-specific reason for every SIP response.

Vapi's SIP troubleshooting guide lists 603 among destination-side responses. Since March 25, 2026, US carriers must use **SIP 603+ ("Network Blocked")** for analytics-based blocking, which older systems reported as 608. [What 603+ and 608 mean](/guides/sip-603-plus-608-network-blocked)

So if your answer rate drops but your error rate doesn't, look at labels first.

## Why Vapi numbers get flagged

Vapi uses imported numbers from Twilio, Vonage, Telnyx and others for outbound calls. Free Vapi numbers can't make outbound calls. That means reputation sits with the number and your calling pattern, not with Vapi.

- **High volume from one number.** Batch calls and campaigns can push hundreds of calls through a single `phoneNumberId`.
- **Short calls and low answer rates.** Carrier analytics treat these as robocall signals.
- **Dead air.** A pause before the assistant speaks makes people hang up fast, which hurts the number.
- **New or recycled numbers** with no history, or someone else's.
- **Missing STIR/SHAKEN, CNAM or analytics registration.** Vapi's outbound guide covers all three.
- **Calls people didn't expect**, which lead to reports and blocks.

[Why numbers get flagged](/guides/why-number-shows-spam-likely)

## Place the test call from Vapi

The check call must come **from the number you're testing**. We never spoof numbers, so Vapi places it.

Create a small test assistant in the dashboard. Give it a one-line first message, voicemail detection set to hang up, and a short maximum duration. Our phone rings for a few seconds, then sends the call to voicemail, so the call only needs to last a moment.

Then call each test line with the `/call` endpoint:

```bash
curl -X POST https://api.vapi.ai/call \
  -H "Authorization: Bearer $VAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "assistantId": "TEST_ASSISTANT_ID",
    "phoneNumberId": "PHONE_NUMBER_ID",
    "customer": { "number": "+14695550123" }
  }'
```

`phoneNumberId` is the imported number you want to check. `customer.number` is the test line's `dial` value. Don't use the `customers` batch field here: place the calls one at a time.

## Run the check with Spam I Am

Start a check. The first check on any number is free, with no signup or key.

```bash
curl -X POST https://ismynumberspam.com/v1/checks \
  -H "Content-Type: application/json" \
  -d '{"number": "2145550100"}'
```

You get an `id`, a `token` and one `dial` number per carrier. Call them within 2 minutes for one carrier, plus 1 minute for each extra carrier.

Here's the whole flow in Node:

```js
const SIA = "https://ismynumberspam.com/v1";
const NUMBER = "2145550100";               // the Vapi number you're checking
const key = process.env.SIA_API_KEY;        // optional for the first check
const h = { "Content-Type": "application/json", ...(key && { Authorization: `Bearer ${key}` }) };
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

const check = await (await fetch(`${SIA}/checks`, {
  method: "POST", headers: h, body: JSON.stringify({ number: NUMBER }),
})).json();
const q = key ? "" : `?token=${check.token}`;
const getCheck = async () => (await fetch(`${SIA}/checks/${check.id}${q}`, { headers: h })).json();

for (const line of check.calls) {
  await fetch("https://api.vapi.ai/call", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.VAPI_API_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({
      assistantId: process.env.TEST_ASSISTANT_ID,
      phoneNumberId: process.env.PHONE_NUMBER_ID,
      customer: { number: line.dial },
    }),
  });
  // wait for this carrier's result before dialing the next line
  while ((await getCheck()).calls.find((c) => c.carrier === line.carrier).status === "waiting") {
    await sleep(5000);
  }
}

for (const c of (await getCheck()).calls) {
  console.log(c.carrier, c.status, c.label, c.caller_name, c.screenshot_url);
}
```

These examples are a starting point. Check field names against Vapi's current docs before you rely on them.

A `complete` carrier has `flagged`, `label`, `caller_name` and a `screenshot_url`. An `incomplete` carrier with `reason: "no_call"` got no call in time. If Vapi shows the call was placed, the carrier may have blocked it. That's more urgent than a label. Incomplete carriers are free.

You can also pass `webhook_url` when you start the check to get the result POSTed to you, signed with a `Spamiam-Signature` header.

### Use MCP

Vapi assistants can load tools from an MCP server. Add a tool of type `mcp` that points at our server:

```json
{
  "type": "mcp",
  "function": { "name": "spamIAm" },
  "server": {
    "url": "https://ismynumberspam.com/mcp",
    "headers": { "Authorization": "Bearer sia_..." }
  }
}
```

Vapi imports every tool the server exposes, so use this on an internal ops assistant, not a customer-facing one.

For agent builders, connect both MCP servers to your coding agent. Vapi's server has `create_call`; ours has `start_check` and `get_check`.

```bash
claude mcp add --transport http spam-i-am https://ismynumberspam.com/mcp
claude mcp add --transport http vapi https://mcp.vapi.ai/mcp \
  --header "Authorization: Bearer $VAPI_API_KEY"
```

Then ask your agent to start a check, call each test line with `create_call`, and report each carrier.

## Pre-campaign checklist

- **Check every imported number** before you attach it to a campaign.
- **Check before each campaign.** All three carriers cost $0.40 per number.
- **Re-check after volume spikes**, and whenever `customer-did-not-answer` climbs.
- **Check active numbers on a schedule.** Weekly is a good default for numbers in daily use.
- **Track results per `phoneNumberId`.** Vapi's number-warming guide recommends reporting per source number. Add the check result to that report.
- **One check per number per hour.**

## If it's flagged

Pause outbound calls from that number. Then:

1. **Fix the cause.** Lower volume, call people who expect you, and cut latency at the start of the call.
2. **Register with your telephony provider.** Vapi has no paid spam add-on of its own. Its outbound guide points to your provider: STIR/SHAKEN through Twilio Trust Hub (Vapi says 5 to 7 business days), CNAM (3 to 5 business days), and Twilio Voice Integrity, which registers Twilio numbers with the carriers' analytics engines.
3. **Register with the Free Caller Registry** at [freecallerregistry.com](https://freecallerregistry.com), which reaches Hiya, First Orion and TNS.
4. **Request a review** where you're flagged: [AT&T](/guides/remove-spam-label-att) · [Verizon](/guides/remove-spam-label-verizon) · [T-Mobile](/guides/remove-scam-likely-tmobile)
5. **Rest and re-warm the number.** Vapi's number-warming guide recommends small recurring batches of real conversations with people who expect the call, and pausing a number when its labels get worse. Swapping in fresh numbers to dodge a label doesn't fix the cause.
6. **Consider a reputation-management provider** for large fleets. They handle registrations and reviews, but can't guarantee removal.

Vapi notes caller ID setup can take 2 to 4 weeks to propagate. Re-check every few days. We only check. We don't remove labels.

## FAQ

### Is there a Vapi ended reason for spam?
No. Labeled calls look like normal unanswered calls. Blocked calls appear as connection failures or SIP errors.

### Can I check a free Vapi number?
Not with Vapi. Free Vapi numbers can't make outbound calls, and the check call must come from the number.

### Will the test call cost anything on Vapi?
Yes, a few seconds of a normal outbound call, billed by Vapi and your telephony provider.

### Does one clean carrier mean I'm fine?
No. AT&T, Verizon and T-Mobile each decide separately. Check all three.

### What does a check cost?
First check on a number: free. Then $0.25 for one carrier or $0.40 for two or three.

## Sources

- [Vapi: Outbound calling and trusted caller ID](https://docs.vapi.ai/calls/outbound-calling)
- [Vapi: Call ended reasons](https://docs.vapi.ai/calls/call-ended-reason)
- [Vapi: Troubleshoot SIP response codes](https://docs.vapi.ai/advanced/sip/troubleshoot-sip-response-codes)
- [Vapi: Warm outbound numbers](https://docs.vapi.ai/outbound-campaigns/number-warming)
- [Vapi: MCP tools](https://docs.vapi.ai/tools/mcp)
- [Vapi: MCP server](https://docs.vapi.ai/sdk/mcp-server)
- [Spam I Am API docs](/docs) · [MCP server](/docs/mcp)
