Endpoints
/xql/validate, /xql/explain, /xql/run.
All three endpoints read the XQL query from the raw request body (plain text, not a JSON-wrapped field or query parameter) and all three require the Authorization header described in Authentication.
POST /xql/validate
Parses and plans the query without touching any data store. Use this to check a query is well-formed and within the lookback ceiling before running it. Works with any recognized API key, including free tier, and is never metered.
curl https://api.xcreener.com/xql/validate \
-H "Authorization: Bearer <your-api-key>" \
--data-raw 'market = "CRYPTO"
timeframe = h1
rsi(14) < 30'Success (200):
{ "valid": true }Failure (400):
{
"valid": false,
"error": {
"type": "syntax",
"message": "Unexpected end of input, expected ')'",
"position": { "line": 3, "column": 12, "offset": 45 }
}
}error.type is "syntax" for a parse-time error (includes position) or "plan" for a plan-time error, such as exceeding the 300-bar lookback ceiling (no position).
POST /xql/explain
Parses and plans the query and, on success, returns both the data-requirements manifest and a human-readable description. Works with any recognized API key, including free tier, and is never metered.
curl https://api.xcreener.com/xql/explain \
-H "Authorization: Bearer <your-api-key>" \
--data-raw 'market = "CRYPTO"
timeframe = h1
columns = [close, rsi(14)]
sort = rsi(14) asc
rsi(14) < 30'Success (200):
{
"plan": {
"market": "CRYPTO",
"sources": [{ "timeframe": "h1", "series": ["close"], "minLookback": 15 }]
},
"explanation": "Matches when rsi(14) < 30. Returns close, rsi(14), sorted by rsi(14) ascending."
}Failure (400): same shape as /xql/validate's failure response: no plan or explanation field is included.
explain() is mechanical, not paraphrased
The explanation string renders the query back in near-XQL prose (e.g. "Matches when rsi(14) < 30"): it does not translate to plain-English trading language. It's meant as a mechanical sanity check on what a query does, not a trader-facing summary.
POST /xql/run
Parses and plans the query; on success, fetches the OHLCV data the plan requires and executes the query against every instrument in the query's market/timeframe universe. Works with any recognized key, including free tier, metered against your subscription's daily quota: see Rate Limits.
curl https://api.xcreener.com/xql/run \
-H "Authorization: Bearer <your-api-key>" \
--data-raw 'market = "CRYPTO"
timeframe = h1
columns = [close, rsi(14)]
sort = rsi(14) asc
limit = 5
rsi(14) < 30'/xql/run counts against your account's daily quota: every response carries X-RateLimit-Remaining and X-RateLimit-Reset headers so you can track it. See Rate Limits for per-tier quotas and how to make the most of them.
Success (200):
{
"results": [
{
"symbol": "SOLUSD",
"columns": { "close": 142.31, "rsi(14)": 24.8 }
},
{
"symbol": "ADAUSD",
"columns": { "close": 0.612, "rsi(14)": 27.1 }
}
]
}results reflects the query's sort ordering and limit truncation. An empty array ({ "results": [] }) means the query is valid but no instrument currently matches, not an error.
Failure modes:
| Status | Cause |
|---|---|
400 | Parse or plan failure (same error shape as /xql/validate): no data fetch occurs |
429 | Daily quota exhausted for your subscription tier: see Rate Limits |
500 | The query parsed and planned successfully, but the underlying database connection failed |
401 happens before any of this
A missing or unrecognized API key is rejected before parse/plan logic runs on all three endpoints: see Authentication.