REST API
Language-agnostic REST API reference for webhooks.cc. Use any HTTP client to manage endpoints, inspect requests, and stream webhooks.
Updated Mar 2026
Overview
The TypeScript SDK wraps this API, but you can call it directly from any language using standard HTTP requests. All request and response bodies use JSON.
Base URL: https://webhooks.cc
Webhook receiver URL: https://go.webhooks.cc
Authentication
Authenticate by passing your API key in the Authorization header:
Authorization: Bearer whcc_...
API keys are generated from the account page. Keys use the whcc_ prefix and are stored as SHA-256 hashes — the raw key is shown only once at creation time.
Some sensitive operations (account deletion, API key management) require a Supabase session token
instead of an API key. These operations return 403 when called with an API key.
Endpoints
Create endpoint
curl -X POST https://webhooks.cc/api/endpoints \
-H "Authorization: Bearer whcc_..." \
-H "Content-Type: application/json" \
-d '{"name": "my-endpoint"}'Response:
{
"id": "...",
"slug": "abc123",
"name": "my-endpoint",
"url": "https://go.webhooks.cc/w/abc123",
"createdAt": 1234567890000
}List endpoints
curl https://webhooks.cc/api/endpoints \
-H "Authorization: Bearer whcc_..."Returns an array of endpoint objects.
Get endpoint
curl https://webhooks.cc/api/endpoints/abc123 \
-H "Authorization: Bearer whcc_..."Update endpoint
Update an endpoint's name, mock response, or notification webhook.
curl -X PATCH https://webhooks.cc/api/endpoints/abc123 \
-H "Authorization: Bearer whcc_..." \
-H "Content-Type: application/json" \
-d '{"name": "new-name", "mockResponse": {"status": 200, "body": "{\"ok\":true}", "headers": {"Content-Type": "application/json"}}, "notificationUrl": "https://hooks.slack.com/services/..."}'Set "mockResponse": null to clear the mock response and return to the default 200 OK. Set "notificationUrl": null to stop sending notifications. The notificationUrl must be a valid http or https URL, max 2048 characters.
Delete endpoint
Deletes the endpoint and all its captured requests.
curl -X DELETE https://webhooks.cc/api/endpoints/abc123 \
-H "Authorization: Bearer whcc_..."Requests
List requests
curl "https://webhooks.cc/api/endpoints/abc123/requests?limit=50" \
-H "Authorization: Bearer whcc_..."Returns an array of request objects, newest first.
List requests (paginated)
curl "https://webhooks.cc/api/endpoints/abc123/requests/paginated?limit=20&cursor=..." \
-H "Authorization: Bearer whcc_..."Response:
{
"items": [{ "id": "...", "method": "POST", "...": "..." }],
"cursor": "eyJ...",
"hasMore": true
}Pass the returned cursor to the next request to fetch the next page.
Get single request
curl https://webhooks.cc/api/requests/REQUEST_ID \
-H "Authorization: Bearer whcc_..."Response:
{
"id": "REQUEST_ID",
"endpointId": "...",
"method": "POST",
"path": "/",
"headers": { "content-type": "application/json", "...": "..." },
"body": "{\"event\": \"test\"}",
"queryParams": {},
"contentType": "application/json",
"ip": "203.0.113.1",
"size": 18,
"receivedAt": 1234567890000
}Clear requests
Delete all captured requests for an endpoint without deleting the endpoint itself.
curl -X DELETE "https://webhooks.cc/api/endpoints/abc123/requests" \
-H "Authorization: Bearer whcc_..."Send test webhook
Send a test webhook to one of your endpoints through the API.
curl -X POST https://webhooks.cc/api/send-test \
-H "Authorization: Bearer whcc_..." \
-H "Content-Type: application/json" \
-d '{"slug": "abc123", "method": "POST", "headers": {"content-type": "application/json"}, "body": "{\"event\": \"test\"}"}'Search
Search captured requests across endpoints with optional filters.
curl "https://webhooks.cc/api/search/requests?slug=abc123&method=POST&q=stripe&limit=20" \
-H "Authorization: Bearer whcc_..."Query parameters:
| Param | Type | Description |
|---|---|---|
slug | string | Filter by endpoint slug |
method | string | Filter by HTTP method |
q | string | Free-text search |
from | string | Start time (duration or timestamp) |
to | string | End time (duration or timestamp) |
limit | number | Max results (default: 50) |
offset | number | Pagination offset |
order | string | "asc" or "desc" (default) |
Search count
Count matching requests without returning them.
curl "https://webhooks.cc/api/search/requests/count?slug=abc123&method=POST" \
-H "Authorization: Bearer whcc_..."Returns { "count": 42 }. Accepts the same query parameters as search (except limit, offset, order).
Real-time streaming (SSE)
Stream incoming requests as Server-Sent Events. Useful for building integrations that react to webhooks in real time.
curl -N "https://webhooks.cc/api/stream/abc123" \
-H "Authorization: Bearer whcc_..." \
-H "Accept: text/event-stream"Each captured request arrives as an SSE message:
event: request
data: {"id":"...","method":"POST","path":"/","headers":{...},"body":"...","receivedAt":1234567890000}
The server sends keepalive pings (:ping) every 30 seconds to keep the connection alive. Maximum connection duration is 30 minutes — reconnect when the stream closes.
Usage
Check your current request quota and usage.
curl https://webhooks.cc/api/usage \
-H "Authorization: Bearer whcc_..."Response:
{
"used": 12,
"limit": 50,
"remaining": 38,
"plan": "free",
"periodEnd": 1234567890000
}Teams
Manage teams, share endpoints, and invite members. Requires a Pro plan.
List teams
curl https://webhooks.cc/api/teams \
-H "Authorization: Bearer whcc_..."Returns an array of team objects that you own or belong to.
Create team
curl -X POST https://webhooks.cc/api/teams \
-H "Authorization: Bearer whcc_..." \
-H "Content-Type: application/json" \
-d '{"name": "My Team"}'Response:
{
"id": "TEAM_ID",
"name": "My Team",
"ownerId": "...",
"createdAt": "2026-03-28T00:00:00.000Z"
}Update team
Rename a team. Only the team owner can update.
curl -X PATCH https://webhooks.cc/api/teams/TEAM_ID \
-H "Authorization: Bearer whcc_..." \
-H "Content-Type: application/json" \
-d '{"name": "Renamed Team"}'Delete team
Delete a team and remove all memberships. Only the team owner can delete.
curl -X DELETE https://webhooks.cc/api/teams/TEAM_ID \
-H "Authorization: Bearer whcc_..."Returns 204 No Content on success.
Share endpoint with team
Share one of your endpoints so all team members can view its captured requests.
curl -X POST https://webhooks.cc/api/teams/TEAM_ID/endpoints \
-H "Authorization: Bearer whcc_..." \
-H "Content-Type: application/json" \
-d '{"endpointId": "ENDPOINT_ID"}'Unshare endpoint
Remove an endpoint from a team.
curl -X DELETE https://webhooks.cc/api/teams/TEAM_ID/endpoints/ENDPOINT_ID \
-H "Authorization: Bearer whcc_..."Returns 204 No Content on success.
Invite member
Invite a user to your team by email. Only the team owner can invite.
curl -X POST https://webhooks.cc/api/teams/TEAM_ID/invite \
-H "Authorization: Bearer whcc_..." \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'List members
List all members and pending invites for a team.
curl https://webhooks.cc/api/teams/TEAM_ID/members \
-H "Authorization: Bearer whcc_..."Response:
{
"members": [
{ "userId": "...", "email": "[email protected]", "role": "owner" },
{ "userId": "...", "email": "[email protected]", "role": "member" }
],
"pendingInvites": [{ "id": "...", "email": "[email protected]", "createdAt": "..." }]
}Remove member
Remove a member from a team. Only the team owner can remove members.
curl -X DELETE https://webhooks.cc/api/teams/TEAM_ID/members/USER_ID \
-H "Authorization: Bearer whcc_..."Returns 204 No Content on success.
Leave team
Leave a team you are a member of. Owners cannot leave their own team — delete it instead.
curl -X POST https://webhooks.cc/api/teams/TEAM_ID/leave \
-H "Authorization: Bearer whcc_..."Invites
Manage team invitations sent to you.
List pending invites
curl https://webhooks.cc/api/invites \
-H "Authorization: Bearer whcc_..."Returns an array of pending invite objects addressed to your account.
Accept invite
curl -X POST https://webhooks.cc/api/invites/INVITE_ID/accept \
-H "Authorization: Bearer whcc_..."Decline invite
curl -X POST https://webhooks.cc/api/invites/INVITE_ID/decline \
-H "Authorization: Bearer whcc_..."Session-token-only routes
Some routes require a Supabase session token (from browser login) instead of an API key. These return 403 when called with an API key.
GET /api/api-keys— list your API keysPOST /api/api-keys— create a new API keyDELETE /api/api-keys?id=...— delete an API keyDELETE /api/account— delete your account and all data
These routes are designed for the web dashboard, not programmatic access.
Error handling
All errors return a JSON body with an error field:
{ "error": "Invalid or missing API key" }| Status | Meaning |
|---|---|
400 | Validation error — check request body and parameters |
401 | Invalid or missing API key |
404 | Resource not found |
429 | Rate limited — check Retry-After header for wait time |
500 | Server error |
Rate limit headers
Rate-limited endpoints return these headers on every response (not just 429s):
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Remaining requests in the current window |
X-RateLimit-Reset | Unix timestamp (seconds) when the window resets |
Retry-After | Seconds to wait (only on 429 responses) |
Language examples
Python
import requests
API_KEY = "whcc_..."
BASE = "https://webhooks.cc"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# Create endpoint
endpoint = requests.post(f"{BASE}/api/endpoints", headers=HEADERS, json={"name": "my-endpoint"}).json()
slug = endpoint["slug"]
print(f"Webhook URL: {endpoint['url']}")
# Send a test webhook
requests.post(f"{BASE}/api/send-test", headers=HEADERS, json={
"slug": slug,
"method": "POST",
"headers": {"content-type": "application/json"},
"body": '{"event": "test"}'
})
# List captured requests
captured = requests.get(f"{BASE}/api/endpoints/{slug}/requests", headers=HEADERS).json()
for req in captured:
print(f"{req['method']} {req['path']} — {req['receivedAt']}")Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const (
base = "https://webhooks.cc"
apiKey = "whcc_..."
)
func main() {
// Create endpoint
body, _ := json.Marshal(map[string]string{"name": "my-endpoint"})
req, _ := http.NewRequest("POST", base+"/api/endpoints", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
var endpoint map[string]interface{}
json.Unmarshal(data, &endpoint)
fmt.Printf("Webhook URL: %s\n", endpoint["url"])
// List requests
slug := endpoint["slug"].(string)
req, _ = http.NewRequest("GET", base+"/api/endpoints/"+slug+"/requests", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
resp, _ = http.DefaultClient.Do(req)
defer resp.Body.Close()
data, _ = io.ReadAll(resp.Body)
var requests []map[string]interface{}
json.Unmarshal(data, &requests)
for _, r := range requests {
fmt.Printf("%s %s\n", r["method"], r["path"])
}
}Ruby
require "net/http"
require "json"
require "uri"
API_KEY = "whcc_..."
BASE = "https://webhooks.cc"
def api_request(method, path, body = nil)
uri = URI("#{BASE}#{path}")
req = case method
when :get then Net::HTTP::Get.new(uri)
when :post then Net::HTTP::Post.new(uri)
when :delete then Net::HTTP::Delete.new(uri)
end
req["Authorization"] = "Bearer #{API_KEY}"
req["Content-Type"] = "application/json"
req.body = body.to_json if body
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
JSON.parse(res.body)
end
# Create endpoint
endpoint = api_request(:post, "/api/endpoints", { name: "my-endpoint" })
slug = endpoint["slug"]
puts "Webhook URL: #{endpoint['url']}"
# Send a test webhook
api_request(:post, "/api/send-test", {
slug: slug,
method: "POST",
headers: { "content-type" => "application/json" },
body: '{"event": "test"}'
})
# List captured requests
requests = api_request(:get, "/api/endpoints/#{slug}/requests")
requests.each do |req|
puts "#{req['method']} #{req['path']} — #{req['receivedAt']}"
endRust
use reqwest::header::{AUTHORIZATION, CONTENT_TYPE, HeaderMap, HeaderValue};
use serde_json::{json, Value};
const BASE: &str = "https://webhooks.cc";
const API_KEY: &str = "whcc_...";
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let mut headers = HeaderMap::new();
headers.insert(AUTHORIZATION, HeaderValue::from_str(&format!("Bearer {API_KEY}"))?);
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
// Create endpoint
let endpoint: Value = client
.post(format!("{BASE}/api/endpoints"))
.headers(headers.clone())
.json(&json!({"name": "my-endpoint"}))
.send()
.await?
.json()
.await?;
let slug = endpoint["slug"].as_str().unwrap();
println!("Webhook URL: {}", endpoint["url"]);
// Send a test webhook
client
.post(format!("{BASE}/api/send-test"))
.headers(headers.clone())
.json(&json!({
"slug": slug,
"method": "POST",
"headers": {"content-type": "application/json"},
"body": r#"{"event": "test"}"#
}))
.send()
.await?;
// List captured requests
let requests: Vec<Value> = client
.get(format!("{BASE}/api/endpoints/{slug}/requests"))
.headers(headers)
.send()
.await?
.json()
.await?;
for req in &requests {
println!("{} {}", req["method"], req["path"]);
}
Ok(())
}Next steps
TypeScript SDK reference
Full method reference for the @webhooks-cc/sdk package.
Plans & Limits
Request quotas, billing periods, and plan details.
Interactive API Explorer
Try the API directly from your browser with the interactive reference.