Customer API
Reference documentation for accessing PentaTrail CTEM data via REST API and MCP. This read-only public surface requires ctem:read and is generated from the same OpenAPI source as the landing page.
Authentication
Include your API key as a Bearer token in all requests. Generate API keys from the PentaTrail Dashboard under Settings > API Keys.
curl -H "Authorization: Bearer ptk_your_api_key_here" \
"https://api.pentatrail.co/v1/ctem/domains"Scopes
API keys must include ctem:read scope.
ctem:readOpenAPI
The OpenAPI JSON is generated from the same source-of-truth data used by the landing page. The published docs and the machine-readable spec stay in sync.
curl -s "https://pentatrail.co/api/openapi/customer-api-v2" | jq .This spec is generated from the same source-of-truth data as the landing page.
MCP Setup
Model Context Protocol (MCP) Access read-only PentaTrail CTEM data from Model Context Protocol (MCP) clients such as Claude Code and Claude Desktop.
npx @pentatrail/mcp-server{
"mcpServers": {
"pentatrail": {
"command": "npx",
"args": ["@pentatrail/mcp-server"],
"env": {
"PENTATRAIL_API_KEY": "ptk_your_api_key_here",
"PENTATRAIL_API_URL": "https://api.pentatrail.co"
}
}
}
}PENTATRAIL_API_URL set PENTATRAIL_API_URL to https://api.pentatrail.co.
Read Endpoints
Read CTEM data. All require ctem:read scope. 9 routes are published today.
/v1/ctem/domainsctem:readList all monitored domains.
/v1/ctem/hostsctem:readList hosts for a domain with enrichment (port count, tech count, open finding count).
domain_idrequiredOrigin domain ID (UUID)pagePage number (default: 1)limitItems per page (default: 50, max: 100)host_statusFilter: active, discovered, dns_only, inactive, third_partysearchSearch by FQDNorder_bySort: fqdn, first_seen_at, last_seen_at, host_statusascendingtrue/false (default: true)/v1/ctem/findingsctem:readList vulnerabilities/findings for a domain. Default sort: Threat Discovery Level (TDL5=most critical). Only findings on active hosts are returned.
domain_idrequiredOrigin domain ID (UUID)pagePage numberlimitItems per page (max: 100)statusFilter: open, in_progress, closed, acceptedseverityFilter: critical, high, medium, low, infopriority_keyTDL filter: tdl5, tdl4, tdl3, tdl2, tdl1, infotarget_fqdnFilter by affected FQDNsource_filterall, passive_only, deep_onlyvuln_idExact match by vulnerability IDsearchSearch by title, vuln_id, or targetorder_bySort: effective_priority_rank, cvss, severity_order, first_seen_at, last_seen_atascendingtrue/false (default: true)/v1/ctem/assets/countsctem:readGet counts per asset type (hosts, IPs, ports, tech, buckets, URLs, findings).
domain_idrequiredOrigin domain ID (UUID)/v1/ctem/findings/severityctem:readGet open finding counts grouped by Threat Discovery Level (TDL). Only findings on active hosts.
domain_idrequiredOrigin domain ID (UUID)/v1/ctem/scoresctem:readGet live domain scores: asset counts and findings breakdown by severity and status.
domain_idrequiredOrigin domain ID (UUID)/v1/ctem/scores/trendctem:readGet score trend over time (snapshot-based).
domain_idrequiredOrigin domain ID (UUID)daysLookback period in days (7-365, default: 56)/v1/ctem/portsctem:readList discovered open ports.
domain_idrequiredOrigin domain ID (UUID)pagePage numberlimitItems per page (max: 100)searchSearch by hostname or servicesource_typeFilter by scan source typeportFilter by port numberprotocoltcp / udporder_bySort: target, port, service, first_seen_at, last_seen_at/v1/ctem/techctem:readList discovered technology stack.
domain_idrequiredOrigin domain ID (UUID)pagePage numberlimitItems per page (max: 100)searchSearch by tech name or hostnamesource_typeFilter by scan source typetech_categoryFilter by categorytech_nameFilter by technology nameorder_bySort: tech_name, tech_category, target, first_seen_at, last_seen_atError Codes
| Code | HTTP | Description |
|---|---|---|
| PT_API_AUTH_INVALID | 401 | Invalid or expired API key |
| PT_API_AUTH_IP_DENIED | 403 | Request from unauthorized IP |
| PT_API_SCOPE_DENIED | 403 | Insufficient API key scope |
| PT_API_FORBIDDEN | 403 | No access to the requested resource |
| PT_API_NOT_FOUND | 404 | Resource not found |
| PT_API_ALREADY_EXISTS | 409 | Resource already exists |
| PT_API_RATE_LIMITED | 429 | Rate limit exceeded (retriable) |
| PT_API_INVALID_PARAM | 400 | Invalid parameter |
| PT_API_INVALID_STATUS | 400 | Invalid status value |
| PT_API_INVALID_CATEGORY | 400 | Invalid exclusion category |
| PT_API_INTERNAL | 500 | Internal server error (retriable) |
Rate Limiting
Each API key is limited to 100 requests per minute. Exceeding the limit returns a 429 response.
Response Headers
X-RateLimit-LimitMaximum requests per window (100)X-RateLimit-RemainingRemaining requests in current windowX-RateLimit-ResetSeconds until window resetsCorrelation ID
Every response includes a correlation_id (format: pt_<uuid>). Use this when contacting support for troubleshooting.
