Automate TPT ⇄ FundsXML conversion

Monthly TPT deliveries for dozens of share classes are a job for a script, not for a browser. The converter exposes its conversion as one HTTP request: POST /api/convert with the file as multipart form data. The direction follows from the file — a TPT (XLSX/CSV) becomes FundsXML, a FundsXML document becomes TPT.

curl

API=https://www.fund-data-converter.eu/api/convert

# TPT → FundsXML: save the XML and print the X-Conversion-* headers
curl -sS --fail-with-body -F file=@fund.xlsx -F response=file -OJ -D - "$API"

# FundsXML → TPT V8 as CSV: file, report.json and issues.csv in one zip
curl -sS --fail-with-body -F file=@fundsxml.xml -F tpt_version=V8 \
  -F output_format=csv -F response=zip -OJ "$API"

Python

import base64, requests

with open("fund.xlsx", "rb") as f:
    r = requests.post("https://www.fund-data-converter.eu/api/convert", files={"file": f}, data={"preview": "false"}, timeout=120)
r.raise_for_status()
report = r.json()
with open(report["output"]["filename"], "wb") as out:
    out.write(base64.b64decode(report["output"]["base64"]))
print(report["validation"]["valid"], report["issueCounts"], report["dataLoss"])

What comes back

The report holds the XSD validation result, issueCounts, every message (see conversion messages), dataLoss and meta with versions, SHA-256 of input and output and the duration.

Options

Field Values Direction
tpt_version V7, V8 both: force the input version, or choose the output version
include_block, include_core true/false TPT → FundsXML
output_format xlsx, csv FundsXML → TPT
delimiter semicolon, comma, pipe, tab FundsXML → TPT, CSV
all_columns true/false FundsXML → TPT

The API documentation has PowerShell examples and every field; the OpenAPI description is at /api/docs.

Read the API documentation

Questions

Do I need an API key?

No. The API is the same endpoint the web page uses. It is limited to 20 conversions per minute and 200 per hour per client, 25 MB per file and 10,000 positions per conversion. Every response says how many are left (X-RateLimit-Remaining-Minute, X-RateLimit-Remaining-Hour); GET /api/limits asks without using a conversion.

How do I know whether a conversion lost data?

The JSON report has dataLoss (values lost or kept only as custom attributes) and validation; with response=file the same key figures arrive in X-Conversion-Data-Lost and X-Conversion-Valid headers.