Skip to content

Commit f5831af

Browse files
sahilsuman933cursoragentsahil
authored
Add docs for spam call rejection with Server URL webhook (#616)
Co-authored-by: Cursor Agent <[email protected]> Co-authored-by: sahil <[email protected]>
1 parent 6a73f37 commit f5831af

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

fern/docs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ navigation:
432432
path: server-url/setting-server-urls.mdx
433433
- page: Server events
434434
path: server-url/events.mdx
435+
- page: Spam call rejection
436+
path: server-url/spam-call-rejection.mdx
435437
- page: Developing locally
436438
path: server-url/developing-locally.mdx
437439
- page: Server authentication
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
title: Spam call rejection
3+
subtitle: Screen inbound calls and reject known spam using your Server URL
4+
slug: server-url/spam-call-rejection
5+
---
6+
7+
Use your Server URL to filter inbound calls before they reach your assistant. When an inbound call arrives, Vapi can ask your server which assistant to use via an `assistant-request`. In that moment, you can check the caller's phone number against your spam list:
8+
9+
- If the number is flagged as spam: return an error message to be spoken to the caller and end the call.
10+
- If the number is allowed: return a transient assistant configuration to proceed with the conversation.
11+
12+
<Info>
13+
Learn more about the request/response shapes on the <a href="/server-url/events">Server events</a> page.
14+
</Info>
15+
16+
## How it works
17+
18+
1. Configure a Server URL on the phone number, assistant, or organization.
19+
2. On inbound calls without a fixed `assistantId` (or if you prefer to decide dynamically), Vapi sends your server an `assistant-request` webhook.
20+
3. Your server validates the calling number and responds with either an `error` or an `assistant` object.
21+
22+
<Note>
23+
Your server must respond within ~7.5 seconds or the call may fail.
24+
</Note>
25+
26+
## Example implementation
27+
28+
Below is a simple example using Node.js/Express. It checks the inbound caller (E.164) against a local spam list, then either rejects with an `error` or returns a transient assistant:
29+
30+
```javascript
31+
import express from "express";
32+
33+
const app = express();
34+
app.use(express.json());
35+
36+
// Replace with your own data store or third‑party spam reputation API
37+
const spamNumbers = new Set(["+11234567890", "+15558675309"]);
38+
39+
app.post("/webhooks/vapi", async (req, res) => {
40+
const messageType = req.body?.message?.type;
41+
if (messageType !== "assistant-request") {
42+
return res.sendStatus(204);
43+
}
44+
45+
const incomingNumber = req.body?.call?.from?.phoneNumber;
46+
47+
if (incomingNumber && spamNumbers.has(incomingNumber)) {
48+
// Reject spam callers with a spoken error message
49+
return res.json({
50+
error: "Sorry, your number is blocked due to spam reports. If this is a mistake, please contact support."
51+
});
52+
}
53+
54+
// Allow the call: return a transient assistant configuration
55+
return res.json({
56+
assistant: {
57+
name: "Inbound Receptionist",
58+
firstMessage: "Hi there! How can I help you today?",
59+
model: {
60+
provider: "openai",
61+
model: "gpt-4o",
62+
messages: [
63+
{
64+
role: "system",
65+
content: "You are a helpful receptionist. Answer succinctly and route the caller if needed."
66+
}
67+
]
68+
},
69+
voice: {
70+
provider: "11labs",
71+
voiceId: "shimmer"
72+
}
73+
}
74+
});
75+
});
76+
77+
app.listen(3000, () => console.log("Server listening on port 3000"));
78+
```
79+
80+
## Response examples
81+
82+
- Reject with a spoken error message:
83+
84+
```json
85+
{ "error": "Sorry, your number is blocked due to spam reports." }
86+
```
87+
88+
- Proceed with a transient assistant configuration:
89+
90+
```json
91+
{
92+
"assistant": {
93+
"firstMessage": "Hey there! How can I help you today?",
94+
"model": {
95+
"provider": "openai",
96+
"model": "gpt-4o",
97+
"messages": [
98+
{ "role": "system", "content": "You are a friendly inbound assistant." }
99+
]
100+
},
101+
"voice": { "provider": "11labs", "voiceId": "shimmer" }
102+
}
103+
}
104+
```
105+
106+
## Tips
107+
108+
- Keep your spam list in a database or use a reputation API for accuracy.
109+
- If you prefer to use a saved assistant, return `{ "assistantId": "asst_..." }` instead of an inline `assistant`.
110+
- For local testing, see <a href="/server-url/developing-locally">Developing locally</a>.

0 commit comments

Comments
 (0)