Anonymous Endpoints
Anonymous Endpoints provide temporary, public webhook URLs for quick testing and debugging without creating a Hooklistener account. Perfect for evaluating webhook integrations, testing during development, or sharing webhook inspection URLs.
Overview
Anonymous Endpoints let you create a temporary webhook URL instantly, without authentication. Send webhooks to the URL, and view them in real-time through a web interface or API. Endpoints expire automatically after 24 hours (configurable).
Key features:
- No account required: Create endpoints without signing up
- Instant creation: Get a webhook URL in seconds
- Real-time inspection: View incoming webhooks immediately
- Temporary by design: Auto-expire after configurable TTL (default: 24 hours)
- Public viewing: Share inspection URL with team members
- WebSocket streaming: Real-time webhook notifications via WebSocket
- Zero setup: No configuration, authentication, or API keys needed
When to Use
Perfect For:
Quick testing:
- Test webhook integrations during development
- Debug webhook payloads without setup
- Verify webhook format before production
Evaluation:
- Try Hooklistener without creating account
- Evaluate webhook provider behavior
- Share webhook examples with team
Temporary needs:
- One-time webhook testing
- Short-lived debugging sessions
- Quick webhook inspection
Not Recommended For:
Production use:
- Long-term webhook handling
- Critical business workflows
- Persistent webhook storage
Sensitive data:
- Production credentials
- Customer information
- Confidential payloads
Team collaboration:
- Permanent team access
- Role-based permissions
- Organization-wide resources
For production needs, use Debug Endpoints with your Organization instead.
How It Works
Endpoint Lifecycle
-
Create endpoint:
- No authentication required
- Receive unique endpoint ID and viewer token
- Get webhook URL and inspection URL
-
Send webhooks:
- POST requests to webhook URL
- All HTTP methods supported
- Any payload format accepted
-
View webhooks:
- Use viewer token to access inspection interface
- Real-time WebSocket updates
- Full request details (headers, body, method)
-
Expiration:
- Default TTL: 24 hours
- Configurable from 1 hour to 7 days
- Auto-cleanup after expiration
Security Model
Viewer token:
- 32-byte random token (Base64-encoded)
- Required to view webhook details
- SHA256-hashed before storage
- Returned only once on creation
Access control:
- Anyone can send webhooks to endpoint
- Only viewer token holders can see webhook data
- Endpoints cannot be listed or discovered
- No permanent record after expiration
Creating Anonymous Endpoints
Via Web Interface
Navigate to the Hooklistener homepage without logging in:
- Click "Try Without Account" or "Create Anonymous Endpoint"
- Optionally set expiration time (1-168 hours)
- Click "Create Endpoint"
- Save the viewer token (shown only once)
- Copy the webhook URL
- Start sending webhooks
Via API
Create endpoint:
curl -X POST https://api.hooklistener.com/api/v1/anon/endpoints \
-H "Content-Type: application/json" \
-d '{
"ttl_seconds": 86400
}'
Response:
{
"id": "anon-abc123def456",
"viewer_token": "dGhpc2lzYXJhbmRvbXRva2VuZXhhbXBsZQ",
"expires_at": "2024-01-16T10:30:00Z",
"webhook_url": "https://api.hooklistener.com/anon/anon-abc123def456"
}
Important: Store the viewer_token securely - it cannot be retrieved later!
TTL Configuration
Specify how long the endpoint should remain active:
Minimum: 3600 seconds (1 hour) Default: 86400 seconds (24 hours) Maximum: 604800 seconds (7 days)
curl -X POST https://api.hooklistener.com/api/v1/anon/endpoints \
-H "Content-Type: application/json" \
-d '{
"ttl_seconds": 3600
}'
Sending Webhooks
Send HTTP requests to your webhook URL:
Basic Request
curl -X POST https://api.hooklistener.com/anon/anon-abc123def456 \
-H "Content-Type: application/json" \
-d '{
"event": "test",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"user_id": "12345",
"action": "created"
}
}'
With Custom Headers
curl -X POST https://api.hooklistener.com/anon/anon-abc123def456 \
-H "Content-Type: application/json" \
-H "X-Custom-Header: value" \
-H "X-Signature: abc123" \
-d '{
"event": "payment.succeeded"
}'
Different Methods
All HTTP methods are supported:
# GET request
curl -X GET https://api.hooklistener.com/anon/anon-abc123def456?param=value
# PUT request
curl -X PUT https://api.hooklistener.com/anon/anon-abc123def456 \
-d '{"status": "updated"}'
# DELETE request
curl -X DELETE https://api.hooklistener.com/anon/anon-abc123def456
Response
All webhook requests receive:
{
"message": "Webhook captured successfully",
"event_id": "evt_xyz789"
}
HTTP 200 OK - Webhook received and stored HTTP 404 Not Found - Endpoint doesn't exist HTTP 410 Gone - Endpoint expired or claimed
Viewing Webhooks
Via Web Interface
Access the inspection interface:
https://app.hooklistener.com/anon/{endpoint_id}?token={viewer_token}
Features:
- Real-time webhook list
- Full request details (method, headers, body)
- Syntax highlighting for JSON payloads
- Copy request details
- Filter and search
Via API
List webhooks:
curl -X GET "https://api.hooklistener.com/api/v1/anon/endpoints/{endpoint_id}/events?page=1&page_size=50" \
-H "Authorization: Bearer {viewer_token}"
Response:
{
"data": [
{
"id": "evt_xyz789",
"endpoint_id": "anon-abc123def456",
"method": "POST",
"status": "200",
"headers": {
"content-type": "application/json",
"user-agent": "curl/7.68.0"
},
"body": "{\"event\":\"test\"}",
"inserted_at": "2024-01-15T10:30:00Z"
}
],
"pagination": {
"page": 1,
"page_size": 50,
"total_count": 15,
"total_pages": 1
}
}
Get specific webhook:
curl -X GET "https://api.hooklistener.com/api/v1/anon/endpoints/{endpoint_id}/events/{event_id}" \
-H "Authorization: Bearer {viewer_token}"
Response:
{
"id": "evt_xyz789",
"endpoint_id": "anon-abc123def456",
"method": "POST",
"status": "200",
"headers": {
"content-type": "application/json",
"x-custom-header": "value"
},
"body": "{\"event\":\"test\",\"data\":{\"user_id\":\"12345\"}}",
"inserted_at": "2024-01-15T10:30:00Z"
}
Real-Time Updates
WebSocket Connection
Subscribe to real-time webhook notifications:
Connect:
const socket = new WebSocket('wss://api.hooklistener.com/socket');
socket.onopen = () => {
// Join the endpoint channel
socket.send(JSON.stringify({
topic: `anon_webhook:${endpoint_id}`,
event: 'phx_join',
payload: { token: viewer_token },
ref: '1'
}));
};
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.event === 'webhook_received') {
console.log('New webhook:', message.payload);
// Update UI with new webhook
}
};
Webhook event payload:
{
"event_id": "evt_xyz789",
"endpoint_id": "anon-abc123def456",
"method": "POST",
"status": "200",
"headers": {
"content-type": "application/json"
},
"body": "{\"event\":\"test\"}",
"timestamp": "2024-01-15T10:30:00Z"
}
JavaScript Example
Complete example for web interface:
class AnonEndpointViewer {
constructor(endpointId, viewerToken) {
this.endpointId = endpointId;
this.viewerToken = viewerToken;
this.socket = null;
this.webhooks = [];
}
connect() {
this.socket = new WebSocket('wss://api.hooklistener.com/socket');
this.socket.onopen = () => {
console.log('Connected to WebSocket');
this.joinChannel();
};
this.socket.onmessage = (event) => {
const message = JSON.parse(event.data);
this.handleMessage(message);
};
this.socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
this.socket.onclose = () => {
console.log('WebSocket closed');
// Reconnect after 5 seconds
setTimeout(() => this.connect(), 5000);
};
}
joinChannel() {
this.socket.send(JSON.stringify({
topic: `anon_webhook:${this.endpointId}`,
event: 'phx_join',
payload: { token: this.viewerToken },
ref: '1'
}));
}
handleMessage(message) {
if (message.event === 'webhook_received') {
this.webhooks.unshift(message.payload);
this.updateUI();
this.playNotificationSound();
}
}
updateUI() {
const container = document.getElementById('webhooks');
container.innerHTML = this.webhooks.map(webhook => `
<div class="webhook">
<div class="webhook-header">
<span class="method">${webhook.method}</span>
<span class="timestamp">${webhook.timestamp}</span>
</div>
<pre class="webhook-body">${JSON.stringify(JSON.parse(webhook.body), null, 2)}</pre>
</div>
`).join('');
}
playNotificationSound() {
const audio = new Audio('/notification.mp3');
audio.play();
}
disconnect() {
if (this.socket) {
this.socket.close();
}
}
}
// Usage
const viewer = new AnonEndpointViewer('anon-abc123def456', 'dGhpc2lzYXJhbmRvbXRva2VuZXhhbXBsZQ');
viewer.connect();
Checking Endpoint Status
Verify if an endpoint is still active:
curl -X GET https://api.hooklistener.com/api/v1/anon/endpoints/{endpoint_id}
Active endpoint:
{
"id": "anon-abc123def456",
"active": true,
"expires_at": "2024-01-16T10:30:00Z",
"webhook_url": "https://api.hooklistener.com/anon/anon-abc123def456"
}
Expired endpoint:
{
"error": "Endpoint has expired or been claimed",
"active": false
}
HTTP status codes:
- 200 OK - Endpoint is active
- 404 Not Found - Endpoint doesn't exist
- 410 Gone - Endpoint expired or claimed
Use Cases
Testing Stripe Webhooks
1. Create anonymous endpoint:
curl -X POST https://api.hooklistener.com/api/v1/anon/endpoints \
-H "Content-Type: application/json" \
-d '{"ttl_seconds": 3600}'
2. Configure Stripe webhook:
- Go to Stripe Dashboard → Developers → Webhooks
- Add endpoint:
https://api.hooklistener.com/anon/anon-abc123def456 - Select events to send
3. Trigger test event:
- Use Stripe's "Send test webhook" feature
- Or perform actual action (create customer, charge card)
4. View webhook in browser:
https://app.hooklistener.com/anon/anon-abc123def456?token={viewer_token}
Debugging GitHub Webhooks
1. Create endpoint:
curl -X POST https://api.hooklistener.com/api/v1/anon/endpoints \
-H "Content-Type: application/json" \
-d '{"ttl_seconds": 7200}'
2. Add to GitHub repository:
- Settings → Webhooks → Add webhook
- Payload URL:
https://api.hooklistener.com/anon/anon-abc123def456 - Content type: application/json
- Select events
3. Trigger events:
- Push code, create issue, open PR, etc.
- View webhooks in real-time
4. Inspect payload:
curl -X GET "https://api.hooklistener.com/api/v1/anon/endpoints/anon-abc123def456/events" \
-H "Authorization: Bearer {viewer_token}"
Sharing Webhook Examples
Scenario: Show teammate webhook structure
1. Create temporary endpoint:
curl -X POST https://api.hooklistener.com/api/v1/anon/endpoints
2. Send example webhook:
curl -X POST https://api.hooklistener.com/anon/anon-abc123def456 \
-H "Content-Type: application/json" \
-d '{
"order_id": "ORD-12345",
"status": "completed",
"items": [
{"sku": "WIDGET-001", "quantity": 2}
]
}'
3. Share inspection URL with teammate:
https://app.hooklistener.com/anon/anon-abc123def456?token={viewer_token}
4. Endpoint auto-expires after 24 hours
Limitations
Anonymous Endpoints have intentional limitations to prevent abuse:
Storage Limits
Webhooks per endpoint: 1,000 maximum
- Oldest webhooks deleted when limit reached
- FIFO (first in, first out) cleanup
Body size: 1 MB maximum per webhook
- Larger payloads truncated
- Preview limited to 1 KB in list view
- Full body available in detail view (up to 1 MB)
Time Limits
Minimum TTL: 1 hour (3,600 seconds) Maximum TTL: 7 days (604,800 seconds) Default TTL: 24 hours (86,400 seconds)
After expiration:
- Webhook URL returns 410 Gone
- Viewing interface shows expired message
- All data permanently deleted
Rate Limits
Endpoint creation: 10 per hour per IP Webhook requests: 100 per minute per endpoint API requests: 60 per minute per viewer token
Exceeding limits returns:
- 429 Too Many Requests
Retry-Afterheader with seconds to wait
Security Limits
No authentication features:
- Cannot add API keys
- Cannot verify signatures
- Cannot add custom headers
No forwarding:
- Webhooks are only stored, not forwarded
- Cannot create destinations
- Cannot apply transformations
Public by design:
- Anyone with endpoint ID can send webhooks
- Anyone with viewer token can view webhooks
- No IP allowlisting
Security Considerations
Best Practices
-
Don't use for production:
- Anonymous endpoints are temporary
- No SLA or reliability guarantees
- Data deleted after expiration
-
Avoid sensitive data:
- Don't send production credentials
- Don't include customer PII
- Don't share production webhooks
-
Protect viewer token:
- Treat like a password
- Don't commit to version control
- Don't share publicly
- Only share with trusted team members
-
Use short TTLs:
- Set expiration appropriate to need
- Shorter TTL = less exposure window
- Delete when no longer needed
-
Monitor for abuse:
- Check webhook origins
- Verify expected payloads
- Report suspicious activity
What Anonymous Endpoints Are NOT
Not for:
- Production webhook handling
- Long-term storage
- Sensitive data
- Compliance requirements (SOC 2, HIPAA, etc.)
- Team collaboration with permissions
- Audit trails
- Automated workflows
For these needs, create an account and use Debug Endpoints or Bridges.
Migrating to Debug Endpoints
When you're ready for production, migrate to Debug Endpoints:
Anonymous Endpoints:
- ❌ Temporary (max 7 days)
- ❌ No account required
- ❌ Public access with token
- ❌ Limited features
- ❌ No forwarding
Debug Endpoints:
- ✅ Permanent (until deleted)
- ✅ Organization-owned
- ✅ Role-based access control
- ✅ Full feature set
- ✅ Can forward to destinations
Migration Steps
- Create Hooklistener account
- Create Organization
- Create Debug Endpoint with same name
- Update webhook URL in provider
- Test new endpoint
- Let anonymous endpoint expire
See Debug Endpoints for details.
Troubleshooting
Endpoint Not Found (404)
Causes:
- Endpoint ID incorrect
- Endpoint never existed
- Endpoint already expired
Solution:
- Verify endpoint ID
- Check expiration time
- Create new endpoint if expired
Endpoint Expired (410)
Causes:
- TTL elapsed
- Endpoint manually claimed/deleted
Solution:
- Create new endpoint
- Use longer TTL
- Consider Debug Endpoint for permanence
Cannot View Webhooks (401)
Causes:
- Invalid viewer token
- Viewer token missing
- Token not in Authorization header
Solution:
# Correct format
curl -H "Authorization: Bearer {viewer_token}" ...
# Not this
curl -H "X-Viewer-Token: {viewer_token}" ...
Webhooks Not Appearing
Causes:
- WebSocket not connected
- Wrong endpoint ID
- Webhooks sent to different endpoint
Solution:
- Check browser console for errors
- Verify endpoint ID in URL
- Test with curl to confirm webhook received
Rate Limited (429)
Causes:
- Too many endpoint creations (10/hour per IP)
- Too many webhooks (100/min per endpoint)
- Too many API requests (60/min per token)
Solution:
- Wait for rate limit reset (see
Retry-Afterheader) - Reduce request frequency
- Use Debug Endpoint for higher limits
Next Steps
Now that you understand Anonymous Endpoints:
- Try it yourself - No account needed
- Create Debug Endpoint for permanent testing
- Build Bridges for production workflows
- Sign up for full features
Anonymous Endpoints are perfect for quick testing and evaluation. For production use and team collaboration, create a Hooklistener account and use the full platform features.