API
Use the HTTP(s) API to run Convert-Pheno from your own scripts or applications. Send input data, start a conversion, then retrieve the output files. Conversions use the same core engine as the CLI.
This page explains how to run the Mojolicious API yourself. Desktop users do not need these steps: the application starts the API automatically.
Start the APIβ
The API requires a token, a secret value that your script sends with each request (at least 32 characters; the command below generates 64 random hexadecimal characters). This prevents clients without the token from using the service, even when it runs on your own computer.
From the repository root, generate a token and start the API:
export CONVERT_PHENO_API_TOKEN="$(openssl rand -hex 32)"
morbo -l http://127.0.0.1:3000 api/perl/main.pl
The address 127.0.0.1 keeps the API accessible only from this computer.
Keep this terminal running. Your client must send the same token in the
Authorization: Bearer <token> header, as shown in the examples below. If you
run the examples in another terminal, set CONVERT_PHENO_API_TOKEN there to
the same value; do not generate a second token.
Submit a conversionβ
Read GET /api/conversions first. It lists routes, accepted inputs, relevant
options, supported entities, and required databases.
For JSON input, send a request like this to POST /api/jobs:
{
"conversion": "pxf2bff",
"input": {
"data": {
"id": "packet-1",
"subject": {"id": "person-1", "sex": "FEMALE"}
}
},
"output": {"entities": ["individuals"]},
"options": {}
}
curl --fail-with-body \
-H "Authorization: Bearer $CONVERT_PHENO_API_TOKEN" \
-H 'Content-Type: application/json' \
--data @request.json \
http://127.0.0.1:3000/api/jobs
The response contains a job ID. HTTP 202 means accepted, not completed.
Poll GET /api/jobs/{id}. When data.status becomes completed,
data.result.artifacts lists the output files. If it becomes failed,
read data.message.
Upload filesβ
Upload first, then assign the returned handles to the roles listed in the conversion catalog:
curl --fail-with-body \
-H "Authorization: Bearer $CONVERT_PHENO_API_TOKEN" \
-F files=@records.csv \
-F files=@mapping.yaml \
http://127.0.0.1:3000/api/inputs
Use the returned IDs in the job request:
{
"conversion": "csv2bff",
"input": {
"files": {
"source": ["CSV_HANDLE"],
"mapping": ["MAPPING_HANDLE"]
}
},
"output": {"entities": ["individuals"]},
"options": {"separator": ",", "term_audit": "xlsx"}
}
The limit is 100 MiB and 128 files per upload request. Handles are reusable; uploaded files remain in the service state directory after the request finishes. Generic API clients use handles, not server filesystem paths. Desktop uses native file selection for larger local inputs.
OMOP accepts JSON objects keyed by table name or uploaded table files.
For routes with optional dataset metadata, supply the
compact mapping under the
mapping role.
Inspect and downloadβ
| Method | Path | Purpose |
|---|---|---|
GET | /api/jobs/{id} | Status, warnings, and completed output list |
GET | /api/jobs/{id}/outputs/{artifact}/preview | Bounded table or JSON preview |
GET | /api/jobs/{id}/outputs/{artifact}/download | Original output file |
POST | /api/jobs/{id}/cancel | Cancel a queued or active job |
DELETE | /api/jobs/{id} | Delete history, keep outputs |
DELETE | /api/jobs/{id}/files | Delete history and output files |
Downloads are file bytes, not JSON-encoded content. BFF outputs have one file per requested entity; OMOP outputs have one CSV per emitted table.
With term_audit enabled, data.result.meta.terminologyAudit contains summary
counts and a limited preview. Download the XLSX or TSV output for the full report.
Runs execute one at a time. Request errors return 401 for missing
authentication, 403 for denied access, or 422 for rejected job requests.
Failures after submission appear in the job status.
JavaScript exampleβ
This Node.js example uses built-in fetch. Set CONVERT_PHENO_API_TOKEN to
the same value used to start the server. It submits a Phenopacket and checks
the job once per second, for up to one minute.
Convert a Phenopacket to Beacon v2
async function convertPhenopacket(phenopacket) {
const base = 'http://127.0.0.1:3000';
const token = process.env.CONVERT_PHENO_API_TOKEN;
if (!token) throw new Error('Set CONVERT_PHENO_API_TOKEN first');
async function request(path, body) {
const response = await fetch(`${base}${path}`, {
method: body ? 'POST' : 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: body ? JSON.stringify(body) : undefined,
signal: AbortSignal.timeout(10000),
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.error?.message ?? `HTTP ${response.status}`);
}
return result.data;
}
const job = await request('/api/jobs', {
conversion: 'pxf2bff',
input: {data: phenopacket},
output: {entities: ['individuals']},
options: {},
});
const deadline = Date.now() + 60000;
while (Date.now() < deadline) {
const current = await request(`/api/jobs/${job.id}`);
if (current.status === 'completed') {
return {jobId: job.id, outputs: current.result.artifacts};
}
if (['failed', 'cancelled', 'interrupted'].includes(current.status)) {
throw new Error(current.message ?? `Job ${current.status}`);
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
throw new Error(`Stopped waiting for job ${job.id}; it has not been cancelled`);
}
// In an ES module (.mjs):
const result = await convertPhenopacket({
id: 'packet-1',
subject: {id: 'person-1', sex: 'FEMALE'},
});
console.log(result);
The returned list describes the output files; it does not contain their contents.
Use the download endpoint above with the job ID and each output's id to retrieve
them, sending the same authorization header.
Python HTTP serverβ
The JSON-only FastAPI reference server is retained in 0.35, with deprecation
planned for a future release. It still uses its synchronous
POST /api/conversions/{conversion} contract, not the Mojolicious job API above.
Use Mojolicious for new integrations.
The Python module binding remains supported.
See the Python server README if maintaining an existing integration.
The OpenAPI specification and ReDoc reference describe the Mojolicious job API, including its native-only endpoints.
Desktop-only endpoints
Local file selection and project management endpoints require an additional private token managed by Desktop. Other API clients should use the upload endpoint described above, not these endpoints or paths to files on the server.