Skip to main content

Campaigns

This page covers the per-campaign fields and rollout strategies inside the vaccination block. For the surrounding block structure and flows configuration, see the Overview.

Quick start

The fastest path is using the V-SEIHR model preset with a flat-count vaccination campaign. In the following example, we roll out vaccination starting in February 2025 with a target of 100,000 doses per day held constant across the window. See Dose allocation for how the daily dose count splits across age groups.

curl -X POST https://epyscenario-api.isi.it/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"model": {
"preset": "V-SEIHR",
"parameters": {
"R0": 2.5,
"incubation_period": 3.0,
"infectious_period": 2.5,
"hosp_duration": 5.0,
"hosp_proportion": 0.05,
"VE_S": 0.7,
"VE_H": 0.85
}
},
"population": {"name": "United_States"},
"simulation": {"start_date": "2025-01-01", "end_date": "2025-06-30", "Nsim": 10},
"vaccination": {
"campaigns": [
{
"start_date": "2025-02-01",
"end_date": "2025-04-30",
"rollout": {"type": "flat_count", "daily_doses": 100000}
}
]
}
}'

The response includes the resulting Susceptible_to_Susceptible_vax transition series; see Inspecting the rollout for what to look at.

Campaign fields

Each entry in campaigns describes one rollout:

FieldRequiredDescription
namenoFree-text label echoed back in metadata.vaccination. Handy for keeping multiple overlapping campaigns straight.
start_dateyesCampaign start (YYYY-MM-DD), inclusive.
end_dateyesCampaign end (YYYY-MM-DD), inclusive. Must be ≥ start_date.
rolloutyesRollout strategy. v1 supports flat_count; the type field is the discriminator. See Rollout strategies.
target_age_groupsnoList of age-group labels (e.g. ["50-64", "65+"]). Must be unique and must match labels from the resolved population. null (the default) means all groups.

Rollout strategies

Flat rollout (count)

A constant daily_doses count is scheduled every day across the campaign window, distributed proportionally to the source-compartment population in each targeted age group.

"Flat" refers to the scheduled budget, not the delivered curve: as the source pool depletes (through vaccination, infections, etc.), the actual daily delivered count can drift below daily_doses. If the live pool drops below daily_doses per step, the per-source stochastic draw saturates against the available population; if the pool is empty, no doses are delivered that step. See the Dose allocation section for the per-step competing-risks draw.

FieldRequiredDescription
typeyesLiteral "flat_count". The discriminator.
daily_dosesyesTarget doses delivered per day. Must be > 0.
Example

Here is an example of V-SEIHR model run on a 1,000,000 homogeneous population (R0=1.4R_0 = 1.4, VES=0.85\mathrm{VE}_S = 0.85, VEH=0.9\mathrm{VE}_H = 0.9, 0.02% initial infections, no waning), with a single campaign scheduled at 5,000 doses/day from Feb 1 to Oct 15, 2025 (100 stochastic runs, median plotted).

Flat-count rollout: scheduled vs delivered, plus the susceptible pool depleting through the campaign window

The scheduled budget (dashed) holds at 5,000/day across the entire window, but the delivered count drops to zero around the end of May as SS is exhausted by the epidemic plus vaccination.

Custom-model usage

You can define a custom model that incorporates the effects of vaccination and takes advantage of the vaccination block. What you need is a model whose compartments include both a source and a vaccinated target, and (typically) a vaccinated layer that mirrors the unvaccinated transitions with vaccine-efficacy-attenuated rates. The block then drives doses across the source → target pairs declared in flows. You can model the effects of vaccination through transformed parameters (e.g. severity reduction) and additional transitions.

On a custom model the flows field is required; there is no default. Every source and (non-null) target must reference a compartment declared in model.compartments.

curl -X POST https://epyscenario-api.isi.it/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"model": {
"compartments": ["S", "V", "I", "R"],
"parameters": {
"transmission_rate": 0.3,
"transmission_rate_v": "(1 - VE_S) * transmission_rate",
"VE_S": 0.7,
"recovery_rate": 0.1
},
"transitions": [
{"source": "S", "target": "I", "kind": "mediated", "params": ["transmission_rate", "I"]},
{"source": "V", "target": "I", "kind": "mediated", "params": ["transmission_rate_v", "I"]},
{"source": "I", "target": "R", "kind": "spontaneous", "params": ["recovery_rate"]}
]
},
"population": {"name": "Italy"},
"simulation": {"start_date": "2025-01-01", "end_date": "2025-06-30", "Nsim": 10},
"vaccination": {
"flows": [{"source": "S", "target": "V"}],
"campaigns": [
{
"start_date": "2025-02-01",
"end_date": "2025-03-31",
"rollout": {"type": "flat_count", "daily_doses": 50000}
}
]
}
}'

Multiple campaigns

Listing more than one campaign lets you stack rollouts. Two overlapping flat_count campaigns add their daily doses at every step. Use this for booster waves, prioritization changes (e.g. open eligibility on a given date by adding a younger-age campaign mid-rollout), or to compare a baseline campaign against an accelerated counterfactual.

curl -X POST https://epyscenario-api.isi.it/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"model": {
"preset": "V-SEIHR",
"parameters": {"R0": 2.5, "VE_S": 0.7, "VE_H": 0.85}
},
"population": {
"name": "United_States",
"contacts_source": "prem_2021",
"age_group_mapping": {
"0-17": ["0-4", "5-9", "10-14", "15-19"],
"18-49": ["20-24", "25-29", "30-34", "35-39", "40-44", "45-49"],
"50-64": ["50-54", "55-59", "60-64"],
"65+": ["65-69", "70-74", "75+"]
}
},
"simulation": {"start_date": "2025-01-01", "end_date": "2025-06-30", "Nsim": 10},
"vaccination": {
"campaigns": [
{
"name": "phase 1 (older adults)",
"start_date": "2025-02-01",
"end_date": "2025-03-31",
"target_age_groups": ["65+"],
"rollout": {"type": "flat_count", "daily_doses": 40000}
},
{
"name": "phase 2 (open eligibility)",
"start_date": "2025-03-15",
"end_date": "2025-05-31",
"target_age_groups": ["18-49", "50-64", "65+"],
"rollout": {"type": "flat_count", "daily_doses": 80000}
}
]
}
}'