{"openapi":"3.1.0","info":{"title":"epydemix WebAPI","description":"REST API for running epidemic simulations with epydemix","version":"0.7.2"},"servers":[{"url":"https://epyscenario-api.isi.it","description":"Production"},{"url":"http://localhost:8000","description":"Local"}],"paths":{"/api/v1/simulations":{"post":{"tags":["Simulations"],"summary":"Run epidemic simulation","description":"Execute an epidemic simulation with the specified configuration.","operationId":"run_simulation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimulationRequest"},"examples":{"SIR":{"summary":"Basic SIR simulation","description":"Run a Susceptible-Infected-Recovered model on the US population over two months.","value":{"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-03-01","Nsim":10}}},"SIR in custom population (homogeneous)":{"summary":"SIR on a custom inline population","description":"Single-group population of 100,000 with a 1x1 contact matrix specified inline. No epydemix data repo lookup; `age_groups` insertion order defines the contact-matrix row/col order.","value":{"model":{"preset":"SIR","parameters":{"transmission_rate":0.3,"recovery_rate":0.1}},"population":{"source":"custom","name":"Custom Population 1","age_groups":{"A":100000},"contact_matrices":{"all":[[1.0]]}},"simulation":{"start_date":"2024-01-01","end_date":"2024-03-01","Nsim":5}}},"V-SEIHR with seasonality and vaccination":{"summary":"V-SEIHR: Northern-Hemisphere seasonality + autumn vaccination campaign","description":"Year-long V-SEIHR run on the US population with two interventions composed: seasonality on `transmission_rate` (peak Jan 15, trough Jul 15, matching the Northern Hemisphere defaults from Balcan et al. 2010, https://doi.org/10.1016/j.jocs.2010.07.002), and a flat-count vaccination campaign delivered Oct 15 - Dec 31 so the rollout finishes just before the seasonal peak. `output.include_parameters` is enabled so the per-step `transmission_rate` series surfaces in the response for sanity-checking the envelope.","value":{"model":{"preset":"V-SEIHR","parameters":{"R0":2.5,"incubation_period":3.0,"infectious_period":2.5,"hosp_duration":5.0,"hosp_proportion":[0.002,0.005,0.015,0.05,0.18],"VE_S":0.7,"VE_H":0.85}},"population":{"name":"United_States"},"simulation":{"start_date":"2025-08-01","end_date":"2026-07-31","Nsim":10},"parameter_transforms":[{"target_parameter":"transmission_rate","method":"balcan","max_date":"2026-01-15","min_date":"2026-07-15","min_value":0.85}],"vaccination":{"campaigns":[{"start_date":"2025-10-15","end_date":"2025-12-31","rollout":{"type":"flat_count","daily_doses":100000}}]},"output":{"include_parameters":true}}}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimulationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/populations":{"get":{"tags":["Populations"],"summary":"List available populations","description":"Get a list of all available populations that can be used in simulations.","operationId":"list_populations","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PopulationListResponse"}}}}}}},"/api/v1/populations/cache":{"get":{"tags":["Populations"],"summary":"Get population cache status","description":"Get information about the population cache.","operationId":"get_population_cache_status","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CacheInfoResponse"}}}}}}},"/api/v1/populations/{name}":{"get":{"tags":["Populations"],"summary":"Get population details","description":"Get detailed information about a specific population, including total population, population by default age groups, the raw per-single-year age distribution, available contact matrix sources, the default source, and available contact layers.","operationId":"get_population","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","description":"Population identifier (e.g. `United_States`).","title":"Name"},"description":"Population identifier (e.g. `United_States`).","examples":{"United_States":{"summary":"United States","value":"United_States"}}},{"name":"contacts_source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Contact matrix source (prem_2017, prem_2021, or mistry_2021)","title":"Contacts Source"},"description":"Contact matrix source (prem_2017, prem_2021, or mistry_2021)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PopulationDetail"},"examples":{"United_States":{"summary":"United States","value":{"name":"United_States","display_name":"United States","total_population":338120586,"age_groups":{"0-4":18608139,"5-19":63540783,"20-49":132780169,"50-64":63172279,"65+":60019216},"age_distribution":{"0":3667336,"1":3713583,"2":3630098,"3":3767485,"4":3829637,"5":3917291,"6":3996031,"7":4101044,"8":4137919,"9":4126760,"10":4114032,"11":4121711,"12":4166827,"13":4253423,"14":4343515,"15":4508132,"16":4502791,"17":4432925,"18":4395762,"19":4422620,"20":4382209,"21":4362527,"22":4444906,"23":4448980,"24":4379763,"25":4373287,"26":4383880,"27":4412562,"28":4488035,"29":4580433,"30":4651049,"31":4752388,"32":4819745,"33":4828939,"34":4688811,"35":4600864,"36":4545592,"37":4550786,"38":4542751,"39":4432127,"40":4349752,"41":4236657,"42":4157608,"43":4171773,"44":4127247,"45":4109017,"46":4117218,"47":4116783,"48":4162103,"49":4213180,"50":4126472,"51":4086715,"52":4117683,"53":4150925,"54":4181148,"55":4238075,"56":4265036,"57":4310175,"58":4335272,"59":4282817,"60":4214078,"61":4238440,"62":4241499,"63":4215604,"64":4168338,"65":4098795,"66":3985170,"67":3864440,"68":3732717,"69":3612801,"70":3338420,"71":3113775,"72":2947849,"73":2778812,"74":2563739,"75":2204521,"76":1990194,"77":1878879,"78":1717196,"79":1540790,"80":1369057,"81":1243538,"82":1113300,"83":999890,"84+":7418335},"contact_sources":["prem_2017","prem_2021","mistry_2021"],"default_contact_source":"mistry_2021","available_layers":["home","work","school","community"]}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/populations/{name}/contacts":{"get":{"tags":["Populations"],"summary":"Get contact matrices","description":"Get contact matrices for a specific population.","operationId":"get_population_contacts","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"contacts_source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Contact matrix source (prem_2017, prem_2021, or mistry_2021)","title":"Contacts Source"},"description":"Contact matrix source (prem_2017, prem_2021, or mistry_2021)"},{"name":"layers","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Contact layers to include (e.g., home, work, school, community)","title":"Layers"},"description":"Contact layers to include (e.g., home, work, school, community)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactMatrixResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/models/presets":{"get":{"tags":["Model Presets"],"summary":"List model presets","description":"Get information about available predefined epidemic models.","operationId":"list_model_presets","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresetsListResponse"}}}}}}},"/api/v1/health":{"get":{"tags":["Health"],"summary":"Health Check","description":"Check API health status.\n\nReturns the API version and epydemix library version to verify\nthe service is running correctly.\n\nReturns\n-------\nHealthResponse\n    Health status including API and epydemix versions.","operationId":"health_check","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}}},"components":{"schemas":{"BalcanTransform":{"properties":{"target_parameter":{"type":"string","title":"Target Parameter","description":"Name of the model parameter to transform. Must already be defined in `model.parameters`."},"method":{"type":"string","const":"balcan","title":"Method"},"max_date":{"type":"string","title":"Max Date","description":"Date when the multiplier reaches its peak (1.0), `YYYY-MM-DD`."},"min_value":{"type":"number","title":"Min Value","description":"Lower bound of the seasonal scaling. The multiplier reaches `min_value / max_value` at the trough. With the default `max_value=1`, this is simply the fraction of baseline at the trough (e.g. `0.1` means 10% of baseline)."},"max_value":{"type":"number","title":"Max Value","description":"Upper bound of the seasonal scaling. Defaults to `1.0`, which makes the peak exactly equal to the baseline parameter. Only set this if you want to express both bounds in absolute units; the multiplier shape depends only on the ratio `min_value / max_value`.","default":1.0},"min_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Min Date","description":"Date of trough, `YYYY-MM-DD`. If set, period = `2 * |min_date - max_date|`. If omitted, period defaults to 365 days."}},"type":"object","required":["target_parameter","method","max_date","min_value"],"title":"BalcanTransform","description":"Balcan-style sinusoidal seasonality applied across the simulation timeline (Balcan D et al. J. Comput. Sci. 2010; https://doi.org/10.1016/j.jocs.2010.07.002).\n\nThe transform is **multiplicative on top of the baseline parameter**. At each\nstep, the existing value of `target_parameter` is multiplied by a sinusoidal\nfactor that reaches `1.0` on `max_date` (the seasonal peak) and\n`min_value / max_value` on `min_date` (the seasonal trough). The effective\nparameter therefore swings between `baseline` (peak) and\n`baseline * (min_value / max_value)` (trough).\n\n**Recommended usage**: leave `max_value` at its default of `1.0` and only set\n`min_value` to express the seasonal floor as a fraction of the baseline. For\nexample, with `min_value=0.1`, the parameter drops to 10% of its baseline at\nthe trough.\n\nSetting `max_value` to anything other than `1` only matters if you want to\nexpress both bounds in absolute units (mirroring the notation in Balcan et al.\n2010). Note that the multiplier shape depends only on the **ratio**\n`min_value / max_value`: `(max_value=0.4, min_value=0.1)` produces exactly\nthe same dynamics as `(max_value=1, min_value=0.25)` (both have ratio `0.25`)."},"BuiltinPopulationConfig":{"properties":{"source":{"type":"string","const":"builtin","title":"Source","description":"Loads a published population by name from the epydemix data repo.","default":"builtin"},"name":{"type":"string","title":"Name","description":"Population name in epydemix, e.g. `United_States`. It should be one of the population available in `GET /populations` endpoint."},"contacts_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contacts Source","description":"Contact matrix source.\nOptions: `prem_2017`, `prem_2021`, `mistry_2021`."},"layers":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Layers","description":"Contact layers to include.\nOptions: `home`, `work`, `school`, `community`."},"age_group_mapping":{"anyOf":[{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},{"type":"null"}],"title":"Age Group Mapping","description":"Custom age group aggregation. Keys are new group names, values are lists of source age groups to merge.\n- Example: `{\"0-19\": [\"0-4\", \"5-9\", \"10-14\", \"15-19\"], \"65+\": [\"65-69\", \"70-74\", \"75+\"]}`."}},"type":"object","required":["name"],"title":"BuiltinPopulationConfig","description":"Population loaded from the epydemix data repository (countries, regions, etc.)."},"CacheInfoResponse":{"properties":{"hits":{"type":"integer","title":"Hits","description":"Number of cache hits.","examples":[42]},"misses":{"type":"integer","title":"Misses","description":"Number of cache misses.","examples":[8]},"maxsize":{"type":"integer","title":"Maxsize","description":"Maximum cache size.","examples":[50]},"currsize":{"type":"integer","title":"Currsize","description":"Current number of cached items.","examples":[10]},"cached_populations":{"items":{"type":"string"},"type":"array","title":"Cached Populations","description":"Names of populations currently in cache.","examples":[["United_States","Italy","Germany"]]}},"type":"object","required":["hits","misses","maxsize","currsize","cached_populations"],"title":"CacheInfoResponse","description":"Cache information response schema."},"CompartmentFlow":{"properties":{"source":{"type":"string","title":"Source","description":"Compartment competing for doses."},"target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target","description":"Compartment vaccinated individuals move to. `null` marks the source as a dose sink: it contributes to the rate denominator but no transition is emitted."}},"type":"object","required":["source"],"title":"CompartmentFlow","description":"One compartment competing for doses, with an optional vaccinated target.\n\nA flow declares a `source` compartment that contributes to the rate\ndenominator (the eligible pool that competes for the campaign's doses).\nIf `target` is set, vaccinated individuals move `source -> target` and\ntransitions are emitted. If `target` is `null`, the source acts as a\n**dose sink**: it absorbs its share of doses (modeling the impossibility\nof pre-screening recipients) but no transition is emitted.\n\nCombining flows lets one block model dose competition across multiple\ncompartments. Examples:\n\n- `[{S, S_vax}]` -- perfect targeting, denominator = S only.\n- `[{S, S_vax}, {R, null}]` -- dose waste: denominator = S + R, only\n  S -> S_vax fires (matches the upstream epydemix tutorial).\n- `[{S, S_vax}, {S_2, S_2_vax}]` -- one budget shared across two\n  susceptible strata; each fires its own transition."},"CompartmentResults":{"properties":{"dates":{"items":{"type":"string"},"type":"array","title":"Dates","description":"Dates corresponding to values.","examples":[["2024-01-01","2024-01-02","2024-01-03"]]},"data":{"additionalProperties":{"additionalProperties":{"additionalProperties":{"items":{"type":"number"},"type":"array"},"type":"object"},"type":"object"},"type":"object","title":"Data","description":"Nested structure: `compartment -> age_group -> quantile -> [values]`.","examples":[{"Infected":{"total":{"0.025":[621344.45,3041835.25,5800000.0],"0.5":[621391.0,3043170.0,5812500.0],"0.975":[621437.55,3044504.75,5825000.0]}},"Susceptible":{"total":{"0.025":[337330089.45,334285584.7,331100000.2],"0.5":[337330136.0,334286966.0,331103421.0],"0.975":[337330182.55,334288347.3,331106841.8]}}}]}},"type":"object","required":["dates","data"],"title":"CompartmentResults","description":"Compartment trajectory quantiles."},"ContactMatrixResponse":{"properties":{"population_name":{"type":"string","title":"Population Name","description":"Population identifier.","examples":["United_States"]},"contact_source":{"type":"string","title":"Contact Source","description":"Contact matrix source used.","examples":["mistry_2021"]},"layers":{"additionalProperties":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"object","title":"Layers","description":"Contact matrices by layer name. Each matrix is square with one row/column per age group.","examples":[{"community":[[0.61,0.88,0.42],[0.94,1.56,0.67],[0.51,0.72,0.83]],"home":[[1.24,0.87,0.15],[0.91,2.03,0.34],[0.19,0.42,1.77]],"school":[[0.0,0.0,0.0],[0.0,5.42,0.0],[0.0,0.0,0.0]],"work":[[0.08,0.41,0.02],[0.54,2.11,0.17],[0.03,0.23,0.05]]}]},"overall":{"anyOf":[{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},{"type":"null"}],"title":"Overall","description":"Combined contact matrix across all layers.","examples":[[[1.93,2.16,0.59],[2.39,11.12,1.18],[0.73,1.37,2.65]]]},"age_groups":{"items":{"type":"string"},"type":"array","title":"Age Groups","description":"Age group labels for matrix indices (same order as rows and columns).","examples":[["0-19","20-64","65+"]]},"spectral_radius":{"additionalProperties":{"type":"number"},"type":"object","title":"Spectral Radius","description":"Spectral radius (largest eigenvalue) for each layer and overall.","examples":[{"community":2.64,"home":2.41,"overall":12.34,"school":5.42,"work":2.28}]}},"type":"object","required":["population_name","contact_source","layers","age_groups"],"title":"ContactMatrixResponse","description":"Response containing contact matrices for a population."},"CustomPopulationConfig":{"properties":{"source":{"type":"string","const":"custom","title":"Source","description":"Defines age groups and contact matrices inline."},"name":{"type":"string","title":"Name","description":"Display label for this population.","default":"Custom Population"},"age_groups":{"additionalProperties":{"type":"integer"},"type":"object","title":"Age Groups","description":"Age group label to population count. Insertion order defines the row/column order used by every entry in `contact_matrices`.\n- Homogeneous (single group): `{\"A\": 100000}`.\n- Two groups: `{\"A\": 100, \"B\": 100}`."},"contact_matrices":{"additionalProperties":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"object","title":"Contact Matrices","description":"Contact matrices keyed by layer name. The keys define the layer set; each matrix must be square with one row/column per `age_groups` entry, in the same order. Layer name `\"overall\"` is reserved by epydemix and rejected.\n- Homogeneous (1x1): `{\"all\": [[1.0]]}`.\n- Two groups (2x2): `{\"all\": [[0.2, 0.3], [0.3, 0.2]]}`."}},"type":"object","required":["source","age_groups","contact_matrices"],"title":"CustomPopulationConfig","description":"Fully custom population."},"FlatCountRollout":{"properties":{"type":{"type":"string","const":"flat_count","title":"Type","description":"Discriminator. The only rollout strategy supported in v1.","default":"flat_count"},"daily_doses":{"type":"number","exclusiveMinimum":0.0,"title":"Daily Doses","description":"Doses delivered per day. Naturally capped per group by the available source-compartment population at each step."}},"type":"object","required":["daily_doses"],"title":"FlatCountRollout","description":"Constant daily dose count across the campaign window.\n\nDoses are split across `target_age_groups` (on the parent campaign)\nproportional to the current source-compartment population in each group\nat every simulation step. The multinomial draw inside the simulator\nnaturally caps each group's transitions at the available source pool."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status","description":"Health status.","examples":["healthy"]},"version":{"type":"string","title":"Version","description":"API version string.","examples":["0.2.2"]},"epydemix_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Epydemix Version","description":"Version of the epydemix library, or None if not available.","examples":["0.3.4"]}},"type":"object","required":["status","version"],"title":"HealthResponse","description":"Health check response schema."},"InitialConditionsConfig":{"properties":{"method":{"type":"string","enum":["percentage","absolute"],"title":"Method","description":"Method: `percentage` or `absolute`.","default":"percentage"},"initial_percentages":{"anyOf":[{"additionalProperties":{"type":"number"},"type":"object"},{"type":"null"}],"title":"Initial Percentages","description":"Percentage (0-100, not a fraction) of the population in each compartment. Remainder goes to the first compartment.\n- Example: `{\"I\": 0.01, \"R\": 10.0}` puts 0.01% in `I` and 10% in `R`."},"compartments":{"anyOf":[{"additionalProperties":{"items":{"type":"number"},"type":"array"},"type":"object"},{"type":"null"}],"title":"Compartments","description":"Absolute counts per compartment per age group. Required when method is `absolute`. Each list must have one entry per age group, in the same order as `population.age_groups`.\n- Example (two age groups): `{\"Susceptible\": [9900, 9990], \"Infected\": [100, 10]}`."}},"type":"object","title":"InitialConditionsConfig","description":"Initial conditions for compartments."},"InterventionConfig":{"properties":{"layer_name":{"type":"string","title":"Layer Name","description":"Contact layer to modify, e.g. `school`, `work`."},"start_date":{"type":"string","title":"Start Date","description":"Start date in `YYYY-MM-DD` format."},"end_date":{"type":"string","title":"End Date","description":"End date in `YYYY-MM-DD` format."},"reduction_factor":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Reduction Factor","description":"Multiplier for contacts. `0.2` = reduce to 20% of normal."},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Optional name for this intervention."}},"type":"object","required":["layer_name","start_date","end_date","reduction_factor"],"title":"InterventionConfig","description":"A contact reduction intervention applied to a specific layer during a time period."},"ModelConfig":{"properties":{"preset":{"anyOf":[{"type":"string","enum":["SIR","SEIR","SIS","V-SEIHR"]},{"type":"null"}],"title":"Preset","description":"Predefined model preset. Auto-configures compartments and transitions.\n- `SIR`: Susceptible-Infected-Recovered\n- `SEIR`: Susceptible-Exposed-Infected-Recovered\n- `SIS`: Susceptible-Infected-Susceptible\n- `V-SEIHR`: Vaccinated SEIHR with parallel unvaccinated/vaccinated compartments. Use together with the `vaccination` block.\nWhen using a preset, you can still override default parameter values via `parameters`."},"compartments":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Compartments","description":"List of compartment names for a custom model. Required if no preset.\n- Example: `[\"S\", \"E\", \"I\", \"R\", \"H\"]`."},"parameters":{"additionalProperties":{"anyOf":[{"type":"number"},{"items":{"type":"number"},"type":"array"},{"type":"string"}]},"type":"object","title":"Parameters","description":"Model parameters as key-value pairs. Each value is one of:\n- scalar `float`: uniform constant rate.\n- `list[float]`: age-varying (length must match resolved population age groups).\n- `str`: arithmetic expression over other parameter names, e.g. `\"(1 - p_h) * gamma\"`. Evaluated after scalars, age-varying values, and `parameter_transforms`, in dependency order. Only arithmetic operators are supported (`+`, `-`, `*`, `/`, `//`, `**`, `%`, unary `+`/`-`); no function calls, attribute access, subscripts, or comparisons. Source-parameter shapes propagate via numpy broadcasting, so a calculated parameter inherits time- or age-variation from its sources automatically. Calculated parameters cannot be the target of `parameter_transforms` (apply transforms to the source instead). Expressions can also reference reserved SCREAMING_SNAKE_CASE names derived from the model state, currently:\n- `CONTACT_MATRIX_EIGENVALUE_ALL`: dominant eigenvalue of the sum of all contact-matrix layers. Useful for R0 calibration, e.g. `{\"transmission_rate\": \"R0 * gamma / CONTACT_MATRIX_EIGENVALUE_ALL\"}`. User parameter names cannot collide with these reserved names.\nFor presets, scalar/list values override the preset defaults. For custom models, all parameter names used in transitions must be defined here. Examples:\n- Scalar parameter: `{\"transmission_rate\": 0.3, \"recovery_rate\": 0.1}`.\n- Age-varying parameter: `{\"transmission_rate\": [0.35, 0.30, 0.25]}`.\n- Calculated parameter: `{\"p_h\": 0.05, \"gamma\": 0.1, \"recovery_rate\": \"(1 - p_h) * gamma\"}`."},"transitions":{"anyOf":[{"items":{"$ref":"#/components/schemas/TransitionConfig"},"type":"array"},{"type":"null"}],"title":"Transitions","description":"List of transitions between compartments. Required if no preset.\nEach transition defines how individuals move from one compartment to another."}},"type":"object","title":"ModelConfig","description":"Epidemic model configuration. Use `preset` for a built-in model (SIR, SEIR, SIS), or provide `compartments`, `parameters`, and `transitions` for a custom model."},"ModelMetadata":{"properties":{"preset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preset","description":"Preset name if a preset was used.","examples":["SIR"]},"compartments":{"items":{"type":"string"},"type":"array","title":"Compartments","description":"Compartment names in the model.","examples":[["Susceptible","Infected","Recovered"]]}},"type":"object","required":["compartments"],"title":"ModelMetadata","description":"Model section of simulation metadata. Mirrors the `model` section of the request."},"OutputConfig":{"properties":{"quantiles":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Quantiles","description":"Quantiles to compute for trajectories and summary. Default: `[0.025, 0.05, 0.25, 0.5, 0.75, 0.95, 0.975]`."},"include_trajectories":{"type":"boolean","title":"Include Trajectories","description":"Include raw per-run trajectory data in the response. Can be large.","default":false},"include_parameters":{"type":"boolean","title":"Include Parameters","description":"Include the effective per-step parameter arrays under `results.parameters`. Useful for plotting parameters such as `transmission_rate` after balcan/scale/override transforms have been applied. Off by default.","default":false},"compartments":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Compartments","description":"Compartments to include in the trajectory section. Default: all. Does not affect `summary`."},"transitions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Transitions","description":"Transitions to include in the trajectory section. Default: all. Does not affect `summary`."},"age_groups":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Age Groups","description":"Age groups to include in both trajectories and summary, e.g. `[\"0-4\", \"5-19\", \"total\"]`. Default: all age groups plus `total`."},"summary":{"anyOf":[{"$ref":"#/components/schemas/SummaryConfig"},{"type":"null"}],"description":"Summary statistics configuration. Omit to return the default summary."}},"type":"object","title":"OutputConfig","description":"Output configuration. Everything is optional; defaults return all compartments, all transitions, all age groups (including `total`), all standard quantiles, and a populated `summary`."},"OverrideTransform":{"properties":{"target_parameter":{"type":"string","title":"Target Parameter","description":"Name of the model parameter to transform. Must already be defined in `model.parameters`."},"method":{"type":"string","const":"override","title":"Method"},"start_date":{"type":"string","title":"Start Date","description":"Window start, `YYYY-MM-DD`."},"end_date":{"type":"string","title":"End Date","description":"Window end, `YYYY-MM-DD`. Must be `>= start_date`."},"value":{"anyOf":[{"type":"number"},{"items":{"type":"number"},"type":"array"}],"title":"Value","description":"Absolute replacement value during the window. Scalar for uniform, or a list of one value per age group (length must match the resolved population)."}},"type":"object","required":["target_parameter","method","start_date","end_date","value"],"title":"OverrideTransform","description":"Absolute value override during a date window.\n\nReplaces the parameter wholesale during `[start_date, end_date]`. Applied\nlast in the transform pass, so an override always wins for its window\nregardless of where it appears in the list. The override is baked into\n`model.parameters`, so calculated parameters that reference the target\npick up the overridden value automatically (the same as `balcan` /\n`scale`)."},"ParameterResults":{"properties":{"dates":{"items":{"type":"string"},"type":"array","title":"Dates","description":"Dates corresponding to values, matching the simulator's internal grid.","examples":[["2024-01-01","2024-01-02","2024-01-03"]]},"data":{"additionalProperties":{"additionalProperties":{"items":{"type":"number"},"type":"array"},"type":"object"},"type":"object","title":"Data","description":"Nested structure: `parameter_name -> age_group -> [values per date]`. Scalar parameters and time-varying scalars are broadcast across all age groups; age-varying parameters report each group separately. Override windows are baked into the returned arrays so they reflect what actually drove the simulation.","examples":[{"recovery_rate":{"0-4":[0.1,0.1,0.1],"5-17":[0.1,0.1,0.1]},"transmission_rate":{"0-4":[0.3,0.299,0.298],"5-17":[0.3,0.299,0.298]}}]}},"type":"object","required":["dates","data"],"title":"ParameterResults","description":"Effective parameter values used during the simulation, broadcast to per-step\narrays. Useful for plotting `transmission_rate` vs. time after seasonality, scaling,\nor override transforms have been applied. Only present if `include_parameters` was true."},"PeakStatistic":{"properties":{"quantiles":{"additionalProperties":{"type":"number"},"type":"object","title":"Quantiles","description":"Peak value per quantile, e.g. `{\"0.025\": ..., \"0.5\": ..., \"0.975\": ...}`.","examples":[{"0.025":12200000.0,"0.5":12400000.0,"0.975":12600000.0}]},"peak_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Peak Date","description":"Date of the peak from the median trajectory.","examples":["2024-02-14"]}},"type":"object","required":["quantiles"],"title":"PeakStatistic","description":"Peak statistic for a compartment in one age group."},"PopulationDetail":{"properties":{"name":{"type":"string","title":"Name","description":"Population identifier.","examples":["United_States"]},"display_name":{"type":"string","title":"Display Name","description":"Human-readable name.","examples":["United States"]},"total_population":{"type":"integer","title":"Total Population","description":"Total population size.","examples":[338120586]},"age_groups":{"additionalProperties":{"type":"integer"},"type":"object","title":"Age Groups","description":"Default 5-group aggregation (epydemix `mistry_2021`/`prem_2021` coarse groups). Keys are in age-ascending order.","examples":[{"0-4":18608139,"20-49":132780169,"5-19":63540783,"50-64":63172279,"65+":60019216}]},"age_distribution":{"additionalProperties":{"type":"integer"},"type":"object","title":"Age Distribution","description":"Raw per-single-year population counts from the upstream `age_distribution.csv`. Keys are age labels (e.g. `\"0\"`..`\"83\"`, `\"84+\"`) in ascending order.","examples":[{"0":18608139,"1":18500000,"2":18400000,"83":900000,"84+":3200000}]},"contact_sources":{"items":{"type":"string"},"type":"array","title":"Contact Sources","description":"Available contact matrix sources.","examples":[["prem_2017","prem_2021","mistry_2021"]]},"default_contact_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Contact Source","description":"Default contact source for this population.","examples":["mistry_2021"]},"available_layers":{"items":{"type":"string"},"type":"array","title":"Available Layers","description":"Available contact layers (e.g. home, work, school, community).","examples":[["home","work","school","community"]]}},"type":"object","required":["name","display_name","total_population","age_groups","age_distribution","contact_sources","available_layers"],"title":"PopulationDetail","description":"Detailed information about a population."},"PopulationListResponse":{"properties":{"populations":{"items":{"$ref":"#/components/schemas/PopulationSummary"},"type":"array","title":"Populations"},"total":{"type":"integer","title":"Total","description":"Total number of populations.","examples":[152]}},"type":"object","required":["populations","total"],"title":"PopulationListResponse","description":"Response for listing all available populations."},"PopulationMetadata":{"properties":{"source":{"type":"string","enum":["builtin","custom"],"title":"Source","description":"Which population branch the request resolved to. `builtin` = loaded from the epydemix data repo; `custom` = supplied inline.","default":"builtin","examples":["builtin"]},"name":{"type":"string","title":"Name","description":"Population identifier.","examples":["United_States"]},"contacts_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contacts Source","description":"Resolved contact matrix source actually used. `null` for custom populations.","examples":["mistry_2021"]},"layers":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Layers","description":"Resolved contact layers actually used.","examples":[["home","work","school","community"]]},"age_group_mapping":{"anyOf":[{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},{"type":"null"}],"title":"Age Group Mapping","description":"Custom age group aggregation, echoed back if the request supplied one. `null` for custom populations.","examples":[{"0-19":["0-4","5-9","10-14","15-19"],"20+":["20-24","25-29","30-34"]}]},"total":{"type":"integer","title":"Total","description":"Total population size.","examples":[338120586]},"age_groups":{"additionalProperties":{"type":"integer"},"type":"object","title":"Age Groups","description":"Age group label to population count, e.g. `{\"0-4\": 18608139}`. Keys are in model (age-ascending) order.","examples":[{"0-4":18608139,"20-49":132780169,"5-19":63540783,"50-64":63172279,"65+":60019216}]},"contact_matrices":{"additionalProperties":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"object","title":"Contact Matrices","description":"Per-layer contact matrices actually used by the simulation, keyed by layer name. Row/column order matches `age_groups` insertion order.","examples":[{"all":[[1.0]]}]}},"type":"object","required":["name","total","age_groups"],"title":"PopulationMetadata","description":"Population section of simulation metadata. Mirrors the `population` section of the request and adds resolved/derived values."},"PopulationSummary":{"properties":{"name":{"type":"string","title":"Name","description":"Population identifier (e.g., 'United_States')","examples":["United_States"]},"display_name":{"type":"string","title":"Display Name","description":"Human-readable name","examples":["United States"]},"total_population":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Population","description":"Total population size","examples":[338120586]},"available_contact_sources":{"items":{"type":"string"},"type":"array","title":"Available Contact Sources","description":"Available contact matrix sources","examples":[["prem_2017","prem_2021","mistry_2021"]]}},"type":"object","required":["name","display_name"],"title":"PopulationSummary","description":"Summary information for a population."},"PresetInfo":{"properties":{"name":{"type":"string","title":"Name","description":"Preset name (e.g., 'SIR', 'SEIR')","examples":["SIR"]},"description":{"type":"string","title":"Description","description":"Description of the model.","examples":["Susceptible-Infected-Recovered compartmental model."]},"compartments":{"items":{"type":"string"},"type":"array","title":"Compartments","description":"Compartment names.","examples":[["Susceptible","Infected","Recovered"]]},"parameters":{"additionalProperties":{"anyOf":[{"type":"number"},{"items":{"type":"number"},"type":"array"}]},"type":"object","title":"Parameters","description":"Default parameter values. A list value means the default is age-stratified (one entry per age group on the resolved population).","examples":[{"recovery_rate":0.1,"transmission_rate":0.3}]},"transitions":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Transitions","description":"Transition definitions.","examples":[[{"kind":"mediated","params":["transmission_rate","Infected"],"source":"Susceptible","target":"Infected"},{"kind":"spontaneous","params":["recovery_rate"],"source":"Infected","target":"Recovered"}]]}},"type":"object","required":["name","description","compartments","parameters","transitions"],"title":"PresetInfo","description":"Information about a predefined epidemic model."},"PresetsListResponse":{"properties":{"presets":{"items":{"$ref":"#/components/schemas/PresetInfo"},"type":"array","title":"Presets"}},"type":"object","required":["presets"],"title":"PresetsListResponse","description":"Response listing all available model presets."},"ScaleTransform":{"properties":{"target_parameter":{"type":"string","title":"Target Parameter","description":"Name of the model parameter to transform. Must already be defined in `model.parameters`."},"method":{"type":"string","const":"scale","title":"Method"},"start_date":{"type":"string","title":"Start Date","description":"Window start, `YYYY-MM-DD`."},"end_date":{"type":"string","title":"End Date","description":"Window end, `YYYY-MM-DD`. Must be `>= start_date`."},"factor":{"type":"number","title":"Factor","description":"Multiplicative factor applied within `[start_date, end_date]`."}},"type":"object","required":["target_parameter","method","start_date","end_date","factor"],"title":"ScaleTransform","description":"Multiplicative scaling applied during a date window.\n\nOutside `[start_date, end_date]` the multiplier is 1.0; inside it is\n`factor`. Composes multiplicatively with other transforms on the same\nparameter in the order listed."},"SimulationConfig":{"properties":{"start_date":{"type":"string","title":"Start Date","description":"Start date in `YYYY-MM-DD` format."},"end_date":{"type":"string","title":"End Date","description":"End date in `YYYY-MM-DD` format."},"Nsim":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Nsim","description":"Number of simulation runs.","default":10},"dt":{"type":"number","exclusiveMinimum":0.0,"title":"Dt","description":"Time step in days.","default":1.0},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"Random seed for reproducibility."},"resample_frequency":{"type":"string","title":"Resample Frequency","description":"Resampling frequency. `D` = daily, `W` = weekly, `M` = monthly.","default":"D"}},"type":"object","required":["start_date","end_date"],"title":"SimulationConfig","description":"Simulation execution parameters."},"SimulationMetadata":{"properties":{"model":{"$ref":"#/components/schemas/ModelMetadata","description":"Model configuration used for the run."},"population":{"$ref":"#/components/schemas/PopulationMetadata","description":"Resolved population configuration and derived counts."},"simulation":{"$ref":"#/components/schemas/SimulationRunMetadata","description":"Simulation execution parameters used for the run."},"interventions":{"anyOf":[{"items":{"$ref":"#/components/schemas/InterventionConfig"},"type":"array"},{"type":"null"}],"title":"Interventions","description":"Contact-reduction interventions applied to the run, echoed from the request."},"parameter_transforms":{"anyOf":[{"items":{"oneOf":[{"$ref":"#/components/schemas/BalcanTransform"},{"$ref":"#/components/schemas/ScaleTransform"},{"$ref":"#/components/schemas/OverrideTransform"}],"discriminator":{"propertyName":"method","mapping":{"balcan":"#/components/schemas/BalcanTransform","override":"#/components/schemas/OverrideTransform","scale":"#/components/schemas/ScaleTransform"}}},"type":"array"},{"type":"null"}],"title":"Parameter Transforms","description":"Parameter transforms applied to the run, echoed from the request."},"vaccination":{"anyOf":[{"$ref":"#/components/schemas/VaccinationConfig-Output"},{"type":"null"}],"description":"Vaccination configuration applied to the run, echoed from the request."}},"type":"object","required":["model","population","simulation"],"title":"SimulationMetadata","description":"Metadata about the simulation run, grouped to mirror the request shape."},"SimulationRequest":{"properties":{"model":{"$ref":"#/components/schemas/ModelConfig","description":"Epidemic model configuration."},"population":{"oneOf":[{"$ref":"#/components/schemas/BuiltinPopulationConfig"},{"$ref":"#/components/schemas/CustomPopulationConfig"}],"title":"Population","description":"Population configuration. It can load preset population from epydemix, or a custom population defined inline.","discriminator":{"propertyName":"source","mapping":{"builtin":"#/components/schemas/BuiltinPopulationConfig","custom":"#/components/schemas/CustomPopulationConfig"}}},"simulation":{"$ref":"#/components/schemas/SimulationConfig"},"initial_conditions":{"anyOf":[{"$ref":"#/components/schemas/InitialConditionsConfig"},{"type":"null"}],"description":"Initial conditions. Defaults to a small infected fraction."},"interventions":{"anyOf":[{"items":{"$ref":"#/components/schemas/InterventionConfig"},"type":"array"},{"type":"null"}],"title":"Interventions","description":"Contact reduction interventions to apply."},"parameter_transforms":{"anyOf":[{"items":{"oneOf":[{"$ref":"#/components/schemas/BalcanTransform"},{"$ref":"#/components/schemas/ScaleTransform"},{"$ref":"#/components/schemas/OverrideTransform"}],"discriminator":{"propertyName":"method","mapping":{"balcan":"#/components/schemas/BalcanTransform","override":"#/components/schemas/OverrideTransform","scale":"#/components/schemas/ScaleTransform"}}},"type":"array"},{"type":"null"}],"title":"Parameter Transforms","description":"Parameter transforms applied to model parameters. Three methods are supported:\n- `balcan`: sinusoidal seasonality across the simulation timeline (multiplicative).\n- `scale`: multiplicative factor over a date window.\n- `override`: absolute replacement over a date window (scalar or per-age-group).\nMultiple transforms on the same parameter compose: `balcan` and `scale` stack multiplicatively in the order listed; `override` always wins for its date window, regardless of position in the list."},"vaccination":{"anyOf":[{"$ref":"#/components/schemas/VaccinationConfig-Input"},{"type":"null"}],"description":"Vaccination rollout. Defines the source → target flow and any number of dose-count campaigns. The vaccinated compartment structure and vaccine efficacy (`VE_S`, `VE_H`) are defined in the model (either via the `V-SEIHR` preset, or by supplying a custom model with vaccinated twin compartments and calculated parameters)."},"output":{"anyOf":[{"$ref":"#/components/schemas/OutputConfig"},{"type":"null"}],"description":"Output configuration. Defaults to all compartments/transitions with standard quantiles."}},"type":"object","required":["model","population","simulation"],"title":"SimulationRequest","description":"Complete simulation request."},"SimulationResponse":{"properties":{"simulation_id":{"type":"string","title":"Simulation Id","description":"Unique identifier for this simulation run.","examples":["sim_c9617343b215"]},"status":{"type":"string","enum":["completed","failed"],"title":"Status","description":"Whether the simulation completed successfully.","examples":["completed"]},"metadata":{"$ref":"#/components/schemas/SimulationMetadata","description":"Metadata about the simulation run."},"results":{"anyOf":[{"$ref":"#/components/schemas/SimulationResultsData"},{"type":"null"}],"description":"Simulation results. Null if status is `failed`."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Error message if status is `failed`.","examples":[null]}},"type":"object","required":["simulation_id","status","metadata"],"title":"SimulationResponse","description":"Complete simulation response."},"SimulationResultsData":{"properties":{"compartments":{"$ref":"#/components/schemas/CompartmentResults"},"transitions":{"$ref":"#/components/schemas/TransitionResults"},"summary":{"anyOf":[{"$ref":"#/components/schemas/SummaryResults"},{"type":"null"}]},"trajectories":{"anyOf":[{"$ref":"#/components/schemas/TrajectoriesResults"},{"type":"null"}],"description":"Raw trajectory data. Only present if `include_trajectories` was true."},"parameters":{"anyOf":[{"$ref":"#/components/schemas/ParameterResults"},{"type":"null"}],"description":"Effective per-step parameter arrays. Only present if `include_parameters` was true."}},"type":"object","required":["compartments","transitions"],"title":"SimulationResultsData","description":"All simulation results."},"SimulationRunMetadata":{"properties":{"start_date":{"type":"string","title":"Start Date","description":"Simulation start date.","examples":["2024-01-01"]},"end_date":{"type":"string","title":"End Date","description":"Simulation end date.","examples":["2024-06-01"]},"Nsim":{"type":"integer","title":"Nsim","description":"Number of simulation runs.","examples":[10]},"dt":{"type":"number","title":"Dt","description":"Time step in days.","examples":[1.0]},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"Random seed used.","examples":[42]},"resample_frequency":{"type":"string","title":"Resample Frequency","description":"Resampling frequency.","examples":["D"]}},"type":"object","required":["start_date","end_date","Nsim","dt","resample_frequency"],"title":"SimulationRunMetadata","description":"Simulation section of metadata. Mirrors the `simulation` section of the request."},"StatisticQuantiles":{"properties":{"quantiles":{"additionalProperties":{"type":"number"},"type":"object","title":"Quantiles","description":"Quantile to value mapping, e.g. `{\"0.025\": ..., \"0.5\": ..., \"0.975\": ...}`.","examples":[{"0.025":213000000.0,"0.5":215000000.0,"0.975":217000000.0}]}},"type":"object","required":["quantiles"],"title":"StatisticQuantiles","description":"Quantile values for a summary statistic, keyed by quantile string (e.g. `0.5`)."},"SummaryConfig":{"properties":{"peak_compartments":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Peak Compartments","description":"By default, peak statistics are returned for every compartment. Pass a list to narrow the response, e.g. `[\"Infected\"]`, or pass `[]` to explicitly skip returning this summary. Per-quantile peak values and the median-trajectory peak date are returned for each included age group."},"total_transitions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Total Transitions","description":"By default, cumulative totals are returned for every transition. Pass a list to narrow the response, e.g. `[\"Susceptible_to_Infected\"]`, or pass `[]` to explicitly skip returning this summary. Per-quantile total event counts are returned for each included age group."}},"type":"object","title":"SummaryConfig","description":"Configuration for summary statistics.\n\nSummary is returned by default for every compartment and transition, broken\ndown by age group and by the quantiles requested in `output.quantiles`.\nUse the fields below to narrow that down."},"SummaryResults":{"properties":{"peaks":{"anyOf":[{"additionalProperties":{"additionalProperties":{"$ref":"#/components/schemas/PeakStatistic"},"type":"object"},"type":"object"},{"type":"null"}],"title":"Peaks","description":"Peak statistics: `compartment -> age_group -> {quantiles, peak_date}`.","examples":[{"Infected":{"0-4":{"peak_date":"2024-02-13","quantiles":{"0.025":410000.0,"0.5":420000.0,"0.975":435000.0}},"total":{"peak_date":"2024-02-14","quantiles":{"0.025":12200000.0,"0.5":12400000.0,"0.975":12600000.0}}}}]},"totals":{"anyOf":[{"additionalProperties":{"additionalProperties":{"$ref":"#/components/schemas/StatisticQuantiles"},"type":"object"},"type":"object"},{"type":"null"}],"title":"Totals","description":"Cumulative transition totals: `transition -> age_group -> {quantiles}`.","examples":[{"Susceptible_to_Infected":{"0-4":{"quantiles":{"0.025":11700000.0,"0.5":11800000.0,"0.975":11900000.0}},"total":{"quantiles":{"0.025":213000000.0,"0.5":215000000.0,"0.975":217000000.0}}}}]}},"type":"object","title":"SummaryResults","description":"Summary statistics of the simulation."},"TrajectoriesResults":{"properties":{"dates":{"items":{"type":"string"},"type":"array","title":"Dates","description":"Dates corresponding to values.","examples":[["2024-01-01","2024-01-02","2024-01-03"]]},"runs":{"items":{"$ref":"#/components/schemas/TrajectoryData"},"type":"array","title":"Runs","description":"Data for each simulation run."}},"type":"object","required":["dates","runs"],"title":"TrajectoriesResults","description":"Raw trajectories from all simulation runs."},"TrajectoryData":{"properties":{"compartments":{"additionalProperties":{"additionalProperties":{"items":{"type":"number"},"type":"array"},"type":"object"},"type":"object","title":"Compartments","description":"Compartment values: `{compartment: {age_group: [values]}}`.","examples":[{"Infected":{"total":[621391.0,3043170.0,5812500.0]},"Recovered":{"total":[0.0,20000.0,145000.0]},"Susceptible":{"total":[337330136.0,334286966.0,331103421.0]}}]},"transitions":{"additionalProperties":{"additionalProperties":{"items":{"type":"number"},"type":"array"},"type":"object"},"type":"object","title":"Transitions","description":"Transition counts: `{transition: {age_group: [values]}}`.","examples":[{"Infected_to_Recovered":{"total":[0.0,20000.0,145000.0]},"Susceptible_to_Infected":{"total":[621391.0,3043170.0,5812500.0]}}]}},"type":"object","required":["compartments","transitions"],"title":"TrajectoryData","description":"Raw trajectory data for a single simulation run."},"TransitionConfig":{"properties":{"source":{"type":"string","title":"Source","description":"Source compartment name."},"target":{"type":"string","title":"Target","description":"Target compartment name."},"kind":{"type":"string","enum":["spontaneous","mediated"],"title":"Kind","description":"Type of transition.\n- `spontaneous`: rate is a fixed parameter (e.g. recovery, incubation).\n- `mediated`: rate depends on the proportion of a mediating compartment (e.g. transmission driven by contact with infectious individuals)."},"params":{"items":{"type":"string"},"type":"array","title":"Params","description":"Parameter name(s) governing this transition.\n- Spontaneous: a single parameter name (the rate), e.g. `[\"recovery_rate\"]`.\n- Mediated: a two-element list `[rate_param, mediating_compartment]`, e.g. `[\"transmission_rate\", \"I\"]`.\nA single string is also accepted and will be wrapped into a list."}},"type":"object","required":["source","target","kind","params"],"title":"TransitionConfig","description":"A single transition between compartments. Transitions define how individuals move between compartments, either spontaneously at a fixed rate or mediated by contact with another compartment."},"TransitionResults":{"properties":{"dates":{"items":{"type":"string"},"type":"array","title":"Dates","description":"Dates corresponding to values.","examples":[["2024-01-01","2024-01-02","2024-01-03"]]},"data":{"additionalProperties":{"additionalProperties":{"additionalProperties":{"items":{"type":"number"},"type":"array"},"type":"object"},"type":"object"},"type":"object","title":"Data","description":"Nested structure: `transition -> age_group -> quantile -> [values]`.","examples":[{"Susceptible_to_Infected":{"total":{"0.025":[621344.45,3041835.25,5800000.0],"0.5":[621391.0,3043170.0,5812500.0],"0.975":[621437.55,3044504.75,5825000.0]}}}]}},"type":"object","required":["dates","data"],"title":"TransitionResults","description":"Transition count quantiles."},"VaccinationCampaignConfig":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Optional label echoed back in metadata."},"start_date":{"type":"string","title":"Start Date","description":"Campaign start (`YYYY-MM-DD`), inclusive."},"end_date":{"type":"string","title":"End Date","description":"Campaign end (`YYYY-MM-DD`), inclusive. Must be `>= start_date`."},"target_age_groups":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Target Age Groups","description":"Age group labels to target, e.g. `[\"20-49\", \"65+\"]`. `null` = all groups."},"rollout":{"oneOf":[{"$ref":"#/components/schemas/FlatCountRollout"}],"title":"Rollout","description":"Dose-schedule strategy. The `type` discriminator selects the shape; remaining fields are strategy-specific. v1 supports `flat_count`.","discriminator":{"propertyName":"type","mapping":{"flat_count":"#/components/schemas/FlatCountRollout"}}}},"type":"object","required":["start_date","end_date","rollout"],"title":"VaccinationCampaignConfig","description":"One vaccination campaign: a time window, an age target, and a rollout strategy."},"VaccinationConfig-Input":{"properties":{"flows":{"anyOf":[{"items":{"$ref":"#/components/schemas/CompartmentFlow"},"type":"array"},{"type":"null"}],"title":"Flows","description":"Compartments competing for doses, each with an optional `target`. Sources without a `target` act as dose sinks (contribute to the rate denominator but emit no transition). At least one flow must have a non-null `target`. Defaults to `[{source: 'Susceptible', target: 'Susceptible_vax'}]` for the `V-SEIHR` preset; required for custom models."},"campaigns":{"items":{"$ref":"#/components/schemas/VaccinationCampaignConfig"},"type":"array","title":"Campaigns","description":"Campaign windows. Each carries its own rollout strategy; multiple campaigns may overlap and mix strategies. Their per-step dose schedules add."}},"additionalProperties":false,"type":"object","title":"VaccinationConfig","description":"Vaccination rollout block.\n\n`flows` declares which compartments compete for doses and which of them\nactually transition. For the `V-SEIHR` preset it defaults to\n`[{source: 'Susceptible', target: 'Susceptible_vax'}]`. Custom models\nmust supply it explicitly."},"VaccinationConfig-Output":{"properties":{"flows":{"anyOf":[{"items":{"$ref":"#/components/schemas/CompartmentFlow"},"type":"array"},{"type":"null"}],"title":"Flows","description":"Compartments competing for doses, each with an optional `target`. Sources without a `target` act as dose sinks (contribute to the rate denominator but emit no transition). At least one flow must have a non-null `target`. Defaults to `[{source: 'Susceptible', target: 'Susceptible_vax'}]` for the `V-SEIHR` preset; required for custom models."},"campaigns":{"items":{"$ref":"#/components/schemas/VaccinationCampaignConfig"},"type":"array","title":"Campaigns","description":"Campaign windows. Each carries its own rollout strategy; multiple campaigns may overlap and mix strategies. Their per-step dose schedules add."}},"additionalProperties":false,"type":"object","title":"VaccinationConfig","description":"Vaccination rollout block.\n\n`flows` declares which compartments compete for doses and which of them\nactually transition. For the `V-SEIHR` preset it defaults to\n`[{source: 'Susceptible', target: 'Susceptible_vax'}]`. Custom models\nmust supply it explicitly."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"tags":[{"name":"Simulations","description":"Run stochastic epidemic simulations using preset or custom compartmental models."},{"name":"Populations","description":"Browse available populations, age group demographics, and contact matrices."},{"name":"Model Presets","description":"List built-in epidemic models (SIR, SEIR, SIS) with their compartments, parameters, and transitions."}]}