Skip to content

perf-lint API

Base URL: https://perflint.martkos-it.co.uk/api

Rate limits: Free 50 scans/month · Pro 500 scans/month · Team unlimited

Authentication: X-API-Key: your-api-key (required for Pro/Team; optional for free tier within rate limits)


POST /api/lint
Content-Type: multipart/form-data
file=@my-test.jmx
tool=jmeter

Or with API key and explicit options:

Terminal window
curl -X POST https://perflint.martkos-it.co.uk/api/lint \
-H "X-API-Key: ${PERF_LINT_API_KEY}" \
-F "file=@my-test.jmx" \
-F "tool=jmeter" \
-F "format=json"

Parameters:

ParamRequiredValuesDescription
fileYesScript file (.jmx, .js, .scala)
toolNojmeter, k6, gatling, autoDefault: auto (detected from file extension)
formatNojson, sarif, textDefault: json
rulesNocomma-separated rule IDsOnly run these rules
severityNoerror, warn, infoMinimum severity to report
POST /api/lint/content
Content-Type: application/json
{
"content": "import http from 'k6/http';\n...",
"tool": "k6",
"filename": "load-test.js"
}
{
"tool": "k6",
"filename": "load-test.js",
"summary": {
"total": 3,
"errors": 1,
"warnings": 1,
"info": 1
},
"findings": [
{
"ruleId": "K6001",
"severity": "error",
"message": "sleep() missing between requests — add think time to simulate realistic user behaviour",
"line": 12,
"column": 1,
"fix": {
"available": true,
"description": "Add sleep(1) after request"
}
},
{
"ruleId": "K6005",
"severity": "warn",
"message": "No threshold defined — add thresholds to options to enforce SLAs",
"line": 3,
"column": 1,
"fix": {
"available": false
}
}
],
"exitCode": 1,
"scansUsed": 1,
"scansRemaining": 499
}
{
"version": "2.1.0",
"$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
"runs": [
{
"tool": {
"driver": {
"name": "perf-lint",
"version": "1.x",
"rules": [...]
}
},
"results": [...]
}
]
}

Upload SARIF to GitHub Advanced Security for in-PR lint annotations:

- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: lint-results.sarif

GET /api/rules?tool=jmeter&tier=community

Parameters:

ParamValuesDescription
tooljmeter, k6, gatlingFilter by tool
tiercommunity, pro, teamFilter by tier availability
severityerror, warn, infoFilter by severity

Response:

[
{
"id": "JMX001",
"tool": "jmeter",
"severity": "warn",
"tier": "community",
"title": "Thread group uses \"Forever\" loop",
"description": "Set a finite loop count or duration to prevent unbounded test runs.",
"fixable": true,
"docsUrl": "https://perflint.martkos-it.co.uk/rules/JMX001"
}
]
GET /api/rules/{ruleId}

GET /api/team/config
X-API-Key: your-team-key

Returns the shared .perf-lint.yml configuration applied to all scans using this team API key.

PUT /api/team/config
X-API-Key: your-team-key
Content-Type: application/json
{
"rules": {
"JMX001": "off",
"K6005": "warn"
},
"ignore": ["tests/legacy/**"]
}
GET /api/team/usage?month=2026-03

Response:

{
"month": "2026-03",
"scans": 312,
"limit": null,
"topErrors": [
{"ruleId": "JMX010", "count": 87},
{"ruleId": "K6001", "count": 64}
]
}

StatusMeaning
400Bad request (unsupported file type, parse failure)
401Invalid or missing API key
413File too large (max 10MB)
422Validation error
429Rate limit exceeded
500Internal error

Rate limit error:

{
"error": "RATE_LIMIT_EXCEEDED",
"message": "Monthly scan limit reached (50/50). Upgrade to Pro for 500 scans/month.",
"scansUsed": 50,
"resetAt": "2026-04-01T00:00:00Z"
}