xAlmanac Upload API
API v1Push MT5 backtest and optimization results into your xTriel profile from an
external agent. Each upload appears in xAlmanac as a
fully-parsed preset — metrics, balance curve, inputs, and a Tester-settings panel — with the
.set downloadable from there.
.htm and the .set, then POSTs their contents to this endpoint.1 · Authentication
Uploads use your per-user Ingest Token — the same xti_… token the
Reporter EA uses. No separate credential.
- Sign in → Profile → Connect your EA.
- Generate / copy your Ingest Token (shown once — store it safely).
- Send it as a Bearer header on every request:
Authorization: Bearer xti_xxxxxxxxxxxxxxxxxxxxxxxxThe token resolves to your account server-side — you never send a user id or email. Regenerating it invalidates the old token for both the Reporter EA and the agent.
ALMANAC_LIMIT. Starter stores 15, Pro 50, and Max is unlimited; every paid tier gets the same compare and export tools.2 · Endpoint
POST https://xtriel.com/api/almanac/ingest
Authorization: Bearer xti_…
Content-Type: application/jsonBody — a batch of one or more results:
{
"presets": [
{
"ea": "MyExpert", // REQUIRED — groups results under this EA
"version": "v1", // optional (default "v1")
"name": "EURUSD H1 example", // optional display name
"kind": "optimization", // optional: "backtest" | "optimization"
"setFile": { // REQUIRED — the EA inputs (.set) as text
"name": "result.set",
"content": "InpRiskPerSetupPercent=2.0\nInpTakeProfitMode=3\n..."
},
"reportFile": { // recommended — the MT5 .htm report
"name": "ReportTester.html",
"contentBase64": "PGh0bWw+...", // base64 of the report bytes
"encoding": "utf-16le" // MT5 reports are often UTF-16
},
"tester": { // recommended — the Strategy Tester run config
"expert": "MyExpert.ex5",
"symbol": "EURUSD", "timeframe": "H1", "model": 4,
"fromDate": "2026.06.22", "toDate": "2026.06.28",
"deposit": 10000, "currency": "USD", "leverage": "1:100"
},
"results": { "netProfit": 12450, "profitFactor": 1.84, "maxDDpct": 8.7 },
"sourceKey": "sha256-of-set-and-report" // optional dedupe key
}
]
}Field reference
| Field | Req | Notes |
|---|---|---|
ea | yes | EA name (≤64). Results group under it in xAlmanac. |
setFile.content | yes | The .set as UTF-8 text. |
setFile.name | — | Original filename (used for the download name). |
version | — | Defaults to "v1". |
name | — | Display name for the result. |
kind | — | "backtest"/"optimization"; inferred from the .set if omitted. |
reportFile.contentBase64 | — | Base64 of the MT5 .htm. Parsed in your browser for metrics + balance curve. |
reportFile.encoding | — | e.g. utf-16le, utf-8. If omitted, xAlmanac sniffs the BOM when parsing in your browser. |
reportHtmlB64 | — | Shorthand alias for reportFile.contentBase64. |
tester | — | Run config shown in the Tester panel. Keys: expert, symbol, timeframe/period, model, fromDate, toDate, deposit, currency, leverage, optimization, optimizationCriterion, executionMode, spread, forwardMode. Unknown keys dropped. |
results | — | Headline metrics (object). Stored as sent; xAlmanac fills missing metrics from the report in your browser. |
equity | — | Balance curve [[time, balance], …] (≤5000). Usually taken from the report. |
tags | — | Array of strings. |
sourceKey | — | Dedupe key — re-runs update instead of duplicating. |
3 · Response & errors
{
"ok": true,
"created": [ { "artifactId": "…", "ea": "MyExpert", "version": "v1", "name": "…" } ],
"updated": [],
"skipped": []
}created new · updated dedupe hit · skipped rejected (each with a
reason: MISSING_EA, MISSING_SET, BAD_REPORT,
REPORT_TOO_LARGE, ALMANAC_LIMIT, …). A bad item never fails the whole batch.
| Status | Meaning |
|---|---|
401 | Missing / invalid token. |
400 | Malformed JSON, no presets array, or >50 presets in a batch. |
413 | Body too large. |
429 | Too many bad-token attempts — back off ~15 min. |
4 · What you get in xAlmanac
Open xAlmanac. Uploads are auto-imported on load (or via the Agent uploads button) and render like a manual import:
- Full Detail view — net profit, profit factor, drawdown, Sharpe, balance curve.
- Tester settings panel — Expert, Symbol, Period, Model, dates, Deposit, Currency, Leverage — with a blue Download .set button.
- Source filter + column (Manual vs Agent) and an API badge.
- Download report to retrieve the original
.htm.
To reproduce a run in MT5: download the .set, open View → Strategy Tester,
load the EA, Inputs → Load the .set, then match Symbol / Period / Modelling /
date range / Deposit to the Tester-settings panel.
5 · Agent example (Python)
import base64, requests, pathlib
GATEWAY = "https://xtriel.com/api/almanac/ingest"
TOKEN = "xti_xxxxxxxxxxxxxxxxxxxxxxxx" # Profile -> Connect your EA
def upload_result(set_path, report_path, ea, version="v1", name="", tester=None):
set_text = pathlib.Path(set_path).read_text(encoding="utf-8", errors="replace")
report_raw = pathlib.Path(report_path).read_bytes() # raw bytes (MT5 reports often UTF-16)
preset = {
"ea": ea, "version": version, "name": name or pathlib.Path(report_path).stem,
"setFile": {"name": pathlib.Path(set_path).name, "content": set_text},
"reportFile": {
"name": pathlib.Path(report_path).name,
"contentBase64": base64.b64encode(report_raw).decode("ascii"),
"encoding": "utf-16le",
},
}
if tester: preset["tester"] = tester
r = requests.post(GATEWAY, headers={"Authorization": f"Bearer {TOKEN}"},
json={"presets": [preset]}, timeout=30)
r.raise_for_status()
return r.json()
print(upload_result(
"myexpert.set", "report.htm",
ea="MyExpert", name="EURUSD H1 example",
tester={"expert": "MyExpert.ex5", "symbol": "EURUSD",
"timeframe": "H1", "model": 4, "fromDate": "2026.06.22",
"toDate": "2026.06.28", "deposit": 10000, "currency": "USD",
"leverage": "1:100"}))curl
curl -sS -X POST https://xtriel.com/api/almanac/ingest \
-H "Authorization: Bearer $XTRIEL_INGEST_TOKEN" \
-H "Content-Type: application/json" \
--data @batch.json6 · Deploy the upload agent
Run the agent on the machine that can read your MT5 files, or on a VPS where you sync Strategy Tester exports. Keep the ingest token out of code — pass it as an environment variable.
- Create a small Python environment:
python3 -m venv .venv . .venv/bin/activate pip install requests - Store the token outside the script:
export XTRIEL_INGEST_TOKEN="xti_xxxxxxxxxxxxxxxxxxxxxxxx" - Run the uploader against your exported files:
python upload_xalmanac.py
7 · Troubleshooting
401— copy a fresh Ingest Token from Profile → Connect your EA and update your environment variable.ALMANAC_LIMIT— choose a paid tier or remove old results before uploading again. Starter stores 15 presets, Pro 50, and Max is unlimited.BAD_REPORT— re-export the report from MT5 Strategy Tester and preserve its original bytes before base64 encoding.REPORT_TOO_LARGE— keep the decoded report at 2 MB or less.- Missing metrics — include the MT5 report; xAlmanac fills many gaps from it when you open the result.