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:

Parameter Description
property_id Filter by property
source Detection source (decoy_link, endpoint, bot_scanner, sdk, honeypot_agent)
min_bot_score Minimum bot score
max_bot_score Maximum bot score
country Country code(s)
is_proxy true/false
is_vpn true/false
is_tor true/false
start_date ISO 8601 date
end_date ISO 8601 date
sort_by timestamp, bot_score
sort_order asc, 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.

Building a sensor for a stack we do not ship one for? The full wire contract — fields, the client signals block, client-IP resolution, and the fail-open behaviour a sensor must implement — is documented in the Sensor Protocol.

POST /api/v1/detect # submit a detection (Authorization: Bearer sk_live_...)
POST /api/v1/detect/public # browser tag only (aid + sid, unauthenticated)
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
}
Code Meaning
200 Success
201 Created
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
429 Rate Limited
500 Server Error

Endpoint Type Limit
Read operations 100/minute
Write operations 30/minute
Detection submission 1000/minute

Rate limit headers:

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