Skip to main content

Running a Simulation

This guide walks through running your first simulation using the SIR model with US population data.

1. Check available populations

curl https://epyscenario-api.isi.it/api/v1/populations

Pick a population name from the list. We'll use United_States. See Population Presets for the full set of options (contact sources, layers, age-group remapping) and Custom Populations for inline age groups and contact matrices.

2. Check available presets

curl https://epyscenario-api.isi.it/api/v1/models/presets

We'll use the SIR preset. See Model Presets for the SIR / SEIR / SIS / V-SEIR / V-SEIHR compartments and default parameters, or Custom Models to define your own compartments and transitions.

3. Send a simulation request

curl -X POST https://epyscenario-api.isi.it/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"model": {
"preset": "SIR",
"parameters": {
"transmission_rate": 0.3,
"recovery_rate": 0.1
}
},
"population": {
"name": "United_States"
},
"simulation": {
"start_date": "2024-01-01",
"end_date": "2024-06-01",
"Nsim": 10
},
"initial_conditions": {
"method": "percentage",
"initial_percentages": {"Infected": 0.1}
}
}'

The initial_conditions block seeds the compartments at the start of the simulation. Here, 0.1% of the population is placed in Infected and the rest in Susceptible. Omit the block entirely and ~0.05% of each age group is seeded as Infected by default; switch method to "absolute" to set exact per-age counts. See Initial Conditions for the full reference.

4. Read the response

The response contains metadata, results, and a status field. By default the API returns everything: all compartments and transitions, all age groups (plus total), all seven standard quantiles, and a summary with peaks and cumulative totals per age group. You can narrow any of these via output (see Customizing output).

{
"simulation_id": "sim_c9617343b215",
"status": "completed",
"metadata": {
"model": {
"preset": "SIR",
"compartments": ["Susceptible", "Infected", "Recovered"]
},
"population": {
"name": "United_States",
"contacts_source": "mistry_2021",
"layers": ["home", "work", "school", "community"],
"age_group_mapping": null,
"total": 338120586,
"age_groups": {
"0-4": 18608139,
"5-19": 63540783,
"20-49": 132780169,
"50-64": 63172279,
"65+": 60019216
}
},
"simulation": {
"start_date": "2024-01-01",
"end_date": "2024-06-01",
"Nsim": 10,
"dt": 1.0,
"seed": null,
"resample_frequency": "D"
}
},
"results": {
"compartments": {
"dates": ["2024-01-01", "2024-01-02", "..."],
"data": {
"Susceptible": {
"total": {
"0.5": [337330136.0, 334286966.0, "..."],
"0.025": [337330089.45, 334285584.7, "..."],
"0.975": [337330182.55, 334288347.3, "..."]
}
}
}
},
"transitions": {
"dates": ["2024-01-01", "2024-01-02", "..."],
"data": {
"Susceptible_to_Infected": {
"total": {
"0.5": [621391.0, 3043170.0, "..."],
"0.025": [621344.45, 3041835.25, "..."],
"0.975": [621437.55, 3044504.75, "..."]
}
}
}
},
"summary": {
"peaks": {
"Infected": {
"total": {
"quantiles": {
"0.025": 121800000.0,
"0.5": 124500000.0,
"0.975": 127100000.0
},
"peak_date": "2024-02-14"
},
"0-4": { "quantiles": { "0.5": 4120000.0, "...": 0 }, "peak_date": "2024-02-13" },
"65+": { "quantiles": { "0.5": 16800000.0, "...": 0 }, "peak_date": "2024-02-16" }
}
},
"totals": {
"Susceptible_to_Infected": {
"total": { "quantiles": { "0.025": 213000000.0, "0.5": 215000000.0, "0.975": 217000000.0 } },
"0-4": { "quantiles": { "0.5": 11800000.0, "...": 0 } }
}
}
}
}
}

Results are organized as quantiles (median, confidence intervals) across simulation runs. Both compartments and transitions follow the same nested structure: name -> age_group -> quantile -> [values]. The total age group is the sum across all age groups.

summary mirrors that shape without the time dimension. peaks is compartment -> age_group -> {quantiles, peak_date} and carries the maximum value reached during the simulation window per quantile. totals is transition -> age_group -> {quantiles} and carries the cumulative number of transition events over the whole window.

5. Customizing output

Everything under output is optional; sensible defaults cover most cases. You can narrow the response with any combination of:

{
"output": {
"quantiles": [0.1, 0.5, 0.9],
"age_groups": ["total"],
"compartments": ["Infected"],
"transitions": ["Susceptible_to_Infected"],
"summary": {
"peak_compartments": ["Infected"],
"total_transitions": []
}
}
}
  • quantiles drives both the trajectory quantiles and the summary quantiles.
  • age_groups filters both the trajectory age groups and the summary age groups. Use ["total"] to skip the per-age breakdown entirely.
  • compartments / transitions filter the trajectory section only.
  • summary.peak_compartments / summary.total_transitions: omit to include every compartment / transition; pass [] to explicitly opt out of that half of the summary. An empty array for both leaves summary: null.

6. Increase Nsim for production use

Start with Nsim: 10 while testing, then increase to 100 or more for reliable estimates.

7. One-liner example

For a quick read of one stat from the response, pipe through jq. For example, the median peak of Infected summed across all age groups along with its date:

curl -s -X POST https://epyscenario-api.isi.it/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"model": {"preset": "SIR", "parameters": {"transmission_rate": 0.3, "recovery_rate": 0.1}},
"population": {"name": "United_States"},
"simulation": {"start_date": "2024-01-01", "end_date": "2024-06-01", "Nsim": 100}
}' | jq '.results.summary.peaks.Infected.total | {peak_date, median: .quantiles["0.5"]}'
{
"peak_date": "2024-01-06",
"median": 290283372.5
}
tip

Use the API Reference to build and send requests interactively without writing curl commands.

Next

Try the same request in the Playground to iterate on parameters and see plots without leaving the browser.