MAIVE UI
My Runs
← Back to Home

Public API

Run MAIVE, WAIVE, WLS, and RTMA models from your own scripts and pipelines.

The API is free and anonymous: no accounts, no API keys, no sign-up. It is the same compute this web app uses, given a documented JSON contract. Abuse is bounded by server-side concurrency caps and edge rate limits rather than by identity.

Base URL

https://api.maive.eu

Content type is application/json in both directions. The machine-readable contract is the OpenAPI 3 spec, which is the source of truth; the usage guide has the same examples in narrative form.

Endpoints

Public API endpoints
EndpointKindDescription
POST /v1/run-modelSyncRun MAIVE, WAIVE, or WLS and get the result in the response.
POST /v1/run-rtmaSyncRun RTMA and get the result in the response.
POST /v1/runsAsyncQueue a run; returns a jobId immediately.
GET /v1/runs/{jobId}AsyncPoll a run; returns the result once it has succeeded.
GET /v1/healthMetaHealth check.

Synchronous or asynchronous

Async is the recommended default.

Synchronous endpoints return the result in the same response, which is the simplest thing to call, but they are subject to the edge's roughly 100 second proxy cap. That is comfortable for typical runs (about 15 to 60 seconds including a cold start) and unsuitable for anything larger.

The asynchronous path (POST /v1/runs then poll GET /v1/runs/{jobId} every 2 to 5 seconds) holds no long-lived connection, so it has no failure mode tied to run duration. Use it by default, especially for batch or CI usage. Batch status for several runs at once: GET /v1/runs?ids=a,b,c (up to 100 ids, statuses only).

Data

Send data as an array of row objects. Columns are resolved by canonical key name when present (matched case-insensitively); otherwise the first 3 or 4 keys are read positionally in the order effect, se, n_obs, study_id.

Data row fields
FieldTypeRequired forNotes
effectnumberMAIVE-family, RTMAEstimated effect size.
senumberMAIVE-family, RTMAStandard error; must be greater than 0.
n_obsintegerMAIVE-familyNumber of observations; must be a positive integer.
study_idstringOptionalEnables study clustering. If present, rows must be at least unique studies plus 3.

The MAIVE family (/v1/run-model) needs 3 or 4 columns and at least 4 rows. RTMA (/v1/run-rtma) needs 2 columns (effect, se); rows with a missing or non-positive se are silently dropped. These rules mirror the app's own validation page and run server-side, so you get a structured 400 instead of a raw R error.

Parameters

Every parameter is optional; unset ones fall back to the defaults below.

A minimal valid request is just {"data": [...]}:

{
  "data": [
    {"effect": 0.42, "se": 0.11, "n_obs": 120},
    {"effect": 0.31, "se": 0.06, "n_obs": 90},
    {"effect": 0.55, "se": 0.20, "n_obs": 45},
    {"effect": 0.12, "se": 0.04, "n_obs": 200}
  ]
}

MAIVE, WAIVE, and WLS

MAIVE-family model parameters and defaults
ParameterValuesDefault
modelTypeMAIVE | WAIVE | WLSMAIVE
maiveMethodPET | PEESE | PET-PEESE | EKPET-PEESE
weightequal_weights | standard_weights | adjusted_weights | study_weightsequal_weights
standardErrorTreatmentnot_clustered | clustered | clustered_cr2 | bootstrapclustered_cr2
includeStudyDummiesbooleanfalse
includeStudyClusteringbooleanfalse
computeAndersonRubinbooleanfalse
useLogFirstStagebooleanfalse
winsorizenumber (percent, 0 disables)0
shouldUseInstrumentingbooleanderived: false for WLS, true otherwise

RTMA

RTMA parameters and defaults
ParameterValuesDefault
favorPositivebooleantrue
alphaSelectnumber0.05
ciLevelnumber0.95
winsorizenumber (percent, 0 disables)0

Plots (funnelPlot, zScorePlot, and their width and height companions) are excluded by default: each is a base64 PNG of roughly 50KB that most callers do not need. Add ?include=plot to any run or poll request to embed them.

Example: synchronous run

curl -s https://api.maive.eu/v1/run-model \
  -H 'Content-Type: application/json' \
  -d '{
    "data": [
      {"effect": 0.42, "se": 0.11, "n_obs": 120},
      {"effect": 0.31, "se": 0.06, "n_obs": 90},
      {"effect": 0.55, "se": 0.20, "n_obs": 45},
      {"effect": 0.12, "se": 0.04, "n_obs": 200}
    ]
  }'

Example: asynchronous run

Submit, poll until terminal, then read the result.

# 1. Submit
job=$(curl -s https://api.maive.eu/v1/runs \
  -H 'Content-Type: application/json' \
  -d '{
    "modelType": "MAIVE",
    "data": [
      {"effect": 0.42, "se": 0.11, "n_obs": 120},
      {"effect": 0.31, "se": 0.06, "n_obs": 90},
      {"effect": 0.55, "se": 0.20, "n_obs": 45},
      {"effect": 0.12, "se": 0.04, "n_obs": 200}
    ]
  }' | jq -r '.jobId')

echo "jobId: $job"

# 2. Poll until terminal
while true; do
  status=$(curl -s "https://api.maive.eu/v1/runs/$job" | tee /tmp/run.json | jq -r '.status')
  echo "status: $status"
  [[ "$status" == "succeeded" || "$status" == "failed" || "$status" == "timedout" ]] && break
  sleep 3
done

# 3. Read the result
jq '.result' /tmp/run.json

Errors and rate limits

Every error shares one envelope:

{
  "error": {
    "code": "validation_error",
    "message": "Data must have 3 or 4 columns; found 6."
  }
}
Error codes
CodeStatusMeaning
validation_error400The request body failed validation.
not_found404Unknown or expired jobId.
method_not_allowed405The HTTP method is not supported on this route.
payload_too_large413The dataset is too large to queue (roughly 200KB of JSON). Use a synchronous endpoint instead.
rate_limited429Edge rate limit or the backend concurrency cap was hit.
internal_error500An unexpected server-side error occurred.
not_configured503This deployment has no async runs infrastructure configured.

Two guardrails apply: a hard concurrency cap on the compute backend, and per-IP rate limiting at the edge. Both are tuned from observed load, so treat any 429 as "retry with backoff" rather than a hard quota.

jobId and privacy

  • A jobId is an opaque bearer token, not an account-scoped identifier. Anyone holding it can read that run's status and result, so treat it like a share link.
  • Runs and their results expire after 48 hours; polling after that returns 404 not_found.
  • Synchronous runs are stateless. Asynchronous runs persist the parameters and the result for up to 48 hours; the input dataset itself is not persisted beyond the transient queue message.
  • Do not submit confidential or personally identifiable data. There is no data-classification or redaction layer; treat every request the way you would treat a request to any other unauthenticated public web service.

Citation

If you use MAIVE in published or reported work, please cite the paper:

How to Cite This App

Please cite the MAIVE paper when using this tool for your research.

Irsova, Z., Bom, P.R.D., Havranek, T., & Rachinger, H. (2025). Spurious precision in meta-analysis of observational research. Nature Communications, 16, 8454. https://doi.org/10.1038/s41467-025-63261-0

View full paper →
© Charles University 2025• Created by Petr Čala
APIApplicationsContactReport Issues