POST /v0/predict
Classify an incoming HTTP request and receive a structured threat verdict.
POST https://api.nyoxis.com/v0/predict?api_key=<YOUR_API_KEY>
Content-Type: application/jsonAuthentication
All requests must include a valid workspace API key in the api_key query parameter.
?api_key=wk_live_abc123...Workspace tokens are scoped to a single workspace and can be created or rotated in the Nyoxis console.
Keep your API key secret. Do not expose it in client-side code or public repositories. Always call this endpoint from your server.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
method | string | ✅ | HTTP method of the request (GET, POST, PUT, …) |
path | string | ✅ | Request path. Must begin with /. |
query | string | — | Raw query string (everything after ?, excluding the ? itself) |
headers | object | — | Key-value map of request headers |
body | string | — | Raw request body as a UTF-8 string |
ip_addr | string | — | Source IP address of the original client. If omitted, extracted from CF-Connecting-IP, X-Real-IP, or X-Forwarded-For headers when present |
session_id | string | — | Currently ignored by this endpoint (reserved for future use) |
The more context you provide, the richer the verdict. method and path are sufficient for basic classification; query, body, headers, and ip_addr improve accuracy. Session reputation is derived from a fingerprint of ip_addr + user-agent + accept-language.
Example request
{
"method": "POST",
"path": "/api/users/search",
"query": "page=1&limit=20",
"headers": {
"content-type": "application/json",
"accept": "application/json",
"user-agent": "Mozilla/5.0"
},
"body": "{\"name\":\"alice\"}",
"ip_addr": "203.0.113.42"
}Data processing
Before inference, every payload passes through a three-stage pipeline:
- Redaction — Sensitive field values (passwords, tokens, API keys, OTP codes, secrets) are replaced with
<redacted>inquery,body, andheaders. - Normalization — Dynamic scalar values are canonicalized: integers →
<int>, floats →<float>, UUIDs →<uuid>, booleans →<bool>. Query keys are sorted to reduce duplicate pattern noise. - Hashing — The normalized payload is SHA-256 hashed. Identical patterns are served from cache without consuming inference quota.
Your raw payload values are never persisted.
Response body
{
is_cached: boolean
prediction?: PredictionObject | null
ip_reputation?: ReputationObject | null
session_reputation?: ReputationObject | null
}prediction
Present when the result is fresh (201) or cached (200). null when the monthly inference quota is exceeded.
{
evaluator: {
kind: string // e.g. "http_classifier"
identifier: string // model version, e.g. "v0.0.4-alpha"
}
suspicious: {
value: boolean // true if the model considers the request a threat
confidence: number // 0.0 – 1.0
}
attacks: Array<{
kind: string // attack category name
confidence: number // per-class confidence, 0.0 – 1.0
}>
risk: "none" | "low" | "medium" | "high"
risk_score: number // 0.0 – 1.0; numeric severity
explanations?: string // optional human-readable reasoning
}Attack categories include: sql_injection, path_traversal, rce, xss, open_redirect, ssrf, xxe, command_injection, ldap_injection, nosql_injection, and others. Only categories with non-trivial confidence are included in the response.
ip_reputation / session_reputation
ip_reputation is populated when an IP is available. session_reputation is generated from a fingerprint of ip_addr + user-agent + accept-language. The request body session_id field is currently ignored.
{
id: string // internal identifier
risk: "none" | "low" | "medium" | "high"
risk_score: number
ban?: {
platform?: { reason?: string; expires_at?: string }
workspace?: { reason?: string; expires_at?: string }
}
}Full response example
{
"is_cached": false,
"prediction": {
"evaluator": {
"kind": "http_classifier",
"identifier": "v0.0.4-alpha"
},
"suspicious": { "value": true, "confidence": 0.97 },
"attacks": [
{ "kind": "sql_injection", "confidence": 0.94 },
{ "kind": "path_traversal", "confidence": 0.12 }
],
"risk": "high",
"risk_score": 0.94,
"explanations": "SQL injection pattern detected in query parameter."
},
"ip_reputation": {
"id": "8a4fa2b3-1c6e-4d2b-9f3a-1a0b2c3d4e5f",
"risk": "high",
"risk_score": 0.82,
"ban": {
"platform": null,
"workspace": null
}
},
"session_reputation": null
}HTTP status codes
| Code | Meaning |
|---|---|
201 Created | Fresh inference computed and returned |
200 OK | Result served from cache — OR — monthly quota exceeded (prediction will be null) |
400 Bad Request | Invalid HTTP method string or malformed JSON body |
401 Unauthorized | Missing, invalid, or expired api_key; workspace mismatch; account disabled |
424 Failed Dependency | Billing account not linked to workspace, or AI model unavailable |
500 Internal Server Error | Internal pipeline failure (redaction, normalization, or model inference) |
Error format
All error responses use a consistent JSON envelope:
{ "msg": "Human-readable error description" }Rate limits and caching
- Monthly inference quota — Each billing account has a monthly inference quota. When exceeded, the API returns
200 OKwithprediction: nullbut continues to returnip_reputationandsession_reputationdata. - Request cache — Identical normalized request patterns are served from cache. Cached results return
200 OKwithis_cached: trueand do not consume quota. - Quota reset — Quotas reset on the 1st of each calendar month at 00:00 UTC.
IP header resolution
If ip_addr is not provided in the request body, the API attempts to extract it in this order:
CF-Connecting-IPheaderX-Real-IPheaderX-Forwarded-Forheader (first IP in the list)
When deploying behind a CDN or reverse proxy, forward CF-Connecting-IP or set ip_addr explicitly to ensure correct attribution.