{"openapi":"3.0.3","info":{"title":"Lightcast Input-Output API (US I/O)","description":"The U.S. Input-Output Social Accounting Matrix (SAM) service. It exposes\neconomic impact, requirements, spending, and model metadata endpoints for\nSAM dataruns.\n\n## Path shape\n\nU.S. data paths follow `/io/us/{datarun}/{year}/{service}`.\nTruncating the path lists the valid values for the next segment: `GET /io/us`\nlists dataruns, `GET /io/us/{datarun}` lists years, and\n`GET /io/us/{datarun}/{year}` lists the services (producers) available.\n\n## Content negotiation\n\nThe response format of a *successful* response is chosen from the `Accept`\nheader:\n\n| `Accept`           | Response body      |\n|--------------------|--------------------|\n| (absent)           | `text/csv`         |\n| `text/csv`         | `text/csv`         |\n| `application/json` | `application/json` |\n| `text/plain`       | `text/plain`       |\n| `text/html`        | `text/plain`       |\n| `*/*`              | `application/json` |\n\nAn `Accept` header containing none of the above yields `400`.\n`GET /io/us/docs` ignores `Accept` entirely and always responds with\n`text/markdown; charset=UTF-8`.\n\nContent negotiation applies to success responses only — see **Errors**.\n\n## Request tracing\n\nEvery request may carry an `X-Correlation-ID` header. It is echoed in the\n`X-Correlation-ID` response header on success; when the request does not\nsupply one, the service generates a UUID. The header is *not* set on error\nresponses. These headers apply to every operation and are therefore not\nrepeated on each one below.\n\n## Inputs\n\nData-producing endpoints accept their inputs either as a JSON request body\nor as query-string parameters, and the two are merged. `areas` is accepted\nas a single comma-separated query parameter alongside an optional `type`;\nevery other query parameter must appear at most once.\n\nA request body is therefore optional wherever the query string can carry\nevery input the endpoint needs — `?areas=16057` alone is a complete request\nto most data endpoints. It is required wherever an input is an array or an\nobject, because a query-string value is always read as a single string. That\nmakes the body mandatory for `scenario`, `bulk`, and `batch_requirements`,\nand for the `metrics`, `forSectors`, `sectors`, and `limit_sectors` inputs\nwherever they are used.\n\nInput validation is strict: **any property the endpoint does not define is\nrejected with `400`**. Because query parameters are validated as part of the\nsame object, an unrecognised query parameter fails the request the same way.\n\n**`GET` cannot carry a request body.** On `GET`, every input must come from\nthe query string, so any endpoint that needs an array or object input is\ndocumented as `POST`-only below.\n\n`datarun`, `year`, and service path segments are case-insensitive.\n\n## Errors\n\nApplication error bodies are a JSON string containing the message, served\nas `text/plain` regardless of `Accept`. Kong rejects missing or insufficient\nOAuth credentials before the request reaches the application; its auth\nerrors are JSON objects served as `application/json`.\n\nTwo further statuses apply uniformly to every operation and are therefore\nnot repeated below:\n\n* `405` — the request method is not `GET`, `POST`, or `DELETE`.\n* `413` — the request body exceeds 100 MB.","version":"1.0.0","contact":{"name":"Lightcast Customer Support @ customersupport@lightcast.io"}},"servers":[{"url":"https://api.lightcast.io","description":"Production"},{"url":"https://qa.api.lightcast.io","description":"QA"}],"security":[{"OAuth2":["us-io"]}],"tags":[{"name":"Service","description":"Health, documentation, and metadata endpoints."},{"name":"Metadata","description":"Dataruns, years, codes, and available services."},{"name":"Data","description":"Model-producing endpoints."}],"paths":{"/io/us/status":{"get":{"tags":["Service"],"summary":"Service health","description":"Returns `OK` when at least one datarun is available and every available\ndatarun has at least one year of data. The GET route is public.","operationId":"getStatus","security":[],"responses":{"200":{"$ref":"#/components/responses/StatusOk"},"400":{"$ref":"#/components/responses/BadInput"},"403":{"$ref":"#/components/responses/ServiceUnavailable"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/status/us":{"get":{"tags":["Service"],"summary":"Service health (country-scoped alias)","description":"Alias of `/io/us/status`; the response is identical. The GET route is\npublic.","operationId":"getStatusUs","security":[],"responses":{"200":{"$ref":"#/components/responses/StatusOk"},"400":{"$ref":"#/components/responses/BadInput"},"403":{"$ref":"#/components/responses/ServiceUnavailable"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/docs":{"get":{"tags":["Service"],"summary":"User's guide","description":"Returns the Input-Output API user's guide as Markdown, with live\nexamples (current dataruns, years, and codes) interpolated from the\ndeployed data. Requires no authentication and always responds with\n`text/markdown; charset=UTF-8`, ignoring `Accept`.\n\nThe guide remains available even when live examples cannot be read; in\nthat case representative sample values are shown in their place and\nlabelled as such.","operationId":"getDocs","security":[],"responses":{"200":{"description":"Markdown documentation.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"text/markdown":{"schema":{"type":"string"}}}},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us":{"get":{"tags":["Metadata"],"summary":"List dataruns","description":"Available SAM dataruns, newest first.","operationId":"listDataruns","responses":{"200":{"$ref":"#/components/responses/DatarunList"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Metadata"],"summary":"List dataruns","description":"Identical to `GET /io/us`.","operationId":"listDatarunsPost","responses":{"200":{"$ref":"#/components/responses/DatarunList"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}":{"parameters":[{"$ref":"#/components/parameters/Datarun"}],"get":{"tags":["Metadata"],"summary":"List years","description":"Years of data available in the given datarun.","operationId":"listYears","responses":{"200":{"$ref":"#/components/responses/YearList"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Metadata"],"summary":"List years","operationId":"listYearsPost","responses":{"200":{"$ref":"#/components/responses/YearList"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/codes":{"parameters":[{"$ref":"#/components/parameters/Datarun"}],"get":{"tags":["Metadata"],"summary":"List sector codes","description":"All SAM account codes and their definitions for the datarun, ordered by\nthe model's canonical account ordering.","operationId":"listCodes","responses":{"200":{"$ref":"#/components/responses/CodeList"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Metadata"],"summary":"List sector codes","operationId":"listCodesPost","responses":{"200":{"$ref":"#/components/responses/CodeList"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/sources":{"parameters":[{"$ref":"#/components/parameters/Datarun"}],"get":{"tags":["Metadata"],"summary":"Data source statement","description":"Prose describing the data sources behind the MR-SAM model.","operationId":"getSources","responses":{"200":{"$ref":"#/components/responses/SourceStatement"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Metadata"],"summary":"Data source statement","operationId":"getSourcesPost","responses":{"200":{"$ref":"#/components/responses/SourceStatement"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/{year}":{"parameters":[{"$ref":"#/components/parameters/Datarun"},{"$ref":"#/components/parameters/Year"}],"get":{"tags":["Metadata"],"summary":"List data services (producers)","description":"Each data service available under this datarun/year, with its\ndescription and whether it supports multi-regional models. Supplying\nmore than one region to a service without multi-regional support is an\nerror.\n\nThe listing does not cover `eis` or `bulk`, though both are valid —\n`eis` as a `{service}` value and `bulk` at its own path below. `eis`\nsupports multi-regional models; `bulk` is single-region only.","operationId":"listProducers","responses":{"200":{"$ref":"#/components/responses/ProducerList"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Metadata"],"summary":"List data services (producers)","operationId":"listProducersPost","responses":{"200":{"$ref":"#/components/responses/ProducerList"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/{year}/{service}":{"parameters":[{"$ref":"#/components/parameters/Datarun"},{"$ref":"#/components/parameters/Year"},{"name":"service","in":"path","required":true,"description":"The data service to run. `basics` bundles several services in one\nrequest via the `metrics` array; every other value runs that single\nservice. Matching is case-insensitive.\n\nNote that `scenario`, `bulk`, `requirements`, `spending`, `econbase`,\nand `batch_requirements` are documented as their own paths below\nbecause they take additional inputs.","schema":{"type":"string","enum":["basics","a","b","bjobs","consultantmultipliers","earnings","eis","exports","grp","multipliers","ratios","rid","rpcs","sales","tpi","z"]},"example":"multipliers"}],"get":{"tags":["Data"],"summary":"Run one or more basic metrics","description":"Runs the named service, or — when the path segment is `basics` — every\nmetric listed in the request's `metrics` array, each keyed in the\nresponse by its `altName`.\n\n`A`, `B`, `BJobs`, and `Z` return full matrices and can produce very\nlarge responses; use `limit_sectors` to constrain them.\n\nOnly `ratios`, `rpcs`, `eis`, `requirements`, `spending`, and `scenario`\nsupport multi-regional models. Supplying more than one region to any\nother service is an error. `eis` supports multi-regional models even\nthough it is not included in the listing at\n`GET /io/us/{datarun}/{year}`.\n\nOn `GET`, inputs must come from the query string — see **Inputs**. Use\n`POST` for the `basics` segment, whose `metrics` array can only be\nsupplied in a body.","operationId":"runBasics","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/UnprocessableContent"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Data"],"summary":"Run one or more basic metrics","operationId":"runBasicsPost","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"requestBody":{"$ref":"#/components/requestBodies/BasicsBody"},"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/UnprocessableContent"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/{year}/scenario":{"parameters":[{"$ref":"#/components/parameters/Datarun"},{"$ref":"#/components/parameters/Year"}],"post":{"tags":["Data"],"summary":"Run a scenario","description":"Applies the given shocks to the model and returns the resulting impact\nvectors. Single-region scenarios key their change array by the empty\nstring; multi-regional scenarios key it by region name, and every region\nmust be named. The number of keys in `changes` may not exceed the number\nof regions.\n\nIn multi-regional mode every shocked sector must have non-zero sales in\nthe region it is applied to.\n\n`POST`-only: `changes` is mandatory and can only be sent in a request\nbody — see **Inputs**.","operationId":"runScenario","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"requestBody":{"$ref":"#/components/requestBodies/ScenarioBody"},"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/{year}/bulk":{"parameters":[{"$ref":"#/components/parameters/Datarun"},{"$ref":"#/components/parameters/Year"}],"post":{"tags":["Data"],"summary":"Run a bulk scenario","description":"Runs many independent single-account shocks against one region in a\nsingle request and returns a summary row per change, identified by the\nchange's `id`. Single-region only: supplying more than one region, or\nmore than one key in `changes`, is rejected with `400`. Each change may\nuse either the long field names (`id`, `account`, `amount`, `unit`) or\ntheir single-letter forms (`i`, `a`, `m`, `u`). Duplicate `id` values\nare rejected with `400`.\n\n`POST`-only: `changes` is mandatory and can only be sent in a request\nbody — see **Inputs**.","operationId":"runBulkScenario","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"requestBody":{"$ref":"#/components/requestBodies/BulkBody"},"responses":{"200":{"$ref":"#/components/responses/BulkResult"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/{year}/requirements":{"parameters":[{"$ref":"#/components/parameters/Datarun"},{"$ref":"#/components/parameters/Year"}],"get":{"tags":["Data"],"summary":"Sector requirements","description":"What the selected sectors buy from other sectors, split into demand\nsatisfied inside and outside the region. Omitting `forSectors` returns\nevery sector.\n\nRegion inputs must come from the query string on `GET`; use `POST` to\nsend `forSectors` or any other array input — see **Inputs**.","operationId":"getRequirements","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Data"],"summary":"Sector requirements","operationId":"getRequirementsPost","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"requestBody":{"$ref":"#/components/requestBodies/SectorInfoBody"},"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/{year}/spending":{"parameters":[{"$ref":"#/components/parameters/Datarun"},{"$ref":"#/components/parameters/Year"}],"get":{"tags":["Data"],"summary":"Sector spending","description":"What other sectors spend on the selected sectors. Omitting `forSectors`\nreturns every sector.\n\nRegion inputs must come from the query string on `GET`; use `POST` to\nsend `forSectors` or any other array input — see **Inputs**.","operationId":"getSpending","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Data"],"summary":"Sector spending","operationId":"getSpendingPost","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"requestBody":{"$ref":"#/components/requestBodies/SectorInfoBody"},"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/{year}/econbase":{"parameters":[{"$ref":"#/components/parameters/Datarun"},{"$ref":"#/components/parameters/Year"}],"get":{"tags":["Data"],"summary":"Economic base","description":"Groups sectors (with per-sector coefficients) into analysis groups and\nreturns each group's impact on the region. Single-region only;\nmulti-regional requests are rejected with `400`.\n\nUse `POST` for any real request: `sectors` is an array and can only be\nsent in a request body — see **Inputs**. A `GET` with only a region\nsucceeds but has no groups to report on.","operationId":"getEconBase","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Data"],"summary":"Economic base","operationId":"getEconBasePost","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQuery"},{"$ref":"#/components/parameters/ClosureTypeQuery"}],"requestBody":{"$ref":"#/components/requestBodies/EconBaseBody"},"responses":{"200":{"$ref":"#/components/responses/SamData"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/io/us/{datarun}/{year}/batch_requirements":{"parameters":[{"$ref":"#/components/parameters/Datarun"},{"$ref":"#/components/parameters/Year"}],"post":{"tags":["Data"],"summary":"Requirements for many areas at once","description":"Returns pre-computed requirements rows for one sector across every area\nin a single region. Areas with no pre-computed row are absent from the\nresponse.\n\nConstraints, all enforced with `400`:\n\n* exactly one region (it may contain many areas);\n* area `type` must be `county`, `state`, or `msa` — `zip` is rejected;\n* `limit_sectors` must contain exactly one sector.\n\nUnlike every other data endpoint, the JSON response is a flat array of\nrows rather than the standard SAM result set.\n\n`POST`-only: `limit_sectors` is mandatory here and can only be sent in a\nrequest body — see **Inputs**.","operationId":"getBatchRequirements","parameters":[{"$ref":"#/components/parameters/AreasQuery"},{"$ref":"#/components/parameters/TypeQueryBatch"}],"requestBody":{"$ref":"#/components/requestBodies/BatchRequirementsBody"},"responses":{"200":{"$ref":"#/components/responses/BatchRequirements"},"400":{"$ref":"#/components/responses/BadInput"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}}},"components":{"securitySchemes":{"OAuth2":{"type":"oauth2","description":"Client-credentials OAuth 2.0, enforced by Kong. The token must carry\nevery scope required by the operation and be presented as\n`Authorization: Bearer <token>`.","flows":{"clientCredentials":{"tokenUrl":"https://auth.emsicloud.com/connect/token","scopes":{"us-io":"Access to the U.S. Input-Output API"}}}}},"parameters":{"Datarun":{"name":"datarun","in":"path","required":true,"description":"SAM datarun version, as listed by `GET /io/us`.","schema":{"type":"string"},"example":"2026.3"},"Year":{"name":"year","in":"path","required":true,"description":"Data year, as listed by `GET /io/us/{datarun}`.","schema":{"type":"string"},"example":"2024"},"AreasQuery":{"name":"areas","in":"query","required":false,"description":"Comma-separated area IDs, as an alternative to supplying `region` in the\nbody. Builds a single unnamed region. Supplying this key more than once\nis rejected with `400`.","schema":{"type":"string"},"example":"16057,16055"},"TypeQuery":{"name":"type","in":"query","required":false,"description":"Area type for `areas`. Defaults to `county`.","schema":{"type":"string","enum":["county","zip"],"default":"county"}},"TypeQueryBatch":{"name":"type","in":"query","required":false,"description":"Area type for `areas` on this endpoint. Defaults to `county`; `zip` is\nnot accepted here.","schema":{"type":"string","enum":["county","state","msa"],"default":"county"}},"ClosureTypeQuery":{"name":"closuretype","in":"query","required":false,"description":"Closure method, as an alternative to supplying it in the body.","schema":{"$ref":"#/components/schemas/ClosureType"}}},"schemas":{"ErrorMessage":{"type":"string","description":"Every error body is a bare JSON string containing the message — not an\nobject — and is served as `text/plain` regardless of `Accept`.\n\nSchema-validation failures carry an extra layer of quoting: the body\nreads `\"\\\"Unknown property 'bogus' on request object (/)\\\"\"`.","example":"Invalid sector passed: 999999"},"ClosureType":{"type":"string","description":"Closure method for the model.\n\n* `TypeI` / `Type1` / `1` / `I` — direct and indirect effects\n* `TypeII` / `Type2` / `2` / `II` — direct, indirect, and limited induced effects\n* `TypeEMSI` — Lightcast's custom closure, used by Analyst\n\nMatching is case-insensitive.","enum":["TypeI","TypeII","TypeEMSI"],"default":"TypeEMSI"},"AreaType":{"type":"string","description":"Type of the IDs in `areas`. Most endpoints accept only `county` and\n`zip`; `batch_requirements` accepts `county`, `state`, and `msa`. A type\nthe endpoint does not allow is rejected with `400`\n(`\"The area type 'State' is not allowed for this endpoint, please use\none of County,Zip\"`).\n\nThe enum gives the canonical spellings; matching is case-insensitive, so\n`County` and `COUNTY` are equally valid.","enum":["county","zip","state","msa"],"default":"county"},"Region":{"type":"object","required":["areas"],"properties":{"name":{"type":"string","description":"Region label. May be empty for a single-region request; in\nmulti-regional mode every region must be named, and a blank name is\nrejected with `400` (`\"Regions must have names for multi-regional\nmode.\"`). Names are matched case-insensitively and are how\n`scenario` keys its `changes`, so give each region a distinct name.","example":"latah"},"areas":{"type":"array","description":"Area IDs of the type given by `type`. County and state IDs are FIPS\ncodes (county IDs must be at least 4 characters, state IDs at most\n2); every ID is validated against the datarun and an unknown ID\nfails the request with `400`.","minItems":1,"items":{"type":"string"},"example":["16057"]},"type":{"$ref":"#/components/schemas/AreaType"}}},"BaseInputs":{"type":"object","required":["region"],"description":"Inputs common to every data-producing endpoint. Validation is strict:\nany property not listed here (or added by the endpoint's own schema) is\nrejected with `400`. Query-string parameters are validated as part of\nthis same object, so an unrecognised query parameter fails the same way.","properties":{"region":{"type":"array","description":"One region for a single-region model, more than one to run\nmulti-regionally. Multi-regional runs require every region to be\nnamed and are only supported by services that report `HasMR(true)`\nfrom `GET /io/us/{datarun}/{year}`. The array must not be empty.","minItems":1,"items":{"$ref":"#/components/schemas/Region"}},"closuretype":{"$ref":"#/components/schemas/ClosureType"},"limit_sectors":{"type":"array","description":"Restrict the output rows to these sectors. Codes may be given fully\nqualified (`z|111000`) or bare (`111000`), in which case the\nindustry prefix is inferred.","items":{"type":"string"},"example":["z|111000"]},"logging":{"type":"boolean","description":"Accepted for backwards compatibility. Has no effect on the response."}}},"Metric":{"type":"object","required":["name","altName"],"properties":{"name":{"type":"string","description":"Name of the service to run.","example":"GRP"},"altName":{"type":"string","description":"Non-empty key under which this metric's results appear in the\nresponse. Must be unique within the request.","example":"grp"}}},"BasicsInputs":{"allOf":[{"$ref":"#/components/schemas/BaseInputs"},{"type":"object","properties":{"metrics":{"type":"array","description":"Required when the path segment is `basics`, ignored otherwise.\nMust be non-empty and every entry must carry a unique, non-empty\n`altName`.","items":{"$ref":"#/components/schemas/Metric"}}}}]},"Change":{"type":"object","description":"A single shock. Every field is required, and each may be given under\nits long name or its single-letter alias — supply exactly one of each\npair. Omitting both is rejected with `400`\n(`\"One of ('a','account') is required on object (/)\"`), and supplying\nboth is rejected the same way\n(`\"Can only have one of ('a','account') on object (/)\"`).","allOf":[{"oneOf":[{"required":["account"]},{"required":["a"]}]},{"oneOf":[{"required":["amount"]},{"required":["m"]}]},{"oneOf":[{"required":["unit"]},{"required":["u"]}]}],"properties":{"account":{"type":"string","description":"Sector to shock. Fully qualified (`z|111000`) or bare (`111000`).","example":"111000"},"a":{"type":"string","description":"Short form of `account`."},"amount":{"type":"string","description":"Signed magnitude of the shock, as a numeric string.","example":"1000.0"},"m":{"type":"string","description":"Short form of `amount`."},"unit":{"type":"string","description":"Unit the amount is expressed in.","enum":["sales","jobs","earnings"],"example":"jobs"},"u":{"type":"string","description":"Short form of `unit`.","enum":["sales","jobs","earnings"]}}},"BulkChange":{"allOf":[{"$ref":"#/components/schemas/Change"},{"type":"object","description":"Adds a required identifier, subject to the same exactly-one-of rule\nas the inherited fields.","oneOf":[{"required":["id"]},{"required":["i"]}],"properties":{"id":{"type":"string","description":"Caller-chosen identifier echoed on the result row for this\nchange. Must be unique within the request.","example":"1"},"i":{"type":"string","description":"Short form of `id`."}}}]},"ScenarioInputs":{"allOf":[{"$ref":"#/components/schemas/BaseInputs"},{"type":"object","required":["changes"],"properties":{"changes":{"type":"object","description":"Change arrays keyed by region name — the empty string for a\nsingle unnamed region. The number of keys may not exceed the\nnumber of regions.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/Change"}}}}}]},"BulkInputs":{"allOf":[{"$ref":"#/components/schemas/BaseInputs"},{"type":"object","required":["changes"],"properties":{"changes":{"type":"object","description":"Exactly one keyed, non-empty array of changes; the key is\nconventionally the empty string.","maxProperties":1,"additionalProperties":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/BulkChange"}}}}}]},"SectorInfoInputs":{"allOf":[{"$ref":"#/components/schemas/BaseInputs"},{"type":"object","properties":{"forSectors":{"type":"array","description":"Sectors to report on. When omitted, every sector is returned.","items":{"type":"string"},"example":["111000","z|112000"]}}}]},"EconSector":{"type":"object","required":["group","sector","coef"],"properties":{"group":{"type":"string","description":"Analysis group this sector contributes to.","example":"Ag"},"sector":{"type":"string","description":"Sector code, fully qualified or bare.","example":"111000"},"coef":{"type":"number","format":"double","description":"Share of the sector attributed to the group. Must be written as a\nJSON floating-point literal: an integer such as `1` is rejected with\n`400` (`\"Property should be of type real\"`). Write `1.0`.","example":0.5}}},"EconBaseInputs":{"allOf":[{"$ref":"#/components/schemas/BaseInputs"},{"type":"object","properties":{"sectors":{"type":"array","items":{"$ref":"#/components/schemas/EconSector"}}}}]},"BatchRequirementsInputs":{"allOf":[{"$ref":"#/components/schemas/BaseInputs"},{"type":"object","required":["limit_sectors"],"description":"`limit_sectors` is required here and must contain exactly one\nsector."}]},"ProducerInfo":{"type":"object","properties":{"name":{"type":"string","description":"Service name, usable as the `{service}` path segment.","example":"Multipliers"},"description":{"type":"string","example":"Calculate sales, jobs and earnings multipliers."},"hasMR":{"type":"boolean","description":"Whether the service supports multi-regional models. Services without\na multi-regional implementation fail with `500` when more than one\nregion is supplied."}}},"CodeDefinition":{"type":"object","description":"One row of the SAM account dimension table.","properties":{"child":{"type":"string","description":"Fully qualified sector code.","example":"z|111000"},"category":{"type":"string","example":"Industry"},"subAccountName":{"type":"string"},"detailedAccountName":{"type":"string","example":"Oilseed and grain farming"}}},"BatchRequirementsRow":{"type":"object","properties":{"area":{"type":"string","description":"Area ID the row belongs to.","example":"16075"},"sector":{"type":"string","example":"z|111000"},"total":{"type":"number","format":"double","example":34234},"in_region":{"type":"number","format":"double","example":234},"out_region":{"type":"number","format":"double","example":2344}}},"SamResultSetVector":{"type":"object","description":"A named vector of values, keyed by sector code. Demographic codes are\nemitted under their long names.","additionalProperties":{"type":"number","format":"double"},"example":{"z|111000":366640,"vl|19-1011":128546}},"SamResultSet":{"type":"object","description":"One slice of results: a `bSameSizedVectors` flag plus one\n`SamResultSetVector` per named vector. What the slice represents\ndepends on the model — see `SamProducerResultSet`.","properties":{"bSameSizedVectors":{"type":"boolean","description":"Whether every vector in this set covers the same sectors."}},"additionalProperties":{"$ref":"#/components/schemas/SamResultSetVector"}},"SamProducerResultSet":{"type":"object","description":"Output of one producer: a `name` plus a set of `SamResultSet` objects.\n**How those are keyed depends on whether the run was\nmulti-regional**, and clients must handle both:\n\n* Single-region — one key per data year, e.g. `\"2024\"`.\n* Multi-regional — one key per region, using the region `name` in\n  lower case, e.g. `\"latah\"`. `requirements`, `spending`, and `rpcs`\n  additionally emit one key per ordered region pair, written\n  `\"<a>|<b>\"` (e.g. `\"latah|whitman\"`), holding the off-diagonal\n  region-block vectors. For `requirements` the first name is the\n  supplying region and the second the consuming one. The data year does\n  not appear as a key at all.\n\nRegion names are returned in lower case, so a region declared as `Latah`\nis returned under `latah`.\n\nFor `requirements`, each region's totals reconcile as\n`Total Requirements = Local Absorption + Σ Cross-Region Absorption\ninto that region + Out of greater region imports`.","properties":{"name":{"type":"string","description":"Identifier of the producer that generated this result set.","example":"producers.RegRequirements"}},"additionalProperties":{"$ref":"#/components/schemas/SamResultSet"}},"SamData":{"type":"object","description":"The standard data response. Keys are the `altName` of each requested\nmetric, or the empty string for endpoints that run a single producer.","additionalProperties":{"$ref":"#/components/schemas/SamProducerResultSet"}}},"requestBodies":{"BasicsBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicsInputs"},"examples":{"singleService":{"summary":"One service, single region","value":{"region":[{"name":"Latah","areas":["16057"],"type":"county"}]}},"basicsBundle":{"summary":"Several metrics in one request","value":{"region":[{"name":"Latah","areas":["16057"],"type":"county"}],"metrics":[{"altName":"grp","name":"GRP"},{"altName":"tpi","name":"TPI"}],"limit_sectors":["z|111000"]}},"multiRegional":{"summary":"Multi-regional basics","value":{"region":[{"name":"Whitman","areas":["53075"],"type":"county"},{"name":"Latah","areas":["16057"],"type":"county"}],"metrics":[{"altName":"Ratios","name":"Ratios"},{"altName":"Rpcs","name":"Rpcs"}],"closuretype":"TypeI"}}}}}},"ScenarioBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScenarioInputs"},"examples":{"singleRegion":{"summary":"Single-region scenario","value":{"region":[{"areas":["16057"],"type":"county"}],"changes":{"":[{"account":"111000","amount":"1000.0","unit":"jobs"},{"account":"z|112000","amount":"2000.0","unit":"earnings"}]},"closuretype":"TypeEMSI"}},"multiRegional":{"summary":"Multi-regional scenario","value":{"region":[{"name":"latah","areas":["16057"],"type":"county"},{"name":"whitman","areas":["53075"],"type":"county"}],"changes":{"latah":[{"account":"111000","amount":"-1000.0","unit":"jobs"}],"whitman":[{"account":"z|111000","amount":"1000.0","unit":"jobs"}]},"closuretype":"TypeII"}}}}}},"BulkBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkInputs"},"examples":{"longNames":{"summary":"Long field names","value":{"region":[{"name":"","areas":["16057"],"type":"county"}],"changes":{"":[{"id":"1","account":"111000","amount":"1000.0","unit":"jobs"},{"id":"2","account":"z|112000","amount":"2000.0","unit":"earnings"}]}}},"shortNames":{"summary":"Abbreviated field names","value":{"region":[{"name":"","areas":["16057"],"type":"county"}],"changes":{"":[{"i":"1","a":"111000","m":"1000.0","u":"jobs"}]}}}}}}},"SectorInfoBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectorInfoInputs"},"examples":{"selectedSectors":{"summary":"Specific sectors","value":{"region":[{"name":"","areas":["16057"],"type":"county"}],"forSectors":["111000","z|112000"]}},"allSectors":{"summary":"All sectors","value":{"region":[{"name":"","areas":["16057"],"type":"county"}]}}}}}},"EconBaseBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EconBaseInputs"},"examples":{"twoGroups":{"value":{"region":[{"name":"","areas":["16057"],"type":"county"}],"sectors":[{"group":"Ag","sector":"111000","coef":0.5},{"group":"Ag","sector":"z|112000","coef":1}]}}}}}},"BatchRequirementsBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRequirementsInputs"},"examples":{"counties":{"summary":"One sector across many counties","value":{"region":[{"name":"","areas":["16075","16057"],"type":"county"}],"limit_sectors":["z|111000"]}}}}}}},"responses":{"StatusOk":{"description":"Service is healthy.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"text/csv":{"schema":{"type":"string","example":"OK"}},"application/json":{"schema":{"type":"string","example":"OK"}},"text/plain":{"schema":{"type":"string","example":"OK"}}}},"DatarunList":{"description":"Available dataruns, newest first.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}},"example":["2026.3","2026.2"]},"text/csv":{"schema":{"type":"string"},"example":"2026.3\n2026.2\n"},"text/plain":{"schema":{"type":"string"}}}},"YearList":{"description":"Years available in the datarun, newest first.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}},"example":["2024","2023","2022"]},"text/csv":{"schema":{"type":"string"},"example":"2024\n2023\n2022\n"},"text/plain":{"schema":{"type":"string"}}}},"CodeList":{"description":"Sector code definitions.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CodeDefinition"}}},"text/csv":{"schema":{"type":"string"},"example":"child,category,subAccountName,detailedAccountName\n\"z|111000\",\"Industry\",\"Industries\",\"Oilseed and grain farming\"\n"},"text/plain":{"schema":{"type":"string"}}}},"SourceStatement":{"description":"Prose description of the model's data sources.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"application/json":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}},"text/csv":{"schema":{"type":"string"}}}},"ProducerList":{"description":"Data services available for this datarun and year.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProducerInfo"}}},"text/plain":{"schema":{"type":"string"},"example":"Multipliers : Calculate sales, jobs and earnings multipliers. HasMR(false)\nRatios : Jobs, earnings, and value added ratios HasMR(true)\n"},"text/csv":{"schema":{"type":"string"}}}},"SamData":{"description":"Model results.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SamData"},"examples":{"singleRegion":{"summary":"Single region — keyed by data year","value":{"":{"2024":{"bSameSizedVectors":true,"Total Requirements":{"vl|19-1011":128546,"z|332119":366640},"Satisfied in region":{"vl|19-1011":128585,"z|332119":240110},"Satisfied outside region":{"vl|19-1011":0,"z|332119":126530}},"name":"producers.RegRequirements"}}},"multiRegional":{"summary":"Two regions — keyed by region name, plus one entry per ordered region pair. Note the year is absent and the vector names differ from the single-region form.","value":{"":{"name":"producers.MRRequirements","latah":{"bSameSizedVectors":true,"Total Requirements":{"z|111000":23795179.33},"Local Absorption":{"z|111000":4210330.11},"Out of greater region imports":{"z|111000":18334849.22}},"whitman":{"bSameSizedVectors":true,"Total Requirements":{"z|111000":31480222.5},"Local Absorption":{"z|111000":9880222.5},"Out of greater region imports":{"z|111000":21000000}},"latah|whitman":{"bSameSizedVectors":true,"Cross-Region Absorption":{"z|111000":600000}},"whitman|latah":{"bSameSizedVectors":true,"Cross-Region Absorption":{"z|111000":1250000}}}}}}},"text/csv":{"schema":{"type":"string"},"example":"Result Set: 2024\nSector,\"Total Requirements\",\"Satisfied in region\",\"Satisfied outside region\"\n\"z|111000\",366640,240110,126530\n"},"text/plain":{"schema":{"type":"string"}}}},"BulkResult":{"description":"One summary row per change. Each row carries the change's `id` as a\nfield; every value is rendered as a string.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},"example":[{"id":"1","total sales":"1.10641e+08","total earnings":"2.63788e+07","total federal taxes":"165662"}]},"text/csv":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}},"BatchRequirements":{"description":"Requirements rows, one per area that has data for the requested sector.","headers":{"X-Correlation-ID":{"$ref":"#/components/headers/CorrelationId"}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BatchRequirementsRow"}},"example":[{"area":"16075","sector":"z|111000","total":34234,"in_region":234,"out_region":2344}]},"text/csv":{"schema":{"type":"string"},"example":"area,sector,total,in_region,out_region\n16075,\"z|111000\",34234,234,2344\n"},"text/plain":{"schema":{"type":"string"}}}},"BadInput":{"description":"The request could not be processed as written: malformed JSON, a schema\nviolation, an unknown property, an unknown path, an unsupported `Accept`\nvalue, an invalid sector or area ID, an area type the endpoint does not\nallow, an unavailable year, or an endpoint-specific constraint (for\nexample a multi-regional request to `econbase`, `bulk`, or\n`batch_requirements`, each of which rejects it explicitly).\n\nServed as `text/plain`.","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ErrorMessage"},"examples":{"invalidSector":{"value":"Invalid sector passed: 999999"},"invalidArea":{"value":"1 invalid counties were passed: [\"16058\"]"},"invalidAreaType":{"value":"The area type 'State' is not allowed for this endpoint, please use one of County,Zip"},"missingYear":{"value":"Data for year '1999' is not available"},"missingMetrics":{"value":"Metrics must be specified for the basics resource!"},"unknownService":{"summary":"A {service} segment that names no producer","value":"No resource called: nope"},"unknownProperty":{"summary":"Schema violations are quoted twice","value":"\"Unknown property 'bogus' on request object (/)\""},"unknownPath":{"summary":"A path matching no route at all","value":"These aren't the droids you're looking for... Method: 'Get' Path: 'v2/us'"},"unsupportedAccept":{"value":"application/xml does not contain a supported mime type!"}}}}},"Unauthorized":{"description":"Kong rejected a missing, invalid, or expired OAuth token.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"Forbidden":{"description":"Kong rejected a token lacking a required scope. Some application\noperational conditions also return 403 with a `text/plain` body.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}},"text/plain":{"schema":{"$ref":"#/components/schemas/ErrorMessage"}}}},"ServiceUnavailable":{"description":"The service has no usable data: either no dataruns are present, or a\ndatarun contains no years. Served as `text/plain`.","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ErrorMessage"},"examples":{"noDataruns":{"value":"No dataruns available"},"noYears":{"value":"No years available in 2026.3"}}}}},"UnprocessableContent":{"description":"The request was well-formed but the underlying model data is missing or\ninconsistent, so the result could not be computed. This is a data\nproblem rather than a caller error. It is raised by the `eis` service —\neither at `/io/us/{datarun}/{year}/eis` or as an `eis` entry in a\n`basics` request. Served as `text/plain`.","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ErrorMessage"},"examples":{"householdSales":{"value":"EIS is unavailable for year 2024 and counties 16057: household-sales total is 0, so consumption cannot be normalized."}}}}},"InternalError":{"description":"The request could not be completed. The body carries a diagnostic\nmessage and is served as `text/plain`.\n\nThis is also the response to a multi-regional request to a service that\ndoes not support multi-regional models.","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ErrorMessage"},"examples":{"noMultiRegional":{"summary":"A multi-regional request to a single-region-only service","value":"Invalid basics producer: MRMultipliers"},"nonExistingChange":{"summary":"A multi-regional shock on a sector with no sales in that region","value":"Non-existing change MR scenarios are not implemented!"}}}}}},"headers":{"CorrelationId":{"description":"Echo of the request's `X-Correlation-ID`, or a server-generated UUID\nwhen the request did not supply one. Set on success responses only.","schema":{"type":"string"}}}}}