Skip to content

API Reference Summary

Quick reference for key WebDecoy API endpoints.


The WebDecoy API uses REST architecture with JSON payloads. All endpoints require authentication via Bearer token (API key or Auth0 JWT).

https://api.webdecoy.com/api
Authorization: Bearer sk_live_your_api_key

Or for user sessions:

Authorization: Bearer <auth0_jwt_token>

POST /auth/callback
Authorization: Bearer <auth0_jwt>

Response:

{
"id": "user-uuid",
"auth0_id": "auth0|123",
"email": "[email protected]",
"name": "User Name"
}
GET /auth/me
Authorization: Bearer <token>

POST /organizations
Authorization: Bearer <token>
{
"name": "My Organization"
}
GET /organizations?page=1&page_size=50
Authorization: Bearer <token>
GET /organizations/{organization_id}
Authorization: Bearer <token>
PUT /organizations/{organization_id}
Authorization: Bearer <token>
{
"name": "Updated Name"
}

POST /organizations/{organization_id}/properties
Authorization: Bearer <token>
{
"name": "Production Website"
}
GET /organizations/{organization_id}/properties?page=1&page_size=50
Authorization: Bearer <token>
GET /properties/{property_id}
Authorization: Bearer <token>

POST /organizations/{organization_id}/domains
Authorization: Bearer <token>
{
"domain": "decoy.example.com",
"record_type": "A"
}
GET /organizations/{organization_id}/domains
Authorization: Bearer <token>
POST /domains/{domain_id}/verify
Authorization: Bearer <token>
POST /domains/{domain_id}/acme/challenge # start a DNS-01 challenge
POST /domains/{domain_id}/acme/verify-dns # check the TXT record
POST /domains/{domain_id}/acme/verify # complete issuance
POST /domains/{domain_id}/acme/reset # start over
POST /domains/{domain_id}/ssl/http01/initiate # HTTP-01 alternative (A-record domains)
POST /domains/{domain_id}/ssl/http01/complete
Authorization: Bearer <token>
POST /domains/{domain_id}/ssl-status
Authorization: Bearer <token>

POST /decoys
Authorization: Bearer <token>
{
"custom_domain_id": "domain-uuid",
"name": "Admin Backup Trap",
"path": "/admin/backup.zip",
"trigger_action": "log",
"decoy_type": "link"
}
GET /decoys?page=1&page_size=50
Authorization: Bearer <token>
GET /decoys/{decoy_id}
Authorization: Bearer <token>
PATCH /decoys/{decoy_id}
Authorization: Bearer <token>
{
"name": "Updated Name",
"trigger_action": "block"
}
DELETE /decoys/{decoy_id}
Authorization: Bearer <token>

POST /organizations/{organization_id}/bot-scanners
Authorization: Bearer <token>
{
"name": "Main Scanner",
"enabled": true,
"sensitivity": "medium"
}
GET /organizations/{organization_id}/bot-scanners
Authorization: Bearer <token>
GET /organizations/{organization_id}/bot-scanners/{scanner_id}/snippet
Authorization: Bearer <token>
PATCH /organizations/{organization_id}/bot-scanners/{scanner_id}/toggle
Authorization: Bearer <token>

GET /organizations/{organization_id}/detections?page=1&page_size=50
Authorization: Bearer <token>

Query Parameters:

ParameterDescription
property_idFilter by property
sourceDetection source (decoy_link, endpoint, bot_scanner, sdk, honeypot_agent)
min_bot_scoreMinimum bot score
max_bot_scoreMaximum bot score
countryCountry code(s)
is_proxytrue/false
is_vpntrue/false
is_tortrue/false
start_dateISO 8601 date
end_dateISO 8601 date
sort_bytimestamp, bot_score
sort_orderasc, desc
GET /organizations/{organization_id}/detections/{detection_id}
Authorization: Bearer <token>
GET /organizations/{organization_id}/detections/stats
Authorization: Bearer <token>
GET /organizations/{organization_id}/detections/stats/hourly
Authorization: Bearer <token>
GET /organizations/{organization_id}/detections/filter-options
Authorization: Bearer <token>
GET /organizations/{organization_id}/detections/export?format=csv
Authorization: Bearer <token>

Formats: csv, json. Respects the same filters as List Detections.

GET /organizations/{organization_id}/detections/geo
GET /organizations/{organization_id}/detections/stats/rule-executions
GET /organizations/{organization_id}/detections/stats/signals
GET /organizations/{organization_id}/detections/stats/ai-scrapers
GET /organizations/{organization_id}/detections/stats/ai-scrapers/by-name
GET /organizations/{organization_id}/detections/stats/llm-referrals
GET /organizations/{organization_id}/detections/stats/llm-referrals/by-platform
GET /organizations/{organization_id}/detections/stats/llm-referrals/top-pages
GET /organizations/{organization_id}/detections/stats/page-crawlers
GET /organizations/{organization_id}/detections/stats/radar
GET /organizations/{organization_id}/detections/stats/categories
GET /organizations/{organization_id}/detections/stats/top-sources
Authorization: Bearer <token>

Persistent cross-IP adversary identities. See Actors.

GET /organizations/{organization_id}/actors # list; supports sort=threat|ip|property|last_seen, filter=rotating|enforced|ready
GET /organizations/{organization_id}/actors/stats # org summary for the dashboard hero row
GET /organizations/{organization_id}/actors/{actor_id} # actor + IP/UA footprint + recent detections
Authorization: Bearer <token>

The WAF-enforcement pipeline (see Session Clearance). All routes are org-scoped.

POST /organizations/{organization_id}/enforcement/cloudflare/preflight # harmless zone live-test
GET /organizations/{organization_id}/enforcement/mode # monitor | enforce
PUT /organizations/{organization_id}/enforcement/mode
GET /organizations/{organization_id}/enforcement/signatures # active composite signatures (+ pushed count)
GET /organizations/{organization_id}/enforcement/denylist # clearance deny-list
POST /organizations/{organization_id}/enforcement/denylist
DELETE /organizations/{organization_id}/enforcement/denylist/{device_fp}
GET /organizations/{organization_id}/enforcement/routes # token-enforced route scope
POST /organizations/{organization_id}/enforcement/routes
DELETE /organizations/{organization_id}/enforcement/routes/{route_id}
GET /organizations/{organization_id}/enforcement/allowlist # verified-crawler categories
PUT /organizations/{organization_id}/enforcement/allowlist
GET /organizations/{organization_id}/enforcement/credentials # machine service tokens
POST /organizations/{organization_id}/enforcement/credentials
DELETE /organizations/{organization_id}/enforcement/credentials/{credential_id}
GET /organizations/{organization_id}/enforcement/audit # append-only change log
Authorization: Bearer <token>

WHEN→THEN automations (see Response Actions).

GET /organizations/{organization_id}/response-actions
POST /organizations/{organization_id}/response-actions
PUT /organizations/{organization_id}/response-actions/{id}
DELETE /organizations/{organization_id}/response-actions/{id}
Authorization: Bearer <token>

GET /mitre/tactics
GET /organizations/{organization_id}/mitre/stats
Authorization: Bearer <token>

POST /organizations/{organization_id}/integrations/cloudflare
Authorization: Bearer <token>
{
"api_token": "cloudflare_token",
"account_id": "account_id",
"zone_id": "zone_id",
"zone_name": "example.com"
}

Slack, Vercel, Datadog, Splunk, AWS WAF, Fastly, and CrowdStrike each have equivalent org-scoped CRUD + test endpoints under /organizations/{organization_id}/integrations/{provider}.

POST /organizations/{organization_id}/integrations/webhooks
Authorization: Bearer <token>
{
"name": "My Webhook",
"url": "https://example.com/webhook",
"on_detection": true,
"min_bot_score": 70
}
POST /organizations/{organization_id}/integrations/webhooks/{webhook_id}/test
Authorization: Bearer <token>

POST /organizations/{organization_id}/api-keys
Authorization: Bearer <token>
{
"name": "Production SDK",
"scopes": ["detections:read", "detections:write"],
"expires_in": 365
}

Response:

{
"id": "key-uuid",
"name": "Production SDK",
"api_key": "sk_live_xxxxxxx",
"key_prefix": "sk_live_xxx",
"scopes": ["detections:read", "detections:write"]
}

Important: The full api_key is only returned once. Store it securely.

GET /organizations/{organization_id}/api-keys
Authorization: Bearer <token>
DELETE /organizations/{organization_id}/api-keys/{key_id}
Authorization: Bearer <token>

GET /billing/plans
Authorization: Bearer <token>
POST /billing/checkout-session
Authorization: Bearer <token>
{
"organization_id": "org-uuid",
"price_id": "price_xxx",
"success_url": "https://app.example.com/billing/success",
"cancel_url": "https://app.example.com/billing"
}
GET /organizations/{organization_id}/subscription
Authorization: Bearer <token>
GET /organizations/{organization_id}/billing/usage
Authorization: Bearer <token>

These endpoints live on the ingest service — base URL https://ingest.webdecoy.com — and are what the SDKs, detection scripts, and edge validators talk to.

POST /api/v1/detect # submit a detection (X-API-Key: sk_live_...)
POST /api/v1/detect/public # detection-script submissions (site-key based)
POST /api/v1/clearance # mint a wd_clearance token (publishable site key: aid)
GET /api/v1/clearance/config # edge-validator config
POST /api/v1/page-serve # page-serve telemetry
POST /api/v1/verify-js # JS-execution verification
GET /api/v1/auth/validate-key # validate an API key
POST /api/v1/sdk/detect # SDK detection submissions
POST /api/v1/sdk/violations/batch # SDK rules-engine violation batches
GET /api/v1/sdk/ip/{address}/enrichment # IP enrichment for SDK filter rules

{
"data": { ... },
"total": 100,
"page": 1,
"page_size": 50
}
{
"error": "Error message",
"code": "ERROR_CODE",
"status": 400
}
CodeMeaning
200Success
201Created
400Bad Request
401Unauthorized
403Forbidden
404Not Found
429Rate Limited
500Server Error

Endpoint TypeLimit
Read operations100/minute
Write operations30/minute
Detection submission1000/minute

Rate limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642680000