EchoTrail Insights API
Programmatic access to Windows process behavior data: over 300 million real execution events from endpoint telemetry, growing every day. Query process profiles, validate parent-child relationships, analyze suspicious events, and search the dataset, over REST or as MCP tools. One key works for both.
Base URL
https://api.echotrail.ioDon't have an API key yet? Get one free for summary answers, 10 requests a minute, 500 a month, no credit card required. Team and above return the full record.
Authentication
All API requests require an API key passed in the Authorization header as a Bearer token.
Authorization: Bearer et_live_xxxxxxxxxxxxxxxxxxxxxxxxAll keys use the et_live_ prefix. You can identify a key by its first 11 characters (e.g. et_live_abc) which are shown in the dashboard. The full key is only visible at creation time.
Keys are created and managed in the Developer Dashboard. Store them securely. You can only view the full key at creation time.
MCP Quickstart
EchoTrail Insights implements the Model Context Protocol (MCP), so Claude, Codex, Cursor, or any MCP client can query process data directly. The MCP endpoint speaks JSON-RPC 2.0 over HTTP, using the same API key authentication as the REST API.
MCP Endpoint
https://api.echotrail.io/mcpOnly tools/call requests count against your monthly quota. Protocol methods (initialize, ping, tools/list) are free.
Connect a client
Claude Code
One command:
claude mcp add --transport http echotrail https://api.echotrail.io/mcp \
--header "Authorization: Bearer YOUR_API_KEY"Or add to your project's .mcp.json (the transport type is http; an entry with a URL and no type is skipped):
{
"mcpServers": {
"echotrail": {
"type": "http",
"url": "https://api.echotrail.io/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}Claude Desktop
claude_desktop_config.json starts local servers, so connect through the mcp-remote bridge (needs Node.js), which sends your key as the Authorization header. Open Settings, Developer, Edit Config, and add:
{
"mcpServers": {
"echotrail": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://api.echotrail.io/mcp",
"--header", "Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer YOUR_API_KEY"
}
}
}
}The header value goes through env because Claude Desktop splits an argument on spaces. Custom connectors (Settings, Connectors, Add custom connector) authenticate with OAuth, which this server does not use; the bridge is the supported path for an API key.
Codex CLI
Add to ~/.codex/config.toml:
[mcp_servers.echotrail]
url = "https://api.echotrail.io/mcp"
http_headers = { "Authorization" = "Bearer YOUR_API_KEY" }Cursor
Add to your project's .cursor/mcp.json:
{
"mcpServers": {
"echotrail": {
"url": "https://api.echotrail.io/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}Tool Reference
The MCP server exposes 8 tools. Which tools are available depends on your tier; use tools/list to see what's available for your key.
lookup_processFree (summary)Get comprehensive behavioral profile for a Windows process. Same data as GET /v1/process/{name}.
Input
{ "process_name": "svchost.exe" }lookup_hashTeam+Look up a file hash (SHA-256 or MD5) to find associated filenames and execution counts.
Input
{ "hash_value": "a1b2c3d4..." }MCP-only. There is no REST route for this tool.
check_parent_childFree (summary)Validate whether a parent-child process relationship has been observed in the dataset. Same data as GET /v1/parent-child.
Input
{ "parent": "services.exe", "child": "svchost.exe" }analyze_pathTeam+Check whether a process has been observed running from a specific file path.
Input
{
"process_name": "svchost.exe",
"file_path": "c:\\windows\\system32\\svchost.exe"
}MCP-only. There is no REST route for this tool.
get_prevalenceTeam+Get the prevalence (execution count) for a process.
Input
{ "process_name": "svchost.exe" }MCP-only. There is no REST route for this tool.
check_process_treeTeam+Assess the normalcy of a three-level process chain. Same data as GET /v1/tree.
Input
{
"grandparent": "wininit.exe",
"parent": "services.exe",
"child": "svchost.exe"
}analyze_eventTeam+Composite event analysis with 0-10 risk scoring. Same data as POST /v1/analyze.
Input
{
"process_name": "powershell.exe",
"parent_process": "excel.exe",
"file_path": "c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe"
}search_processesTeam+Semantic search across Windows processes using natural language. Same data as GET /v1/search.
Input
{ "query": "remote administration tools", "limit": 5 }Response shapes
The two free endpoints (/v1/process and /v1/parent-child, and the matching lookup_process and check_parent_child tools) have two shapes. The free tier returns a summary: enough to answer “is this known, and is this normal?”. Team and above return the full record. Every other endpoint and tool is Team and above and has one shape. The examples below are GET /v1/process/putty.exe and the lookup_process tool, which share a shape; every value is the current API output for that process. The data is one dataset,over 300 million process executions observed in the wild, growing every day.
Free · summary
{
"name": "putty.exe",
"known": true,
"category": "Remote Access",
"publisher": "Simon Tatham (Open Source)",
"description": "PuTTY SSH/Telnet client.",
"most_common_parent": {
"name": "explorer.exe",
"share_pct": 81.69,
"verdict": "normal"
},
"full_record_available": true,
"upgrade_url": "https://echotrail.io/pricing/",
"lab": {
"observed": true,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"runs": 1,
"install_source": {
"kind": "winget",
"package": "PuTTY.PuTTY",
"version": "0.84.0.0"
},
"publisher": "Simon Tatham",
"signature_status": "Valid",
"persistence": {
"present": false,
"kinds": [],
"by_kind": {}
},
"network": {
"present": true,
"destinations": 1
},
"counts": {
"command_lines": {
"distinct": 2,
"raw": 2
},
"dll_loads": {
"distinct": 53,
"raw": 89
},
"registry_writes": {
"distinct": 3,
"raw": 15
},
"file_writes": {
"distinct": 2,
"raw": 2
},
"dns": {
"distinct": 1,
"raw": 1
},
"driver_loads": {
"distinct": 0,
"raw": 0
},
"pipes": {
"distinct": 0,
"raw": 0
},
"wmi": {
"distinct": 0,
"raw": 0
},
"remote_threads": {
"distinct": 0,
"raw": 0
},
"raw_access": {
"distinct": 0,
"raw": 0
},
"tampering": {
"distinct": 0,
"raw": 0
},
"process_access": {
"distinct": 0,
"raw": 0
},
"powershell": {
"distinct": 0,
"raw": 0
},
"security_events": {
"distinct": 0,
"raw": 0
},
"http": {
"distinct": 0,
"raw": 0
},
"tls": {
"distinct": 0,
"raw": 0
}
}
}
}Team and above · full record
Rows observed in the lab carry windows_build, observed_at, and lab_count; count and percentage come from executions observed in the wild. Lists are cut to three entries for display.
{
"process_name": "putty.exe",
"description": "PuTTY SSH/Telnet client. Popular open-source terminal emulator for remote access. Also used for SSH tunneling, serial console access, and secure file transfer. Occasionally trojanized and distributed in supply chain attacks.",
"intel": {
"normal_behavior": "Runs from wherever installed (typically Program Files or user download location). Interactive GUI application for SSH/Telnet connections. Used by IT admins and developers for remote system management.",
"suspicious_indicators": "PuTTY connecting to unusual external IPs. Running from temp directories or unusual paths. Port forwarding enabled. Running as a background process without UI. Trojanized versions — verify hash against official releases.",
"abuse_patterns": "1. TUNNELING: Same SSH tunneling capabilities as ssh.exe for C2 and data exfiltration.\n2. TROJANIZED DISTRIBUTION: North Korean threat actors (Lazarus) have distributed trojanized PuTTY installers as part of Operation Dream Job, targeting security researchers and developers.\n3. CREDENTIAL HARVESTING: PuTTY stores session configurations in the registry (HKCU\\Software\\SimonTatham\\PuTTY) including saved sessions with hostnames — useful for attackers mapping infrastructure.",
"detection_guidance": "MEDIUM-CONFIDENCE:\n- PuTTY with port forwarding configurations\n- PuTTY connecting to external IPs outside normal admin patterns\n- PuTTY hash not matching official release hashes (trojanized)\n- PuTTY running from temp/download directories\n\nDATA SOURCES: Process creation (Sysmon 1), network connections (Sysmon 3), registry access for saved sessions",
"false_positive_notes": "Extremely common among IT administrators and developers. Many organizations standardize on PuTTY for SSH access to Linux systems.",
"mitre_techniques": [
"T1021.004",
"T1572",
"T1048"
],
"references": [
"https://attack.mitre.org/techniques/T1021/004/"
]
},
"classification": {
"category": "Remote Access",
"publisher": "Simon Tatham (Open Source)",
"is_lolbin": false,
"risk_level": "medium",
"expected_parent": "explorer.exe (user launch).",
"related_processes": [
"ssh.exe",
"plink.exe",
"pscp.exe"
]
},
"executions": {
"total": 4545
},
"parents": {
"total": 4545,
"top": [
{
"name": "explorer.exe",
"count": 3713,
"percentage": 81.6942
},
{
"name": "putty.exe",
"count": 628,
"percentage": 13.8174
},
{
"name": "RuntimeBroker.exe",
"count": 62,
"percentage": 1.3641
}
]
},
"children": {
"top": [
{
"name": "putty.exe",
"count": 81
},
{
"name": "PUTTY.EXE",
"count": 6
}
]
},
"grandparents": {
"top": [
{
"name": "userinit.exe",
"count": 2683
},
{
"name": "explorer.exe",
"count": 347
},
{
"name": "putty.exe",
"count": 226
}
]
},
"paths": {
"total": 585,
"top": [
{
"path": "C:\\Program Files\\PuTTY",
"count": 364,
"percentage": 62.2222,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"lab_count": 2
},
{
"path": "C:\\Program Files (x86)\\PuTTY",
"count": 118,
"percentage": 20.1709
},
{
"path": "C:\\Users\\...",
"count": 85,
"percentage": 14.5299
}
]
},
"hashes": {
"top": [
{
"sha256": "4119bec97bcf2a736f7769d22dc745d8a398a278bd403e53ec2dd2dd0217a6ae",
"count": null,
"percentage": null,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"lab_count": 2
}
]
},
"command_lines": [
{
"pattern": "\"C:\\Program Files\\PuTTY\\putty.exe\"",
"count": 1,
"example": "\"C:\\Program Files\\PuTTY\\putty.exe\" ",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "\"C:\\Program Files\\PuTTY\\putty.exe\" -ssh -P 22 git@github.com",
"count": 1,
"example": "\"C:\\Program Files\\PuTTY\\putty.exe\" -ssh -P 22 git@github.com ",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"dll_loads": [
{
"pattern": "C:\\Windows\\System32\\msvcrt.dll",
"signer": "Microsoft Windows",
"signature_status": "Valid",
"unsigned": false,
"system_path": true,
"count": 4,
"example": "C:\\Windows\\System32\\msvcrt.dll",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "C:\\Windows\\WinSxS\\<hash>\\comctl32.dll",
"signer": "Microsoft Windows",
"signature_status": "Valid",
"unsigned": false,
"system_path": true,
"count": 4,
"example": "C:\\Windows\\WinSxS\\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.26100.9278_none_3e0d1ba8e3303201\\comctl32.dll",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "C:\\Windows\\System32\\kernel32.dll",
"signer": "Microsoft Windows",
"signature_status": "Valid",
"unsigned": false,
"system_path": true,
"count": 2,
"example": "C:\\Windows\\System32\\kernel32.dll",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"network": [
{
"dst": "140.82.112.3",
"ip": "140.82.112.3",
"port": 22,
"proto": "tcp",
"count": 1,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"dns": [
{
"query": "github.com",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"count": 1
}
],
"registry_writes": [
{
"pattern": "HKLM\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
"value": null,
"operation": "CreateKey",
"noise": true,
"count": 7,
"example": "HKLM\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Notifications\\Data",
"value": "<hex>",
"operation": "SetValue",
"noise": true,
"count": 6,
"example": "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Notifications\\Data",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "HKLM\\System\\CurrentControlSet\\Services\\bam\\State\\UserSettings\\<sid>\\\\Device\\HarddiskVolume3\\Program Files\\PuTTY",
"value": "putty.exe",
"operation": "SetValue",
"noise": true,
"count": 2,
"example": "HKLM\\System\\CurrentControlSet\\Services\\bam\\State\\UserSettings\\S-1-5-21-2242041204-3472126950-1025570065-1002\\\\Device\\HarddiskVolume3\\Program Files\\PuTTY",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"file_writes": [
{
"pattern": "C:\\Users\\<user>\\AppData\\Local\\PUTTY.RND",
"operation": "create",
"noise": false,
"count": 1,
"example": "C:\\Users\\lab\\AppData\\Local\\PUTTY.RND",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "C:\\Users\\<user>\\AppData\\Local\\PUTTY.RND",
"operation": "delete",
"noise": false,
"count": 1,
"example": "C:\\Users\\lab\\AppData\\Local\\PUTTY.RND",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"autoruns": [],
"driver_loads": [],
"pipes": [],
"wmi": [],
"remote_threads": [],
"raw_access": [],
"tampering": [],
"process_access": [],
"powershell": [],
"security_events": [],
"http": [],
"tls": [],
"lab_totals": {
"command_lines": {
"distinct": 2,
"raw": 2
},
"dll_loads": {
"distinct": 53,
"raw": 89
},
"registry_writes": {
"distinct": 3,
"raw": 15
},
"file_writes": {
"distinct": 2,
"raw": 2
},
"network": {
"distinct": 1,
"raw": 1
},
"dns": {
"distinct": 1,
"raw": 1
},
"autoruns": {
"distinct": 0,
"raw": 0
},
"network_destinations": 1,
"driver_loads": {
"distinct": 0,
"raw": 0
},
"pipes": {
"distinct": 0,
"raw": 0
},
"wmi": {
"distinct": 0,
"raw": 0
},
"remote_threads": {
"distinct": 0,
"raw": 0
},
"raw_access": {
"distinct": 0,
"raw": 0
},
"tampering": {
"distinct": 0,
"raw": 0
},
"process_access": {
"distinct": 0,
"raw": 0
},
"powershell": {
"distinct": 0,
"raw": 0
},
"security_events": {
"distinct": 0,
"raw": 0
},
"http": {
"distinct": 0,
"raw": 0
},
"tls": {
"distinct": 0,
"raw": 0
}
},
"lab_runs": [
{
"run_id": 19,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"install_source": {
"kind": "winget",
"package": "PuTTY.PuTTY",
"version": "0.84.0.0"
},
"installer_signer": "Simon Tatham",
"installer_signature_status": "Valid",
"install_status": "ok"
}
],
"lab": {
"observed": true,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"runs": 1,
"install_source": {
"kind": "winget",
"package": "PuTTY.PuTTY",
"version": "0.84.0.0"
},
"publisher": "Simon Tatham",
"signature_status": "Valid",
"persistence": {
"present": false,
"kinds": [],
"by_kind": {}
},
"network": {
"present": true,
"destinations": 1
},
"counts": {
"command_lines": {
"distinct": 2,
"raw": 2
},
"dll_loads": {
"distinct": 53,
"raw": 89
},
"registry_writes": {
"distinct": 3,
"raw": 15
},
"file_writes": {
"distinct": 2,
"raw": 2
},
"dns": {
"distinct": 1,
"raw": 1
},
"driver_loads": {
"distinct": 0,
"raw": 0
},
"pipes": {
"distinct": 0,
"raw": 0
},
"wmi": {
"distinct": 0,
"raw": 0
},
"remote_threads": {
"distinct": 0,
"raw": 0
},
"raw_access": {
"distinct": 0,
"raw": 0
},
"tampering": {
"distinct": 0,
"raw": 0
},
"process_access": {
"distinct": 0,
"raw": 0
},
"powershell": {
"distinct": 0,
"raw": 0
},
"security_events": {
"distinct": 0,
"raw": 0
},
"http": {
"distinct": 0,
"raw": 0
},
"tls": {
"distinct": 0,
"raw": 0
}
}
},
"lab_observed_with": [
"pageant.exe",
"plink.exe",
"pscp.exe"
]
}Team and above · lab-only lists on the full record
On the full record for every process with a lab record. Lists are patterns: volatile tokens (GUIDs, handles, PIDs, hashes, temp names, user dirs, version dirs) collapsed, deduped and counted, top 25 with one raw example each; lab_totals gives distinct vs raw. The free tier gets the lab summary block on the summary shape.
{
"command_lines": "[{ pattern, count, example, windows_build, observed_at }] // top 25 patterns by count",
"dll_loads": "[{ pattern, count, example, signer, signature_status, unsigned, system_path, ... }] // unsigned or non-system first",
"driver_loads": "[{ pattern, count, example, signer, signature_status, unsigned, system_path, ... }]",
"registry_writes": "[{ pattern, value, operation, count, example, noise, ... }] // app-specific first, Windows noise last",
"file_writes": "[{ pattern, operation, count, example, noise, ... }]",
"network": "[{ dst, ip, port, proto, count, ... }] // host+port, by connections",
"dns": "[{ query, count, ... }]",
"http": "[{ method, host, path, user_agent, status, content_type, count, example, ... }] // from the lab bridge pcap",
"tls": "[{ sni, ja4, cipher, tls_version, cert_subject, cert_issuer, count, ... }]",
"pipes": "[{ pattern, event: \"created\" | \"connected\", count, example, ... }]",
"process_access": "[{ target, granted_access, sensitive, count, example (call trace), ... }] // lsass/csrss/winlogon/services + the package",
"remote_threads": "[{ target, start_module, start_function, count, ... }]",
"raw_access": "[{ pattern (device), count, ... }]",
"tampering": "[{ pattern (type), count, ... }]",
"wmi": "[{ event_type, operation, name, query, consumer_type, destination, count, ... }]",
"powershell": "[{ sha256, path, event_id, excerpt, length, count, ... }] // script blocks the package ran",
"security_events": "[{ event_id, channel, pattern, token_elevation, count, ... }] // 4688, 4624, 4698, 7045",
"autoruns": "[{ kind, name, location, command, ... }]",
"lab_totals": "{ <list>: { distinct, raw } for every list above, network_destinations }",
"lab_runs": "[{ run_id, windows_build, observed_at, install_source: { kind, package, version }, installer_signer, installer_signature_status, install_status }]"
}Gated endpoint on the free tier
{
"error": {
"code": "forbidden",
"message": "This endpoint requires 'team' tier or higher (current: 'free')",
"required_tier": "team",
"current_tier": "free",
"upgrade_url": "https://echotrail.io/pricing/",
"what_you_get": "Full records: parent-child trees, prevalence, hash and path analysis, and the written guidance, plus lab observations as they ship. All endpoints and MCP tools."
}
}Process not in the data
Same miss over MCP: lookup_process returns a normal result { name, known: false, queued_for_lab: true, notify_url, note } so agents can reason about it. Either way the name is queued for the lab, and POST /v1/notify registers your interest in it.
{
"error": {
"code": "not_found",
"message": "No data for process: updater_helper.exe",
"name": "updater_helper.exe",
"queued_for_lab": true,
"notify_url": "https://api.echotrail.io/v1/notify/updater_helper.exe"
}
}List caps and denominators
parents.top, children.top, grandparents.top,paths.top, and hashes.top hold the top 10 rows by count.parents.total and paths.total are the sums over all rows for the process, not just the ten shown, and are the denominators of the percentages on those rows; they can be lower than executions.total because not every execution recorded a parent or a path. Each lab list on the full record holds the top 25 patterns by count; lab_totals.<list>.distinctis how many patterns there were before the cap and .raw how many raw events they collapse. Rows past a cap are not retrievable through the API.
Tables, fields, and counts are on The Data.
REST API Reference
All endpoints return JSON. Successful responses use HTTP 200. Errors use the appropriate HTTP status code with a standard error object.
/v1/process/{name}Free (summary)Get the behavioral profile for a Windows process, including execution count, common parent/child relationships, typical file paths, threat intel, and classification data.
| Parameter | Type | In | Description |
|---|---|---|---|
| name* | string | path | Process filename, e.g. svchost.exe |
Response
Team and above (full record, lists cut to the top three for display; empty fields hidden). Free returns the summary shown under Response shapes.
{
"process_name": "putty.exe",
"description": "PuTTY SSH/Telnet client. Popular open-source terminal emulator for remote access. Also used for SSH tunneling, serial console access, and secure file transfer. Occasionally trojanized and distributed in supply chain attacks.",
"intel": {
"normal_behavior": "Runs from wherever installed (typically Program Files or user download location). Interactive GUI application for SSH/Telnet connections. Used by IT admins and developers for remote system management.",
"suspicious_indicators": "PuTTY connecting to unusual external IPs. Running from temp directories or unusual paths. Port forwarding enabled. Running as a background process without UI. Trojanized versions — verify hash against official releases.",
"abuse_patterns": "1. TUNNELING: Same SSH tunneling capabilities as ssh.exe for C2 and data exfiltration.\n2. TROJANIZED DISTRIBUTION: North Korean threat actors (Lazarus) have distributed trojanized PuTTY installers as part of Operation Dream Job, targeting security researchers and developers.\n3. CREDENTIAL HARVESTING: PuTTY stores session configurations in the registry (HKCU\\Software\\SimonTatham\\PuTTY) including saved sessions with hostnames — useful for attackers mapping infrastructure.",
"detection_guidance": "MEDIUM-CONFIDENCE:\n- PuTTY with port forwarding configurations\n- PuTTY connecting to external IPs outside normal admin patterns\n- PuTTY hash not matching official release hashes (trojanized)\n- PuTTY running from temp/download directories\n\nDATA SOURCES: Process creation (Sysmon 1), network connections (Sysmon 3), registry access for saved sessions",
"false_positive_notes": "Extremely common among IT administrators and developers. Many organizations standardize on PuTTY for SSH access to Linux systems.",
"mitre_techniques": [
"T1021.004",
"T1572",
"T1048"
],
"references": [
"https://attack.mitre.org/techniques/T1021/004/"
]
},
"classification": {
"category": "Remote Access",
"publisher": "Simon Tatham (Open Source)",
"is_lolbin": false,
"risk_level": "medium",
"expected_parent": "explorer.exe (user launch).",
"related_processes": [
"ssh.exe",
"plink.exe",
"pscp.exe"
]
},
"executions": {
"total": 4545
},
"parents": {
"total": 4545,
"top": [
{
"name": "explorer.exe",
"count": 3713,
"percentage": 81.6942
},
{
"name": "putty.exe",
"count": 628,
"percentage": 13.8174
},
{
"name": "RuntimeBroker.exe",
"count": 62,
"percentage": 1.3641
}
]
},
"children": {
"top": [
{
"name": "putty.exe",
"count": 81
},
{
"name": "PUTTY.EXE",
"count": 6
}
]
},
"grandparents": {
"top": [
{
"name": "userinit.exe",
"count": 2683
},
{
"name": "explorer.exe",
"count": 347
},
{
"name": "putty.exe",
"count": 226
}
]
},
"paths": {
"total": 585,
"top": [
{
"path": "C:\\Program Files\\PuTTY",
"count": 364,
"percentage": 62.2222,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"lab_count": 2
},
{
"path": "C:\\Program Files (x86)\\PuTTY",
"count": 118,
"percentage": 20.1709
},
{
"path": "C:\\Users\\...",
"count": 85,
"percentage": 14.5299
}
]
},
"hashes": {
"top": [
{
"sha256": "4119bec97bcf2a736f7769d22dc745d8a398a278bd403e53ec2dd2dd0217a6ae",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"lab_count": 2
}
]
},
"command_lines": [
{
"pattern": "\"C:\\Program Files\\PuTTY\\putty.exe\"",
"count": 1,
"example": "\"C:\\Program Files\\PuTTY\\putty.exe\" ",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "\"C:\\Program Files\\PuTTY\\putty.exe\" -ssh -P 22 git@github.com",
"count": 1,
"example": "\"C:\\Program Files\\PuTTY\\putty.exe\" -ssh -P 22 git@github.com ",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"dll_loads": [
{
"pattern": "C:\\Windows\\System32\\msvcrt.dll",
"signer": "Microsoft Windows",
"signature_status": "Valid",
"unsigned": false,
"system_path": true,
"count": 4,
"example": "C:\\Windows\\System32\\msvcrt.dll",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "C:\\Windows\\WinSxS\\<hash>\\comctl32.dll",
"signer": "Microsoft Windows",
"signature_status": "Valid",
"unsigned": false,
"system_path": true,
"count": 4,
"example": "C:\\Windows\\WinSxS\\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.26100.9278_none_3e0d1ba8e3303201\\comctl32.dll",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "C:\\Windows\\System32\\kernel32.dll",
"signer": "Microsoft Windows",
"signature_status": "Valid",
"unsigned": false,
"system_path": true,
"count": 2,
"example": "C:\\Windows\\System32\\kernel32.dll",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"network": [
{
"dst": "140.82.112.3",
"ip": "140.82.112.3",
"port": 22,
"proto": "tcp",
"count": 1,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"dns": [
{
"query": "github.com",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"count": 1
}
],
"registry_writes": [
{
"pattern": "HKLM\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
"operation": "CreateKey",
"noise": true,
"count": 7,
"example": "HKLM\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Notifications\\Data",
"value": "<hex>",
"operation": "SetValue",
"noise": true,
"count": 6,
"example": "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Notifications\\Data",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "HKLM\\System\\CurrentControlSet\\Services\\bam\\State\\UserSettings\\<sid>\\\\Device\\HarddiskVolume3\\Program Files\\PuTTY",
"value": "putty.exe",
"operation": "SetValue",
"noise": true,
"count": 2,
"example": "HKLM\\System\\CurrentControlSet\\Services\\bam\\State\\UserSettings\\S-1-5-21-2242041204-3472126950-1025570065-1002\\\\Device\\HarddiskVolume3\\Program Files\\PuTTY",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"file_writes": [
{
"pattern": "C:\\Users\\<user>\\AppData\\Local\\PUTTY.RND",
"operation": "create",
"noise": false,
"count": 1,
"example": "C:\\Users\\lab\\AppData\\Local\\PUTTY.RND",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
},
{
"pattern": "C:\\Users\\<user>\\AppData\\Local\\PUTTY.RND",
"operation": "delete",
"noise": false,
"count": 1,
"example": "C:\\Users\\lab\\AppData\\Local\\PUTTY.RND",
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
],
"lab_totals": {
"command_lines": {
"distinct": 2,
"raw": 2
},
"dll_loads": {
"distinct": 53,
"raw": 89
},
"registry_writes": {
"distinct": 3,
"raw": 15
},
"file_writes": {
"distinct": 2,
"raw": 2
},
"network": {
"distinct": 1,
"raw": 1
},
"dns": {
"distinct": 1,
"raw": 1
},
"autoruns": {
"distinct": 0,
"raw": 0
},
"network_destinations": 1,
"driver_loads": {
"distinct": 0,
"raw": 0
},
"pipes": {
"distinct": 0,
"raw": 0
},
"wmi": {
"distinct": 0,
"raw": 0
},
"remote_threads": {
"distinct": 0,
"raw": 0
},
"raw_access": {
"distinct": 0,
"raw": 0
},
"tampering": {
"distinct": 0,
"raw": 0
},
"process_access": {
"distinct": 0,
"raw": 0
},
"powershell": {
"distinct": 0,
"raw": 0
},
"security_events": {
"distinct": 0,
"raw": 0
},
"http": {
"distinct": 0,
"raw": 0
},
"tls": {
"distinct": 0,
"raw": 0
}
},
"lab_runs": [
{
"run_id": 19,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"install_source": {
"kind": "winget",
"package": "PuTTY.PuTTY",
"version": "0.84.0.0"
},
"installer_signer": "Simon Tatham",
"installer_signature_status": "Valid",
"install_status": "ok"
}
],
"lab": {
"observed": true,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00",
"runs": 1,
"install_source": {
"kind": "winget",
"package": "PuTTY.PuTTY",
"version": "0.84.0.0"
},
"publisher": "Simon Tatham",
"signature_status": "Valid",
"persistence": {
"present": false,
"by_kind": {}
},
"network": {
"present": true,
"destinations": 1
},
"counts": {
"command_lines": {
"distinct": 2,
"raw": 2
},
"dll_loads": {
"distinct": 53,
"raw": 89
},
"registry_writes": {
"distinct": 3,
"raw": 15
},
"file_writes": {
"distinct": 2,
"raw": 2
},
"dns": {
"distinct": 1,
"raw": 1
},
"driver_loads": {
"distinct": 0,
"raw": 0
},
"pipes": {
"distinct": 0,
"raw": 0
},
"wmi": {
"distinct": 0,
"raw": 0
},
"remote_threads": {
"distinct": 0,
"raw": 0
},
"raw_access": {
"distinct": 0,
"raw": 0
},
"tampering": {
"distinct": 0,
"raw": 0
},
"process_access": {
"distinct": 0,
"raw": 0
},
"powershell": {
"distinct": 0,
"raw": 0
},
"security_events": {
"distinct": 0,
"raw": 0
},
"http": {
"distinct": 0,
"raw": 0
},
"tls": {
"distinct": 0,
"raw": 0
}
}
},
"lab_observed_with": [
"pageant.exe",
"plink.exe",
"pscp.exe"
]
}Examples
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.echotrail.io/v1/process/svchost.exe/v1/parent-childFree (summary)Check whether a specific parent-child process relationship has been observed. Free returns the verdict: whether the pair was seen, a verdict (normal, uncommon, rare, never_observed), and the share of the child's executions. Team and above return the count, the denominator, the percentage, and the child's most common parents for comparison.
| Parameter | Type | In | Description |
|---|---|---|---|
| parent* | string | query | Parent process filename, e.g. services.exe |
| child* | string | query | Child process filename, e.g. svchost.exe |
Response
{
"parent": "services.exe",
"child": "svchost.exe",
"observed": true,
"verdict": "normal",
"share_pct": 99.66,
"full_record_available": true,
"upgrade_url": "https://echotrail.io/pricing/"
}Examples
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.echotrail.io/v1/parent-child?parent=services.exe&child=svchost.exe"/v1/treeTeam+Assess the normalcy of a three-level process chain (grandparent → parent → child). Returns whether the chain has been observed and an overall assessment.
| Parameter | Type | In | Description |
|---|---|---|---|
| grandparent* | string | query | Grandparent process filename |
| parent* | string | query | Parent process filename |
| child* | string | query | Child process filename |
Response
{
"grandparent": "services.exe",
"parent": "svchost.exe",
"child": "rundll32.exe",
"link1": { "parent": "services.exe", "child": "svchost.exe", "observed": true, "percentage": 99.6556 },
"link2": { "parent": "svchost.exe", "child": "rundll32.exe", "observed": true, "percentage": 46.4428 },
"assessment": "expected"
}Examples
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.echotrail.io/v1/tree?grandparent=wininit.exe&parent=services.exe&child=svchost.exe"/v1/analyzeTeam+Composite event analysis with risk scoring. Provide as much context as you have. Process name is required, but adding parent, path, command line, or hash improves the assessment. Every field must be a string; sha256 must be 64 hex characters (anything else is a 400, never a risk signal).
| Parameter | Type | In | Description |
|---|---|---|---|
| process_name* | string | body | Windows process filename |
| parent_process | string | body | Parent process filename |
| grandparent_process | string | body | Grandparent process filename; evaluated only with parent_process (otherwise listed under evidence.ignored) |
| file_path | string | body | Full file path on disk |
| command_line | string | body | Full command line string |
| sha256 | string | body | SHA-256 hash (64 hex chars) |
Response
The current API output for the request below; lists cut to three entries for display. Each signal carries its score and its weight in the 0 to 10 total. known says whether the process is in the data; when it is not, assessment isunknown (absence of data is not evidence of normal behavior) and the score has no baseline. evidence lists the signals evaluated, the optional inputs you did not send, and inputs that were sent but not evaluated. The hash signal counts a hash the behavior lab observed as recognized. Under underlying_data.path,total_executions is the sum of the path rows for the process (the denominator of the percentage), which can be lower than the process's execution total.
{
"process_name": "powershell.exe",
"known": true,
"score": 2.5,
"assessment": "uncommon",
"signals": [
{
"signal": "prevalence",
"score": 0,
"max_weight": 1.0
},
{
"signal": "parent_child",
"score": 2.5,
"max_weight": 3.0
},
{
"signal": "path",
"score": 0,
"max_weight": 2.0
}
],
"underlying_data": {
"prevalence": {
"process_name": "powershell.exe",
"total_executions": 9261865
},
"parent_child": {
"parent": "excel.exe",
"child": "powershell.exe",
"observed": true,
"count": 8,
"total_child_executions": 9261860,
"percentage": 8.637573878249078e-05,
"common_parents": [
{
"name": "cmd.exe",
"count": 7185092
},
{
"name": "jumpcloud-agent.exe",
"count": 1283463
},
{
"name": "platform-scripting-plugin.exe",
"count": 211725
}
]
},
"path": {
"filename": "powershell.exe",
"path": "c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe",
"observed": true,
"count": 9086223,
"total_executions": 9261865,
"percentage": 98.10360008486411,
"common_paths": [
{
"path": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0",
"count": 9086223
},
{
"path": "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0",
"count": 175610
},
{
"path": "C:\\Windows\\syswow64\\WindowsPowerShell\\v1.0",
"count": 32
}
]
}
},
"evidence": {
"evaluated": [
"prevalence",
"parent_child",
"path"
],
"missing": [
"grandparent_process",
"command_line",
"sha256"
],
"ignored": []
}
}Examples
curl -X POST https://api.echotrail.io/v1/analyze \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"process_name": "powershell.exe",
"parent_process": "excel.exe",
"file_path": "c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe"
}'/v1/searchTeam+Semantic search across Windows processes using natural language. Uses vector embeddings to find processes matching your description.
| Parameter | Type | In | Description |
|---|---|---|---|
| q* | string | query | Natural language search query |
| limit | integer | query | Max results, default 5. Values outside 1 to 25 are clamped; a non-integer is a 400 |
Response
{
"query": "remote administration tools",
"results": [
{
"process_name": "repadmin.exe",
"description": "Filename: repadmin.exe\nDescription: Active Directory Replication Administration tool - diagnoses and troublesh...",
"similarity": 0.4562
},
{
"process_name": "psexec.exe",
"description": "Filename: psexec.exe\nDescription: psexec.exe is part of the SysInternals suite of tools developed by Microsoft...",
"similarity": 0.4438
}
],
"count": 2
}Examples
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.echotrail.io/v1/search?q=remote%20administration%20tools&limit=5"/v1/bulk/processesTeam+Look up multiple process names in a single request. One call counts as one request against your quota, whatever the array size; up to 100 names are looked up and any past 100 are dropped (requested says how many were). Every item must be a non-empty string, or the call is a 400 naming the index and nothing is looked up.
| Parameter | Type | In | Description |
|---|---|---|---|
| processes* | string[] | body | Array of process filenames (1 to 100) |
Response
One item per name, in request order. data is exactly theGET /v1/process record for that name (same serialization, includinglab_observed_with and the name-link fields) when found, null when not. Names not found are queued for the lab like a single lookup.
{
"results": [
{
"process_name": "svchost.exe",
"status": "found",
"data": { ...the full /v1/process record for svchost.exe... }
},
{
"process_name": "notarealprocess.exe",
"status": "not_found",
"data": null
}
],
"requested": 2,
"found": 1,
"not_found": 1
}Examples
curl -X POST https://api.echotrail.io/v1/bulk/processes \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"processes": ["svchost.exe", "lsass.exe", "csrss.exe"]}'/v1/bulk/hashesTeam+Look up multiple file hashes (SHA-256 or MD5) in a single request. One call counts as one request against your quota; up to 100 hashes are looked up and any past 100 are dropped. Every item must be 64 or 32 hex characters, or the call is a 400 naming the index.
| Parameter | Type | In | Description |
|---|---|---|---|
| hashes* | string[] | body | Array of SHA-256 (64 hex) or MD5 (32 hex) hashes (1 to 100) |
Response
One item per hash, in request order; data lists the filenames the hash ran as,null when neither the field data nor the behavior lab has seen it. A filename row observed in the wild carries count; one the lab observed carrieslab_count, windows_build, and observed_at and a nullcount; total_executions is field prevalence only (0 for a hash only the lab has seen). Same tool result from lookup_hash.
{
"results": [
{
"hash": "4119bec97bcf2a736f7769d22dc745d8a398a278bd403e53ec2dd2dd0217a6ae",
"status": "found",
"data": {
"sha256": "4119bec97bcf2a736f7769d22dc745d8a398a278bd403e53ec2dd2dd0217a6ae",
"total_executions": 0,
"filenames": [
{
"name": "putty.exe",
"count": null,
"lab_count": 2,
"windows_build": "Windows 11 Enterprise Evaluation 24H2 26100.9445",
"observed_at": "2026-09-10T01:34:03.679371+00:00"
}
]
}
},
{
"hash": "b868487f8edbd0571d30d89573f087bfeac3da190652344afd351b1868ea0f8b",
"status": "found",
"data": {
"sha256": "b868487f8edbd0571d30d89573f087bfeac3da190652344afd351b1868ea0f8b",
"total_executions": 1885424,
"filenames": [
{
"name": "svchost.exe",
"count": 1885424
}
]
}
}
],
"requested": 2,
"found": 2,
"not_found": 0
}Examples
curl -X POST https://api.echotrail.io/v1/bulk/hashes \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"hashes": ["a1b2c3d4e5f6..."]}'/v1/notify/{name}All tiersRegister your organization's interest in a process name the data does not have yet. A 404 from GET /v1/process carries this URL as notify_url, and the MCPlookup_process result carries it next to known: false. It only registers interest: the name is already queued for the behavior lab by the miss itself, and nothing is sent to you when it lands. Bearer key, no body, GET is a 404. Idempotent.
| Parameter | Type | In | Description |
|---|---|---|---|
| name* | string | path | Process filename, e.g. updater_helper.exe |
Response
{
"ok": true,
"name": "updater_helper.exe",
"registered": true,
"note": "Interest in this name is registered for your organization."
}Example
curl -X POST -H "Authorization: Bearer YOUR_API_KEY" \
https://api.echotrail.io/v1/notify/updater_helper.exeQuotas & Rate Limits
Each API tier has a monthly request quota and a per-minute burst limit. Both REST and MCP tools/call requests count against your quota.
What counts
A request counts against the monthly quota when the API did the work: every 2xx, and a lookup that found nothing (404 not_found with queued_for_lab, or an MCP result with known: false). A bulk call counts once, whatever its array size. Requests the API rejected or failed do not count: 400 invalid input, 401, 403 tier gate, 404 unknown route, 429, and 5xx; on MCP, any JSON-RPC error. The per-minute burst limit is separate and counts every authenticated request, accepted or rejected, so a burst of rejections still triggers a 429.
| Tier | Monthly Quota | Burst Limit | Max Keys |
|---|---|---|---|
| Free | 500 | 10/min | 2 |
| Team | 10,000 | 60/min | 10 |
| Product | 100,000 | 300/min | 25 |
Rate-limit headers
REST: every response to an authenticated request carries these headers, except the per-minute 429 (it carries Retry-After instead). MCP: only tools/callresponses carry them; initialize, ping, and tools/list do not count and carry none, and neither does a 401. The values describe the monthly quota:
| Header | Description |
|---|---|
| X-RateLimit-Limit | Your monthly quota |
| X-RateLimit-Remaining | Requests remaining this month |
| X-RateLimit-Reset | Unix timestamp when quota resets (1st of next month) |
Two limits apply together: a per-minute rate limit and a monthly quota. Free, Team, and Product are 10, 60, and 300 requests a minute and 500, 10,000, and 100,000 a month. On REST, exceeding either returns HTTP 429 (rate_limited or quota_exceeded) with aRetry-After header. On MCP, either is HTTP 200 with JSON-RPC error -32000;error.data.error is rate_limited or quota_exceeded anderror.data.retry_after is the number of seconds to wait (also sent asRetry-After).
Tier Comparison
Which endpoints and tools you can access depends on your tier. Higher tiers include everything from lower tiers.
| Capability | Free | Team | Product+ |
|---|---|---|---|
| Response shape | summary | full | full |
| Rate limit | 10 / min | 60 / min | 300 / min |
| Monthly quota | 500 | 10,000 | 100,000 |
| GET /v1/process/{name} · lookup_process (summary on Free) | ✓ | ✓ | ✓ |
| GET /v1/parent-child · check_parent_child (summary on Free) | ✓ | ✓ | ✓ |
| lookup_hash (MCP) | no | ✓ | ✓ |
| analyze_path (MCP) | no | ✓ | ✓ |
| get_prevalence (MCP) | no | ✓ | ✓ |
| GET /v1/tree · check_process_tree | no | ✓ | ✓ |
| POST /v1/analyze · analyze_event | no | ✓ | ✓ |
| GET /v1/search · search_processes | no | ✓ | ✓ |
| POST /v1/bulk/processes (REST only) | no | ✓ | ✓ |
| POST /v1/bulk/hashes (REST only) | no | ✓ | ✓ |
| Lab summary block (build, date, install source, publisher, persistence and network yes/no, counts) | ✓ | ✓ | ✓ |
| Lab detail lists (command lines, DLLs, network, DNS, registry, files, autoruns, ...) | no | ✓ | ✓ |
| Redistribution to your own users | no | no | ✓ |
| Changelog feed | no | no | ✓ |
See Pricing for monthly costs, or upgrade from the Developer Dashboard.
Errors
Every error returns a JSON object whose error key holds a machine-readablecode and a human-readable message. Two responses carry extra fields inside error, because clients act on them: the tier gate (403 forbidden names the tier that unlocks the endpoint in required_tier and links to pricing in upgrade_url) and an unknown process (404 not_found says the name is queued; notify_url registers your interest in it). Both are shown in full under Response shapes.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key"
}
}| HTTP Status | Code | Description |
|---|---|---|
| 400 | bad_request | Missing parameters, a body that is not a JSON object, a field of the wrong type, a malformed hash, or a non-integer limit; the message names the field (and the index in a bulk array) |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | Your tier does not include this endpoint; error.required_tier names the tier that does |
| 404 | not_found | Process not in the data (error.queued_for_lab is true) or unknown route |
| 429 | rate_limited / quota_exceeded | Per-minute limit or monthly quota exceeded; Retry-After says when to try again |
| 500 | internal_error | Unexpected server error (details stay in our logs; the request is not counted) |
MCP error codes
MCP responses use JSON-RPC 2.0 error codes. The HTTP status is 200 for every JSON-RPC error except authentication: a missing or invalid key is HTTP 401 with aWWW-Authenticate: Bearer header and a -32000 error body that echoes your request id.
| Code | Meaning |
|---|---|
| -32700 | Parse error (invalid JSON) |
| -32600 | Invalid request: the body is not a single JSON-RPC object (batches are not supported) or has no method |
| -32601 | Method not found |
| -32602 | Invalid params: a required argument is missing, an argument has the wrong type, or a hash is malformed |
| -32603 | Internal error (details stay in our logs; the call is not counted) |
| -32000 | Unauthorized (HTTP 401), per-minute rate limit, or monthly quota exhausted; error.data.error and error.data.retry_after say which and when to retry |
| -32001 | Tier access denied |
Ready to get started?
Free key: summary answers, 500 requests a month. No credit card required.