Skip to main content

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

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

  1. Create endpoint:

    • No authentication required
    • Receive unique endpoint ID and viewer token
    • Get webhook URL and inspection URL
  2. Send webhooks:

    • POST requests to webhook URL
    • All HTTP methods supported
    • Any payload format accepted
  3. View webhooks:

    • Use viewer token to access inspection interface
    • Real-time WebSocket updates
    • Full request details (headers, body, method)
  4. 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:

  1. Click "Try Without Account" or "Create Anonymous Endpoint"
  2. Optionally set expiration time (1-168 hours)
  3. Click "Create Endpoint"
  4. Save the viewer token (shown only once)
  5. Copy the webhook URL
  6. 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-After header 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

  1. Don't use for production:

    • Anonymous endpoints are temporary
    • No SLA or reliability guarantees
    • Data deleted after expiration
  2. Avoid sensitive data:

    • Don't send production credentials
    • Don't include customer PII
    • Don't share production webhooks
  3. Protect viewer token:

    • Treat like a password
    • Don't commit to version control
    • Don't share publicly
    • Only share with trusted team members
  4. Use short TTLs:

    • Set expiration appropriate to need
    • Shorter TTL = less exposure window
    • Delete when no longer needed
  5. 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

  1. Create Hooklistener account
  2. Create Organization
  3. Create Debug Endpoint with same name
  4. Update webhook URL in provider
  5. Test new endpoint
  6. 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-After header)
  • Reduce request frequency
  • Use Debug Endpoint for higher limits

Next Steps

Now that you understand Anonymous Endpoints:

  1. Try it yourself - No account needed
  2. Create Debug Endpoint for permanent testing
  3. Build Bridges for production workflows
  4. 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.