API Reference
Programmatically audit WordPress plugins, query the plugin directory, and manage webhooks using the WP HealthKit REST API.
Authentication
All API requests require a Bearer token. Generate an API key in Settings → API Keys. API keys require a Pro or higher subscription.
curl https://wphealthkit.com/api/v1/usage \ -H "Authorization: Bearer whk_live_your_key"
Key format
API keys use the whk_live_ prefix. Keys are hashed server-side — the full value is shown only once at creation time. Store it securely.
Response Format
Every API response uses a consistent JSON envelope with three top-level fields.
{
"data": { ... }, // Payload — null on error
"error": null, // Error message string — null on success
"meta": {
"timestamp": "2025-04-10T12:00:00.000Z"
}
}HTTP status codes follow standard semantics: 200 success, 202 accepted (async), 401 unauthorized, 404 not found, 429 rate limited.
Rate Limits
Rate limits apply per API key per minute. Exceeding the limit returns a 429 response with a Retry-After header.
| Plan | Requests / min | Audits / month |
|---|---|---|
| Pro | 10 | 30 |
| Agency | 30 | Unlimited |
| BYOK Agency | 30 | Unlimited (your keys) |
| Enterprise | 100 | Unlimited |
Per-minute limits are enforced per API key. Monthly audit counts follow your plan's token allowance; Agency and Enterprise have unlimited Standard/Advanced audits (Premium engine tier: 50/200 per month respectively).
POST /api/v1/audit
/api/v1/auditPro+Start an asynchronous plugin audit. Accepts either a wp.org plugin slug or a ZIP file upload. Returns an audit ID to poll for results.
Parameters
slugstringoptionalwp.org plugin slug (e.g. contact-form-7)filebinaryoptionalPlugin ZIP file (multipart/form-data). Required if slug not provided.enginesarrayoptionalOptional. Extra engines to run. JSON: ["performance"]. Form field: "performance". Each optional engine costs +1 token.model_tierstringoptionalEngine tier: "standard" (default, ×1 tokens), "advanced" (×2), "premium" (×5). Multiplies the audit's base token cost.Request
# Via slug
curl -X POST https://wphealthkit.com/api/v1/audit \
-H "Authorization: Bearer whk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"slug": "contact-form-7"}'
# Via ZIP upload
curl -X POST https://wphealthkit.com/api/v1/audit \
-H "Authorization: Bearer whk_live_your_key" \
-F "[email protected]"
# With performance engine (costs 2 tokens)
curl -X POST https://wphealthkit.com/api/v1/audit \
-H "Authorization: Bearer whk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"slug":"contact-form-7","engines":["performance"]}'
# ZIP upload with performance engine
curl -X POST https://wphealthkit.com/api/v1/audit \
-H "Authorization: Bearer whk_live_your_key" \
-F "[email protected]" \
-F "engines=performance"Response
{
"data": {
"id": "aud_01j9x4r2v8kz3m7p6nq5w0c1d",
"status": "pending",
"slug": "contact-form-7",
"created_at": "2025-04-10T12:00:00.000Z"
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:00:00.000Z" }
}GET /api/v1/audit/:id
/api/v1/audit/:idPro+Poll the status and results of an audit. Status cycles through pending → processing → completed (or failed).
Parameters
idstringrequiredAudit ID returned from POST /v1/auditRequest
curl https://wphealthkit.com/api/v1/audit/aud_01j9x4r2v8kz3m7p6nq5w0c1d \ -H "Authorization: Bearer whk_live_your_key"
Response
{
"data": {
"id": "aud_01j9x4r2v8kz3m7p6nq5w0c1d",
"status": "completed",
"slug": "contact-form-7",
"plugin_name": "Contact Form 7",
"plugin_version": "5.9.8",
"overall_risk": "LOW",
"findings_count": 3,
"critical_count": 0,
"high_count": 0,
"medium_count": 2,
"low_count": 1,
"report_url": "https://wphealthkit.com/results/aud_01j9x4r2v8kz3m7p6nq5w0c1d",
"completed_at": "2025-04-10T12:01:14.000Z"
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:02:00.000Z" }
}GET /api/v1/audit/:id/findings
/api/v1/audit/:id/findingsPro+Retrieve paginated findings for a completed audit. Use page and per_page query parameters to paginate.
Parameters
idstringrequiredAudit IDpageintegeroptionalPage number (default: 1)per_pageintegeroptionalResults per page, max 100 (default: 25)severitystringoptionalFilter by severity: critical, high, medium, lowRequest
curl "https://wphealthkit.com/api/v1/audit/aud_01j9x4r2v8kz3m7p6nq5w0c1d/findings?page=1&per_page=25" \ -H "Authorization: Bearer whk_live_your_key"
Response
{
"data": {
"findings": [
{
"id": "find_abc123",
"severity": "medium",
"category": "security",
"rule": "no-direct-db-query",
"message": "Direct database query without prepared statement",
"file": "includes/class-handler.php",
"line": 142
}
],
"pagination": {
"page": 1,
"per_page": 25,
"total": 3,
"total_pages": 1
}
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:02:00.000Z" }
}GET /api/v1/audit/:id/fix-prompt
/api/v1/audit/:id/fix-promptPro+Retrieve a batched AI fix prompt for the audit findings. Suitable for passing directly to an LLM to generate fixes.
Parameters
idstringrequiredAudit IDbatchintegeroptionalBatch index for large audits (default: 0)Request
curl https://wphealthkit.com/api/v1/audit/aud_01j9x4r2v8kz3m7p6nq5w0c1d/fix-prompt \ -H "Authorization: Bearer whk_live_your_key"
Response
{
"data": {
"prompt": "You are a WordPress security expert. Fix the following issues in this plugin...",
"findings_included": 3,
"batch": 0,
"total_batches": 1
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:02:00.000Z" }
}GET /api/v1/telemetry/:slug/stats
Pull telemetry data for plugins you own into a custom dashboard. Requires that the authenticated API key owns the plugin via a verified claim or that the key is scoped to this slug.
/api/v1/telemetry/:slug/statsPro+Aggregated telemetry statistics for a plugin you own. Returns active install counts, version distribution, environment breakdowns, and a daily trend series.
Parameters
slugstringrequiredwp.org plugin slug. Must be owned by the authenticated API key.periodstringoptionalTime window: 7d, 30d, or 90d (default: 30d)Request
curl "https://wphealthkit.com/api/v1/telemetry/contact-form-7/stats?period=30d" \ -H "Authorization: Bearer whk_live_your_key"
Response
{
"data": {
"slug": "contact-form-7",
"period": "30d",
"activeInstalls": 4218,
"versionDistribution": {
"5.9.8": 0.62,
"5.9.7": 0.21,
"5.9.6": 0.11,
"other": 0.06
},
"wpVersions": {
"7.0": 0.39,
"6.8": 0.36,
"6.7": 0.19,
"other": 0.06
},
"phpVersions": {
"8.3": 0.41,
"8.2": 0.38,
"8.1": 0.16,
"other": 0.05
},
"locales": {
"en_US": 0.52,
"en_GB": 0.14,
"de_DE": 0.09,
"es_ES": 0.07,
"other": 0.18
},
"multisitePercentage": 0.08,
"avgPageTimeMs": 142,
"errorSummary": {
"total": 23,
"uniqueSites": 9,
"topMessage": "Undefined index: form_id"
},
"trend": [
{ "date": "2026-04-01", "activeInstalls": 4188 },
{ "date": "2026-04-02", "activeInstalls": 4192 }
]
},
"error": null,
"meta": { "timestamp": "2026-04-26T12:00:00.000Z" }
}GET /api/v1/reports/:id/sbom
Download a Software Bill of Materials (SBOM) for a completed audit in CycloneDX 1.6 or SPDX 2.3 format. Useful for EU CRA compliance — distribute the SBOM alongside your plugin to document third-party dependencies.
/api/v1/reports/:id/sbomPro+Generate an SBOM (Software Bill of Materials) for a completed audit. Returns CycloneDX 1.6 or SPDX 2.3 JSON. Requires audit ownership via the authenticated key, or the audit must be public.
Parameters
idstringrequiredAudit IDformatstringoptionalSBOM format: cyclonedx or spdx (default: cyclonedx)Request
# CycloneDX (default) curl "https://wphealthkit.com/api/v1/reports/aud_01j9x4r2v8kz3m7p6nq5w0c1d/sbom" \ -H "Authorization: Bearer whk_live_your_key" \ -o sbom.cdx.json # SPDX 2.3 curl "https://wphealthkit.com/api/v1/reports/aud_01j9x4r2v8kz3m7p6nq5w0c1d/sbom?format=spdx" \ -H "Authorization: Bearer whk_live_your_key" \ -o sbom.spdx.json
Response
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"serialNumber": "urn:uuid:aud_01j9x4r2v8kz3m7p6nq5w0c1d",
"metadata": {
"timestamp": "2026-04-26T12:00:00.000Z",
"tools": [{ "vendor": "WP HealthKit", "name": "wphealthkit-sbom", "version": "1.0.0" }],
"component": {
"type": "application",
"name": "contact-form-7",
"version": "5.9.8"
}
},
"components": [
{
"type": "library",
"bom-ref": "pkg:composer/symfony/[email protected]",
"name": "symfony/polyfill-mbstring",
"version": "1.28.0",
"purl": "pkg:composer/symfony/[email protected]",
"licenses": [{ "license": { "id": "MIT" } }]
}
]
}GET /api/v1/reports/:id/fixplan
Download the Fix Plan for a completed audit — the structured remediation artifact with per-finding impact, fix guidance, test steps, confidence, and agent-safety flags. JSON by default; Markdown with ?format=md for pasting into an AI coding agent.
/api/v1/reports/:id/fixplanPro+Returns the Fix Plan (versioned JSON schema) or Markdown rendering. Requires audit ownership via the authenticated key, or the audit must be public.
Parameters
idstringrequiredAudit IDformatstringoptionaljson (default) or mdRequest
# JSON (default) curl "https://wphealthkit.com/api/v1/reports/aud_01j9x4r2v8kz3m7p6nq5w0c1d/fixplan" \ -H "Authorization: Bearer whk_live_your_key" # Markdown (paste-ready for AI coding agents) curl "https://wphealthkit.com/api/v1/reports/aud_01j9x4r2v8kz3m7p6nq5w0c1d/fixplan?format=md" \ -H "Authorization: Bearer whk_live_your_key" \ -o FIX-PLAN.md
Response
{
"schemaVersion": "1.0",
"plugin": { "name": "My Plugin", "slug": "my-plugin", "version": "1.2.0" },
"audit": { "id": "aud_01j…", "date": "2026-07-23T10:00:00Z", "overallRisk": "HIGH", "grade": "C" },
"summary": { "total": 12, "bySeverity": { "CRITICAL": 1, "HIGH": 3 }, "agentSafeCount": 10, "humanReviewCount": 2 },
"items": [{
"findingId": "f-1",
"severity": "CRITICAL",
"category": "sqli",
"title": "SQL injection via unsanitised GET",
"location": "admin.php:42",
"impact": "…",
"remediation": "…",
"testAfterFix": "…",
"confidence": "HIGH",
"agentSafe": true,
"suggestedDiff": null
}]
}GET /api/v1/reports/:id/sarif
Download the audit as a SARIF 2.1.0 log — feed it to GitHub code scanning (github/codeql-action/upload-sarif) to see findings inline in your repo's Security tab.
/api/v1/reports/:id/sarifPro+Returns the audit findings as a SARIF 2.1.0 document (application/sarif+json). Requires audit ownership via the authenticated key, or the audit must be public.
Parameters
idstringrequiredAudit IDRequest
curl "https://wphealthkit.com/api/v1/reports/aud_01j9x4r2v8kz3m7p6nq5w0c1d/sarif" \ -H "Authorization: Bearer whk_live_your_key" \ -o wphk-audit.sarif
Response
{
"version": "2.1.0",
"runs": [{
"tool": { "driver": { "name": "WP HealthKit", "informationUri": "https://wphealthkit.com" } },
"results": [{
"ruleId": "wphk/sqli/sql-injection-via-unsanitised-get",
"level": "error",
"message": { "text": "SQL injection via unsanitised GET — impact…" },
"locations": [{ "physicalLocation": { "artifactLocation": { "uri": "admin.php" }, "region": { "startLine": 42 } } }]
}]
}]
}GET /api/v1/reports/:id/vex
Download an OpenVEX document for a completed audit — per-CVE exploitability statements with corroboration evidence. The CRA compliance companion to the SBOM: "affected" when 2+ independent sources confirm a CVE, "under_investigation" for single-source detections.
/api/v1/reports/:id/vexPro+Returns an OpenVEX 0.2.0 document with one statement per CVE found in the audited version. Requires audit ownership via the authenticated key, or the audit must be public.
Parameters
idstringrequiredAudit IDRequest
curl "https://wphealthkit.com/api/v1/reports/aud_01j9x4r2v8kz3m7p6nq5w0c1d/vex" \ -H "Authorization: Bearer whk_live_your_key" \ -o vex.json
Response
{
"@context": "https://openvex.dev/ns/v0.2.0",
"author": "WP HealthKit",
"version": 1,
"statements": [{
"vulnerability": { "name": "CVE-2026-1234" },
"products": [{ "@id": "pkg:wordpress/plugin/[email protected]" }],
"status": "affected",
"justification": "Confirmed by 2 independent sources (wpscan, wordfence)"
}]
}GET /api/v1/reports/:id/performance-history
Returns the Playground performance history for a plugin across audited versions, plus a regression delta against the previous version. Available when the optional Playground engine has been run on at least two audits of the same plugin.
/api/v1/reports/:id/performance-historyPro+Retrieve performance regression history for a completed audit. Returns peak memory, query count, and test timestamps for each audited version of the plugin. Requires API key ownership or session auth as the audit owner.
Parameters
idstringrequiredAudit IDRequest
curl https://wphealthkit.com/api/v1/reports/aud_01j9x4r2v8kz3m7p6nq5w0c1d/performance-history \ -H "Authorization: Bearer whk_live_your_key"
Response
{
"data": {
"slug": "contact-form-7",
"history": [
{
"version": "5.9.6",
"memoryPeakKb": 8192,
"dbQueries": 14,
"testedAt": "2026-02-12T09:14:00.000Z"
},
{
"version": "5.9.7",
"memoryPeakKb": 8320,
"dbQueries": 14,
"testedAt": "2026-03-08T11:02:00.000Z"
},
{
"version": "5.9.8",
"memoryPeakKb": 8704,
"dbQueries": 16,
"testedAt": "2026-04-22T10:48:00.000Z"
}
],
"regression": {
"memoryDeltaKb": 384,
"memoryDeltaPercent": 4.6,
"queryDelta": 2,
"previousVersion": "5.9.7"
}
},
"error": null,
"meta": { "timestamp": "2026-04-26T12:00:00.000Z" }
}GET /api/v1/usage
/api/v1/usagePro+Retrieve current usage statistics and limits for your account.
Request
curl https://wphealthkit.com/api/v1/usage \ -H "Authorization: Bearer whk_live_your_key"
Response
{
"data": {
"plan": "agency",
"audits": {
"used": 47,
"limit": 200,
"resets_at": "2025-05-01T00:00:00.000Z"
},
"api_requests": {
"used_today": 312,
"limit_per_minute": 30
}
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:00:00.000Z" }
}GET /api/v1/directory
/api/v1/directoryPublicList publicly audited plugins from the WP HealthKit directory. No authentication required.
Parameters
pageintegeroptionalPage number (default: 1)per_pageintegeroptionalResults per page, max 50 (default: 20)riskstringoptionalFilter by risk level: low, medium, high, criticalqstringoptionalSearch queryRequest
curl "https://wphealthkit.com/api/v1/directory?page=1&per_page=20&risk=low"
Response
{
"data": {
"plugins": [
{
"slug": "contact-form-7",
"name": "Contact Form 7",
"version": "5.9.8",
"overall_risk": "LOW",
"findings_count": 3,
"audited_at": "2025-04-01T08:30:00.000Z",
"report_url": "https://wphealthkit.com/results/aud_01j9x4r2v8kz3m7p6nq5w0c1d"
}
],
"pagination": { "page": 1, "per_page": 20, "total": 1420, "total_pages": 71 }
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:00:00.000Z" }
}GET /api/v1/directory/:slug
/api/v1/directory/:slugPublicRetrieve detailed audit data for a specific plugin by its wp.org slug. No authentication required.
Parameters
slugstringrequiredwp.org plugin slugRequest
curl https://wphealthkit.com/api/v1/directory/contact-form-7
Response
{
"data": {
"slug": "contact-form-7",
"name": "Contact Form 7",
"version": "5.9.8",
"overall_risk": "LOW",
"findings_count": 3,
"critical_count": 0,
"high_count": 0,
"medium_count": 2,
"low_count": 1,
"php_compatibility": { "min": "7.4", "tested_up_to": "8.3" },
"audited_at": "2025-04-01T08:30:00.000Z",
"report_url": "https://wphealthkit.com/results/aud_01j9x4r2v8kz3m7p6nq5w0c1d"
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:00:00.000Z" }
}POST /api/v1/webhooks
/api/v1/webhooksPro+Register a webhook endpoint to receive real-time event notifications.
Parameters
urlstringrequiredHTTPS URL to receive webhook payloadseventsarrayrequiredEvent types to subscribe to (e.g. ["audit.completed"])secretstringoptionalOptional signing secret for HMAC-SHA256 verificationRequest
curl -X POST https://wphealthkit.com/api/v1/webhooks \
-H "Authorization: Bearer whk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/wphk",
"events": ["audit.completed", "audit.failed"],
"secret": "your_signing_secret"
}'Response
{
"data": {
"id": "wh_01j9x4r2v8kz3m7p6nq5w0c1d",
"url": "https://yourapp.com/webhooks/wphk",
"events": ["audit.completed", "audit.failed"],
"created_at": "2025-04-10T12:00:00.000Z"
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:00:00.000Z" }
}GET /api/v1/webhooks
/api/v1/webhooksPro+List all registered webhook endpoints for your account.
Request
curl https://wphealthkit.com/api/v1/webhooks \ -H "Authorization: Bearer whk_live_your_key"
Response
{
"data": {
"webhooks": [
{
"id": "wh_01j9x4r2v8kz3m7p6nq5w0c1d",
"url": "https://yourapp.com/webhooks/wphk",
"events": ["audit.completed", "audit.failed"],
"created_at": "2025-04-10T12:00:00.000Z"
}
]
},
"error": null,
"meta": { "timestamp": "2025-04-10T12:00:00.000Z" }
}DELETE /api/v1/webhooks/:id
/api/v1/webhooks/:idPro+Delete a registered webhook by ID.
Parameters
idstringrequiredWebhook IDRequest
curl -X DELETE https://wphealthkit.com/api/v1/webhooks/wh_01j9x4r2v8kz3m7p6nq5w0c1d \ -H "Authorization: Bearer whk_live_your_key"
Response
{
"data": { "deleted": true, "id": "wh_01j9x4r2v8kz3m7p6nq5w0c1d" },
"error": null,
"meta": { "timestamp": "2025-04-10T12:00:00.000Z" }
}POST /api/v1/fp
Report a specific finding as a false positive. Reports are reviewed by the WP HealthKit team; confirmed patterns result in scanner rule updates that prevent the pattern in all future audits.
/api/v1/fpPro+Submit a false positive report for a finding within a completed audit. Requires auditId, findingId, and findingTitle. All other fields are optional but improve review speed and accuracy.
Parameters
auditIdstringrequiredUUID of the audit containing the findingfindingIdstringrequiredID of the specific finding (e.g. finding-12)findingTitlestringrequiredTitle of the finding as shown in the audit reportfindingCategorystringoptionalCategory of the finding (e.g. coding-standards, security)severitystringoptionalSeverity level: CRITICAL, HIGH, MEDIUM, or LOWlocationstringoptionalFile and line number where the finding occurred (e.g. class-example.php:45)descriptionstringoptionalThe finding description as shown in the audit reportuserReasonstringoptionalYour explanation of why this is a false positive — the more detail, the faster the reviewRequest
curl -X POST https://wphealthkit.com/api/v1/fp \
-H "Authorization: Bearer $WPHK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auditId": "your-audit-id",
"findingId": "finding-5",
"findingTitle": "PHP 8.0+ named arguments on positional WP API calls",
"userReason": "add_action() uses positional args, not PHP 8.0 named argument syntax"
}'Response
{ "id": "fp-report-uuid", "success": true }Error responses
400Missing required fields — auditId, findingId, or findingTitle not provided401Invalid or missing API key404Audit not found or not owned by the authenticated API key409This finding has already been reported as a false positive for this auditGET /api/v1/witnesses/:uid/verify
Independently verify a signed audit witness (reverify/witness/v1). Witnesses are executed proof from the audit sandbox — AJAX/REST exploit probes — bound to the audited artifact's sha256 and signed at generation time. This endpoint re-verifies the packet's ed25519 signature against the producer key published in the public Reverify key registry, so anyone can confirm a witness without trusting WP HealthKit. Only witnesses on public audits are served; private audits' witnesses are owner-only.
/api/v1/witnesses/:uid/verifyPublic — no authRe-verify a witness packet. Returns the verdict, per-check detail, and the full packet. Human-readable version at /verify/witness/:uid.
Parameters
uidstringrequiredWitness id in the path (wit_<32 hex>), from the report payload's _witnesses arrayRequest
curl https://wphealthkit.com/api/v1/witnesses/wit_35e7da3a51a14ff492a16dfcb64a4683/verify
Response
{
"verdict": "valid-structural",
"checks": [
{ "check": "schema", "status": "pass",
"detail": "packet is reverify/witness/v1 with an ed25519 signature block" },
{ "check": "signature", "status": "pass",
"detail": "ed25519 signature valid against 'wphk-witness-2026-07' (reverify registry)" }
],
"witness": {
"id": "wit_35e7da3a51a14ff492a16dfcb64a4683",
"type": "sandbox_transcript",
"payload": {
"outcome": "leaked",
"request": { "method": "POST", "path": "/wp-admin/admin-ajax.php",
"params": { "action": "wpp_public_stats" }, "unauthenticated": true },
"response": { "status": 200 },
"environment": { "wp_version": "7.0", "php_version": "8.3", "sandbox": "php-wasm" }
},
"artifact": { "kind": "wp-plugin-zip", "sha256": "aaf0482ae3772b16…" },
"signature": { "algorithm": "ed25519", "public_key_id": "wphk-witness-2026-07", "signature": "dc1b53c7…" }
},
"verified_at": "2026-07-31T13:10:00.000Z",
"registry_source": "https://reverify.co.uk/.well-known/reverify-keys.json"
}GET /api/v1/receipts/:id/verify
Verify a provenance receipt — the HMAC-SHA256-signed attestation that a specific artifact (plugin ZIP sha256) passed audit. Human-readable version at /receipts/:id.
/api/v1/receipts/:id/verifyPublic — no authVerify a provenance receipt's signature and grade.
Parameters
idstringrequiredReceipt id (UUID) in the pathRequest
curl https://wphealthkit.com/api/v1/receipts/0f1e2d3c-…/verify
Response
{
"valid": true,
"receipt": {
"plugin_name": "Example Plugin",
"plugin_slug": "example-plugin",
"grade": "B",
"layers_run": 62,
"issued_at": "2026-07-29T22:16:52.000Z",
"models": "kimi-k3 + claude-opus-4-7 + deepseek-v4-flash"
}
}