Integrate Nexdge reviews directly into your tools, pipelines, and dashboards. API access requires Pro plan or above.
Authentication
Every request needs a bearer token in the Authorization header (an x-api-key header works too, if that fits your tooling better). Get your key from the dashboard.
Authorization: Bearer YOUR_API_KEYSubmit code for review. Returns severity-graded findings from each specialist, plus the verified-rewrite status.
Request body
| code | string | required | The code to review. 50,000 characters maximum. |
| filename | string | optional | Optional filename, shown back in the response. |
| language | string | optional | One of: javascript, typescript, python, go, rust, java, csharp, cpp, ruby, php, swift, kotlin, sql, html, css, shell, yaml, json, other. Left out, it's reported as "unknown" rather than guessed. |
| checks | string[] | optional | Which specialists to run: security, reliability, business_logic, performance, quality. Defaults to all five. |
| business_context | string | optional | What the code is supposed to do, in business terms. Improves Business Logic findings. 2,000 characters maximum. |
| label | string | optional | An optional name for the review, shown back in the response. 80 characters maximum. |
| apply_all_fixes | boolean | optional | Attempt a full rewrite addressing every finding, not just the verified subset. |
Example request
curl -X POST https://www.nexdge.com/api/v1/analyze \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "async function getUser(id) { return db.query(`SELECT * FROM users WHERE id = ${id}`) }",
"language": "javascript",
"checks": [
"security",
"reliability",
"quality"
]
}'const res = await fetch("https://www.nexdge.com/api/v1/analyze", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.NEXDGE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"code": "async function getUser(id) { return db.query(`SELECT * FROM users WHERE id = ${id}`) }",
"language": "javascript",
"checks": [
"security",
"reliability",
"quality"
]
}),
});
if (!res.ok) throw new Error(`Nexdge returned ${res.status}`);
const review = await res.json();
console.log(review.score, review.risk_level);import os
import requests
res = requests.post(
"https://www.nexdge.com/api/v1/analyze",
headers={
"Authorization": f"Bearer {os.environ['NEXDGE_API_KEY']}",
"Content-Type": "application/json",
},
json={
"code": "async function getUser(id) { return db.query(f'SELECT * FROM users WHERE id = {id}') }",
"language": "javascript",
"checks": ["security","reliability","quality"],
},
timeout=60,
)
res.raise_for_status()
review = res.json()
print(review["score"], review["risk_level"])payload, _ := json.Marshal(map[string]any{
"code": "async function getUser(id) { return db.query(`SELECT * FROM users WHERE id = ${id}`) }",
"language": "javascript",
"checks": []string{"security", "reliability", "quality"},
})
req, _ := http.NewRequest("POST", "https://www.nexdge.com/api/v1/analyze", bytes.NewReader(payload))
req.Header.Set("Authorization", "Bearer "+os.Getenv("NEXDGE_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()Example response
{
"status": "complete",
"request_id": "a1b2c3d4-...",
"filename": null,
"language": "javascript",
"line_count": 1,
"score": 24,
"risk_level": "critical",
"credits_used": 1,
"credits_remaining": 69,
"summary": "Direct string interpolation into a SQL query creates an injection vector.",
"specialists": [
{ "name": "security", "score": 10, "risk_level": "critical", "issue_count": 1, "pass_count": 0 },
{ "name": "reliability", "score": 78, "risk_level": "medium", "issue_count": 1, "pass_count": 3 },
{ "name": "quality", "score": 90, "risk_level": "low", "issue_count": 0, "pass_count": 4 }
],
"findings": [
{
"severity": "critical",
"category": "security",
"line": 1,
"title": "SQL injection vulnerability",
"description": "Template literal used directly in SQL query.",
"suggestion": "Use a parameterised query instead of string interpolation."
}
],
"passed": false,
"fully_rewritten": false,
"requires_human_review": false,
"alternate_available": true
}Rate limits
60 requests per minute, per account, the same limit regardless of plan tier. There's no Studio or Agency scaling on this yet, everyone with API access shares the same ceiling.
A 429 response includes a Retry-After header and a retry_after field, in seconds.
Idempotency
Send an Idempotency-Key header (letters, numbers, hyphens and underscores, 128 characters maximum) and a repeated request within 5 minutes replays the cached response instead of running, and re-billing, the review again.
Idempotency-Key: a-key-you-generate-per-requestErrors
| 400 | Invalid JSON body, or an unrecognised value in checks (the response includes a valid_checks array). |
| 401 | Invalid or expired API key. |
| 402 | Insufficient credits. Response includes credits_required and credits_remaining. |
| 403 | API access requires a Pro plan or above. |
| 413 | Request body or code exceeds the size limit (50,000 characters of code). |
| 429 | Rate limit exceeded. See Retry-After above. |
| 503 | Service temporarily unavailable. Retry shortly, credits are never charged for a failed attempt. |
OpenAPI
A machine-readable OpenAPI 3.1 description of this endpoint, generated from the same allowed values the API validates against. Point your client generator or coding assistant at it.
openapi.json