Testing

This guide covers how to test your AgentPhone integration during development, including local webhook testing and mock payloads.

Testing webhooks locally

To receive webhooks during development, you need to expose your local server to the internet. We recommend ngrok.

Using ngrok

1

Install ngrok

Download from ngrok.com, or install via Homebrew:

brew install ngrok
2

Start your local server

python app.py # or node server.js
3

Expose your local port

In a separate terminal:

ngrok http 3000

Copy the HTTPS URL (e.g., https://abc123.ngrok.io).

4

Register the URL as your webhook

curl -X POST "https://api.agentphone.ai/v1/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://abc123.ngrok.io/webhook"}'
5

Send a test webhook

curl -X POST "https://api.agentphone.ai/v1/webhooks/test" \
-H "Authorization: Bearer YOUR_API_KEY"

Using localtunnel

npm install -g localtunnel
lt --port 3000

Use the provided URL as your webhook URL.

Free ngrok accounts have session limits. The tunnel will disconnect and you’ll need to restart ngrok and update your webhook URL. For persistent tunnels, consider a paid ngrok plan or deploying to a cloud service.

Test webhook endpoint

Use the test endpoint to verify your webhook handler is working correctly. This sends a sample agent.message payload to your configured URL:

curl -X POST "https://api.agentphone.ai/v1/webhooks/test" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"success": true,
"httpStatus": 200,
"errorMessage": null
}

You can also test per-agent webhooks:

curl -X POST "https://api.agentphone.ai/v1/agents/agt_abc123/webhook/test" \
-H "Authorization: Bearer YOUR_API_KEY"

Mock webhook payloads

Use these sample payloads to test your webhook handler locally with curl or in your test suite.

SMS payload

{
"event": "agent.message",
"channel": "sms",
"timestamp": "2025-12-03T10:05:00Z",
"agentId": "agent_123",
"data": {
"conversationId": "conv_test456",
"numberId": "num_abc",
"from": "+14155551234",
"to": "+18571234567",
"message": "Test message",
"direction": "inbound",
"receivedAt": "2025-12-03T10:05:00Z"
},
"conversationState": { "testMode": true },
"recentHistory": [
{ "content": "Hello", "direction": "inbound", "channel": "sms", "at": "2025-12-03T10:04:00Z" }
]
}

Voice payload

{
"event": "agent.message",
"channel": "voice",
"timestamp": "2025-12-03T10:05:00Z",
"agentId": "agent_123",
"data": {
"callId": "call_abc123",
"numberId": "num_abc",
"from": "+14155551234",
"to": "+18571234567",
"status": "in-progress",
"transcript": "I need help with my order",
"confidence": 0.95,
"direction": "inbound"
},
"conversationState": null,
"recentHistory": [
{ "content": "Hello, how can I help?", "direction": "outbound", "channel": "voice", "at": "2025-12-03T10:04:30Z" }
]
}

Testing with curl

Send a mock payload to your local server:

curl -X POST http://localhost:3000/webhook \
-H "Content-Type: application/json" \
-d '{
"event": "agent.message",
"channel": "voice",
"agentId": "agent_123",
"data": {
"callId": "call_test",
"from": "+14155551234",
"to": "+18571234567",
"transcript": "What are your hours?",
"confidence": 0.95,
"direction": "inbound"
},
"conversationState": null,
"recentHistory": []
}'

Example test handlers

Python (Flask)

from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
payload = request.json
channel = payload.get('channel')
data = payload.get('data', {})
if channel == 'sms':
print(f"SMS from {data['from']}: {data['message']}")
return jsonify({'status': 'ok'}), 200
if channel == 'voice':
print(f"Voice from {data['from']}: {data['transcript']}")
return jsonify({'text': f"I heard: {data['transcript']}"}), 200
return jsonify({'status': 'ok'}), 200
if __name__ == '__main__':
app.run(port=3000)

Node.js (Express)

const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook', (req, res) => {
const { channel, data } = req.body;
if (channel === 'sms') {
console.log(`SMS from ${data.from}: ${data.message}`);
return res.status(200).json({ status: 'ok' });
}
if (channel === 'voice') {
console.log(`Voice from ${data.from}: ${data.transcript}`);
return res.status(200).json({ text: `I heard: ${data.transcript}` });
}
res.status(200).json({ status: 'ok' });
});
app.listen(3000, () => console.log('Webhook server on port 3000'));

Checking webhook deliveries

Monitor delivery status to debug issues:

curl "https://api.agentphone.ai/v1/webhooks/deliveries?limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"

The response shows delivery attempts, HTTP status codes, error messages, and retry timestamps. Use this to verify your endpoint is receiving and acknowledging webhooks correctly.