unhcr-refugees-mcp-server
An MCP server that provides access to UNHCR Refugee Data Finder statistics, including displacement stocks, asylum applications, and demographic data. It allows agents to query populations by country of origin and asylum, decode reference codes, and run SQL queries over staged dataframes without requiring an API key.
Endpoint and access
No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.
https://unhcr-refugees.caseyjhand.com/mcpWhat its tools do
8 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.
Checks and signals
Each line is separate evidence, not a trust score.
- Passed Endpoint answered the live check ·
- Availability 1 of 1 checks passed in 30 days
What you can do with it
- Query year-end displacement stocks by country of origin and asylum
- Retrieve asylum application and decision statistics
- Decode UNHCR country codes and regional bureau information
- Run SQL queries over staged UNHCR demographic dataframes
Source and maintenance
- Maintenance checked
Protocol and capabilities
- Server
- unhcr-refugees-mcp-server 0.3.0
- MCP protocol negotiated in check
- 2025-11-25
- Tools
- 8 advertised
- Resources
- 1 advertised
- Resource templates
- 1 advertised
- Prompts
- 0 advertised
{
"tools": {
"listChanged": true
},
"logging": {},
"prompts": {
"listChanged": true
},
"resources": {
"subscribe": true,
"listChanged": true
},
"extensions": {
"io.modelcontextprotocol/skills": {
"directoryRead": true
}
}
}Server-provided instructions
Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.
Tools
8 advertised
unhcr_list_reference — UNHCR reference vocabulary
Decode the vocabulary the unhcr_* tools take as input: countries (ISO3, ISO2, UNHCR code, names, UNHCR and UN regions), UNHCR’s regional bureaus, each dataset’s first and latest year, population-type definitions, and the asylum authority, stage, decision-level, and unit codes. Filter countries with name_contains to turn a country name into the ISO3 code that origin and asylum take.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"topic"
],
"properties": {
"topic": {
"enum": [
"countries",
"regions",
"coverage",
"population_types",
"asylum_codes"
],
"type": "string",
"description": "countries: every queryable country with its codes, names, and regions. regions: UNHCR's regional bureaus. coverage: first and latest year of each dataset, plus the current nowcast month. population_types: what each population type counts and which output column carries it. asylum_codes: asylum authority, application stage, decision level, and unit codes."
},
"name_contains": {
"type": "string",
"maxLength": 200,
"description": "For topic countries only: keep countries whose names, in UNHCR’s English spelling, contain every word given, ignoring case, accents, and punctuation, or whose ISO3, ISO2, or UNHCR code equals a word (\"syria\", \"turkiye\", \"britain\", \"deu\"). Words match every name variant UNHCR records, including short and formal names the output does not list. No fuzzy matching."
}
},
"additionalProperties": false
}{
"type": "object",
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"topic"
]
},
{
"required": [
"error"
]
}
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "JSON-RPC error code for this failure."
},
"data": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"examples": [
"upstream_busy"
],
"description": "Machine-readable failure mode. Declared by this tool: `upstream_busy`: Reference data not yet cached (countries, regions, coverage) needs UNHCR requests, and this server's UNHCR request queue cannot start them before the call's deadline, or UNHCR answered 429. Other values are possible when a failure originates below the handler."
},
"recovery": {
"type": "object",
"required": [
"hint"
],
"properties": {
"hint": {
"type": "string"
}
},
"description": "Actionable next step for the caller.",
"additionalProperties": {}
},
"retryable": {
"type": "boolean",
"description": "Whether retrying may succeed."
}
},
"additionalProperties": {}
},
"message": {
"type": "string",
"description": "Human-readable description of what went wrong."
}
},
"description": "Present when the call failed. Absent on success.",
"additionalProperties": {}
},
"topic": {
"enum": [
"countries",
"regions",
"coverage",
"population_types",
"asylum_codes"
],
"type": "string",
"description": "The topic returned."
},
"notice": {
"type": "string",
"description": "Guidance when name_contains matched nothing or does not apply to the topic."
},
"nowcast": {
"type": "object",
"required": [
"year",
"month"
],
"properties": {
"year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Year of the current nowcast snapshot."
},
"month": {
"type": "string",
"description": "Month name of the current nowcast snapshot (e.g. \"August\")."
}
},
"description": "Present for topic coverage: the single current-year estimate unhcr_get_population's include_nowcast returns.",
"additionalProperties": false
},
"regions": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name",
"country_count"
],
"properties": {
"id": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "UNHCR's region id."
},
"name": {
"type": "string",
"description": "Regional bureau name."
},
"country_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Countries the bureau covers."
}
},
"description": "One UNHCR regional bureau.",
"additionalProperties": false
},
"description": "Present for topic regions."
},
"coverage": {
"type": "array",
"items": {
"type": "object",
"required": [
"dataset",
"tool",
"measure",
"first_year",
"latest_year",
"note"
],
"properties": {
"note": {
"type": "string",
"description": "What the dataset holds."
},
"tool": {
"type": "string",
"description": "The tool that returns this dataset."
},
"dataset": {
"type": "string",
"description": "Dataset key: population, demographics, asylum_applications, asylum_decisions, solutions, unrwa, idmc, or footnotes."
},
"measure": {
"anyOf": [
{
"enum": [
"stock",
"flow"
],
"type": "string"
},
{
"type": "null"
}
],
"description": "stock (year-end) or flow (during the year); null for footnotes."
},
"first_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "First year with data."
},
"latest_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Latest year with data."
}
},
"description": "One dataset's published span.",
"additionalProperties": false
},
"description": "Present for topic coverage."
},
"countries": {
"type": "array",
"items": {
"type": "object",
"required": [
"iso3",
"iso2",
"unhcr_code",
"name",
"name_long",
"nationality",
"unhcr_region",
"unsd_region",
"major_area"
],
"properties": {
"iso2": {
"type": [
"string",
"null"
],
"description": "ISO 3166-1 alpha-2 code, where one exists."
},
"iso3": {
"type": "string",
"description": "ISO 3166-1 alpha-3 code — what origin and asylum take."
},
"name": {
"type": "string",
"description": "UNHCR's country name."
},
"name_long": {
"type": [
"string",
"null"
],
"description": "Long-form name, where UNHCR has one."
},
"major_area": {
"type": [
"string",
"null"
],
"description": "UN Statistics Division major area, where UNHCR records one."
},
"unhcr_code": {
"type": "string",
"description": "UNHCR's own country code, as it appears in data rows."
},
"nationality": {
"type": [
"string",
"null"
],
"description": "Nationality adjective, where UNHCR has one."
},
"unsd_region": {
"type": [
"string",
"null"
],
"description": "UN Statistics Division region, where UNHCR records one."
},
"unhcr_region": {
"type": [
"string",
"null"
],
"description": "UNHCR regional bureau covering the country, where one does."
}
},
"description": "One queryable country.",
"additionalProperties": false
},
"description": "Present for topic countries, sorted by name."
},
"totalCount": {
"type": "number",
"description": "Countries returned, after any name_contains filter."
},
"asylum_codes": {
"type": "object",
"required": [
"authority",
"application_stage",
"decision_level",
"unit"
],
"properties": {
"unit": {
"type": "array",
"items": {
"type": "object",
"required": [
"code",
"label",
"documented"
],
"properties": {
"code": {
"type": "string",
"description": "The code as it appears in the data."
},
"label": {
"type": "string",
"description": "What the code means."
},
"documented": {
"type": "boolean",
"description": "False for codes seen in the data that UNHCR's published methodology does not define."
}
},
"description": "One code and its meaning.",
"additionalProperties": false
},
"description": "Whether a count is of persons or cases."
},
"authority": {
"type": "array",
"items": {
"type": "object",
"required": [
"code",
"label",
"documented"
],
"properties": {
"code": {
"type": "string",
"description": "The code as it appears in the data."
},
"label": {
"type": "string",
"description": "What the code means."
},
"documented": {
"type": "boolean",
"description": "False for codes seen in the data that UNHCR's published methodology does not define."
}
},
"description": "One code and its meaning.",
"additionalProperties": false
},
"description": "Who decided the claim."
},
"decision_level": {
"type": "array",
"items": {
"type": "object",
"required": [
"code",
"label",
"documented"
],
"properties": {
"code": {
"type": "string",
"description": "The code as it appears in the data."
},
"label": {
"type": "string",
"description": "What the code means."
},
"documented": {
"type": "boolean",
"description": "False for codes seen in the data that UNHCR's published methodology does not define."
}
},
"description": "One code and its meaning.",
"additionalProperties": false
},
"description": "Level at which a decision was made."
},
"application_stage": {
"type": "array",
"items": {
"type": "object",
"required": [
"code",
"label",
"documented"
],
"properties": {
"code": {
"type": "string",
"description": "The code as it appears in the data."
},
"label": {
"type": "string",
"description": "What the code means."
},
"documented": {
"type": "boolean",
"description": "False for codes seen in the data that UNHCR's published methodology does not define."
}
},
"description": "One code and its meaning.",
"additionalProperties": false
},
"description": "Stage of an asylum application."
}
},
"description": "Present for topic asylum_codes.",
"additionalProperties": false
},
"population_types": {
"type": "array",
"items": {
"type": "object",
"required": [
"code",
"field",
"label",
"measure",
"definition"
],
"properties": {
"code": {
"type": "string",
"description": "Population-type code (REF, ASY, …), as footnotes and the unhcr_get_demographics population_types filter use it."
},
"field": {
"type": [
"string",
"null"
],
"description": "Output column carrying the type; null when it is counted inside another column."
},
"label": {
"type": "string",
"description": "Population-type name."
},
"measure": {
"enum": [
"stock",
"flow"
],
"type": "string",
"description": "stock (year-end) or flow (during the year)."
},
"definition": {
"type": "string",
"description": "What the type counts."
}
},
"description": "One UNHCR population type.",
"additionalProperties": false
},
"description": "Present for topic population_types."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true
}unhcr_get_population — UNHCR displacement stocks
Get UNHCR year-end displacement stocks (1951 to the latest year) by country of origin and/or asylum: refugees, asylum-seekers, other people in need of international protection, IDPs, stateless people, others of concern, and host communities, plus refugees and IDPs who returned during the year. Stocks count people in a situation on 31 December, not arrivals. Palestine refugees under UNRWA's mandate and IDMC's conflict-IDP estimate are separate series shown beside each row. Set include_nowcast for UNHCR's current-year estimate by asylum country; for sex and age breakdowns, use unhcr_get_demographics.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"limit": {
"type": "integer",
"default": 25,
"minimum": 1,
"multipleOf": 1,
"description": "Inline rows. Default 25; a larger value returns at most 2000 and says so. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
},
"stage": {
"type": "boolean",
"default": false,
"description": "Stage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so."
},
"asylum": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules and limit as origin. Omit to sum every asylum country into one row, or set expand to list each."
},
"expand": {
"enum": [
"none",
"origin",
"asylum",
"both"
],
"type": "string",
"default": "none",
"description": "List every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected."
},
"origin": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 250 distinct codes, enough to list every country in UNHCR's country list. Omit to sum every origin into one row, or set expand to list each."
},
"sort_by": {
"enum": [
"year",
"refugees",
"asylum_seekers",
"oip",
"idps",
"stateless",
"ooc",
"hst",
"returned_refugees",
"returned_idps"
],
"type": "string",
"default": "year",
"description": "Order of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3; a count field orders largest first, nulls last. The nowcast is ordered by refugees or asylum_seekers when sort_by names one, otherwise by asylum ISO3."
},
"year_to": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "Last year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported."
},
"year_from": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "First year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected."
},
"include_nowcast": {
"type": "boolean",
"default": false,
"description": "Append UNHCR's latest monthly estimate of refugees and asylum-seekers by asylum country: one current-year snapshot, independent of the year window. It is sorted and cut to limit on its own, and staged as its own dataframe (nowcast_dataset) when it overflows or stage is set. The nowcast has no origin dimension, so it is skipped when origin lists codes. When origin lists no codes, a window entirely after the latest published year returns the nowcast alone instead of failing."
}
},
"additionalProperties": false
}{
"type": "object",
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"rows",
"total_rows",
"complete",
"measure",
"applied_scope",
"latest_year",
"data_notes",
"attribution",
"footnotes",
"footnotes_total"
]
},
{
"required": [
"error"
]
}
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"cap": {
"type": "number",
"description": "The limit that was applied."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"year",
"origin_iso3",
"origin_unhcr_code",
"origin_name",
"asylum_iso3",
"asylum_unhcr_code",
"asylum_name",
"refugees",
"asylum_seekers",
"oip",
"idps",
"stateless",
"ooc",
"hst",
"returned_refugees",
"returned_idps"
],
"properties": {
"hst": {
"type": [
"number",
"null"
],
"description": "Host community. Null when UNHCR marks it not applicable or not collected — never zero."
},
"oip": {
"type": [
"number",
"null"
],
"description": "Other people in need of international protection. Null when UNHCR marks it not applicable or not collected — never zero."
},
"ooc": {
"type": [
"number",
"null"
],
"description": "Others of concern to UNHCR. Null when UNHCR marks it not applicable or not collected — never zero."
},
"idps": {
"type": [
"number",
"null"
],
"description": "Conflict IDPs UNHCR protects or assists, including IDP-like situations. Null when UNHCR marks it not applicable or not collected — never zero."
},
"year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Calendar year of the figure."
},
"refugees": {
"type": [
"number",
"null"
],
"description": "Refugees, including people in refugee-like situations. Null when UNHCR marks it not applicable or not collected — never zero."
},
"stateless": {
"type": [
"number",
"null"
],
"description": "Stateless people. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "Country of asylum, ISO3. Null when asylum countries are summed into this row."
},
"asylum_name": {
"type": [
"string",
"null"
],
"description": "Asylum country name. Null when summed."
},
"origin_iso3": {
"type": [
"string",
"null"
],
"description": "Country of origin, ISO3. Null when origins are summed into this row."
},
"origin_name": {
"type": [
"string",
"null"
],
"description": "Origin country name. Null when summed."
},
"returned_idps": {
"type": [
"number",
"null"
],
"description": "IDPs who returned during the year (a flow), recorded against the origin country. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_seekers": {
"type": [
"number",
"null"
],
"description": "Asylum-seekers awaiting a decision. Null when UNHCR marks it not applicable or not collected — never zero."
},
"unrwa_refugees": {
"type": [
"number",
"null"
],
"description": "Palestine refugees registered with UNRWA; a separate series, never inside refugees. Present only where UNRWA has a row for this year and scope. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the asylum country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"origin_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the origin country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"returned_refugees": {
"type": [
"number",
"null"
],
"description": "Refugees who returned during the year (a flow), recorded against the country returned from. Null when UNHCR marks it not applicable or not collected — never zero."
},
"idmc_conflict_idps": {
"type": [
"number",
"null"
],
"description": "IDMC's estimate of people displaced by conflict and violence; a separate series from idps. Present only where IDMC has a row for this year and scope. Null when UNHCR marks it not applicable or not collected — never zero."
}
},
"description": "One year of stocks for one origin/asylum scope. A year and scope only UNRWA or IDMC reports carries every UNHCR count null.",
"additionalProperties": false
},
"description": "Inline rows, sorted, up to limit."
},
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "JSON-RPC error code for this failure."
},
"data": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"examples": [
"unknown_country_code",
"invalid_year_window",
"year_out_of_coverage",
"conflicting_scope",
"too_many_country_codes",
"upstream_busy"
],
"description": "Machine-readable failure mode. Declared by this tool: `unknown_country_code`: An origin or asylum value is not an ISO3 code in UNHCR's country list (after ISO2 normalization). `invalid_year_window`: year_from is later than year_to. `year_out_of_coverage`: The whole requested window lies outside the dataset's published years, unless include_nowcast is set without origin codes and the window starts after the latest year (the nowcast is then returned instead). `conflicting_scope`: expand names a dimension that origin or asylum already filters. `too_many_country_codes`: origin or asylum lists more distinct codes than one filter accepts. `upstream_busy`: This server's UNHCR request queue cannot start the call's requests before its deadline, or UNHCR answered 429. Other values are possible when a failure originates below the handler."
},
"recovery": {
"type": "object",
"required": [
"hint"
],
"properties": {
"hint": {
"type": "string"
}
},
"description": "Actionable next step for the caller.",
"additionalProperties": {}
},
"retryable": {
"type": "boolean",
"description": "Whether retrying may succeed."
}
},
"additionalProperties": {}
},
"message": {
"type": "string",
"description": "Human-readable description of what went wrong."
}
},
"description": "Present when the call failed. Absent on success.",
"additionalProperties": {}
},
"shown": {
"type": "number",
"description": "Rows returned inline."
},
"notice": {
"type": "string",
"description": "Guidance for this result: empty-result hints, year and limit clamps, where the full set was staged, or how to narrow."
},
"dataset": {
"type": "object",
"required": [
"name",
"row_count",
"expires_at"
],
"properties": {
"name": {
"type": "string",
"description": "Dataframe handle (df_XXXXX_XXXXX) for unhcr_dataframe_query."
},
"evicted": {
"type": "array",
"items": {
"type": "string"
},
"description": "Older dataframes dropped, oldest first, to keep the staged total within the 1,000,000-row budget; they can no longer be queried. Present only when staging this result evicted any."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows staged."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 time the staged table expires."
}
},
"description": "Present when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.",
"additionalProperties": false
},
"measure": {
"enum": [
"stock",
"flow"
],
"type": "string",
"description": "stock: people in a situation on 31 December; flow: events during the year."
},
"nowcast": {
"type": "array",
"items": {
"type": "object",
"required": [
"asylum_iso3",
"asylum_unhcr_code",
"asylum_name",
"year",
"month",
"refugees",
"asylum_seekers",
"source"
],
"properties": {
"year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Year of the estimate."
},
"month": {
"type": [
"string",
"null"
],
"description": "Month name of the estimate (e.g. \"August\"). Null when UNHCR sent none."
},
"source": {
"type": [
"string",
"null"
],
"description": "Provenance of the estimate, as UNHCR labels it (a comma-separated list). Null when UNHCR sent none."
},
"refugees": {
"type": [
"number",
"null"
],
"description": "Estimated refugees. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "Asylum country, ISO3. Null for the world total."
},
"asylum_name": {
"type": [
"string",
"null"
],
"description": "Asylum country name. Null for the world total."
},
"asylum_seekers": {
"type": [
"number",
"null"
],
"description": "Estimated asylum-seekers. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's code for the asylum country. Null for the world total."
}
},
"description": "One row of UNHCR's current-year estimate.",
"additionalProperties": false
},
"description": "UNHCR's current-year estimate by asylum country, sorted and cut to limit apart from rows: largest first by refugees or asylum_seekers when sort_by names one (nulls last, ties by asylum ISO3), otherwise by asylum ISO3. Present when include_nowcast was set and origin lists no codes."
},
"complete": {
"type": "boolean",
"description": "False when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow."
},
"footnotes": {
"type": "array",
"items": {
"type": "object",
"required": [
"text",
"years",
"origin_iso3",
"asylum_iso3",
"population_types",
"rows_matched"
],
"properties": {
"text": {
"type": "string",
"description": "UNHCR's caveat text, verbatim."
},
"years": {
"type": "string",
"description": "Years the caveat covers, as UNHCR writes them (e.g. \"2019 - 2022\")."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "ISO3 of the asylum country the caveat names; null when it applies to any asylum country."
},
"origin_iso3": {
"type": [
"string",
"null"
],
"description": "ISO3 of the origin country the caveat names; null when it applies to any origin."
},
"rows_matched": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows of the full result the caveat applies to: rows in its years and countries that carry one of its population types."
},
"population_types": {
"type": "array",
"items": {
"type": "string"
},
"description": "Population-type codes the caveat applies to (decode with unhcr_list_reference)."
}
},
"description": "One UNHCR data caveat that applies to rows of this result.",
"additionalProperties": false
},
"description": "UNHCR caveats matching rows of the full result, at most 20. Caveats on inline rows come before those only on rows past the cut; within each group, country-specific first, then in the order of the first row each matches."
},
"truncated": {
"type": "boolean",
"description": "True when rows were cut at limit."
},
"data_notes": {
"type": "array",
"items": {
"type": "string"
},
"description": "How to read the counts: stock or flow, rounding, the meaning of null, caveats."
},
"total_rows": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result."
},
"attribution": {
"type": "object",
"required": [
"source",
"license",
"terms_url",
"providers"
],
"properties": {
"source": {
"type": "string",
"description": "Source to cite: \"UNHCR Refugee Population Statistics Database\"."
},
"license": {
"type": "string",
"description": "Dataset licence (CC BY 4.0)."
},
"providers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Third-party series in this result (IDMC, UNRWA), whose own conditions may apply."
},
"terms_url": {
"type": "string",
"description": "URL of UNHCR's Terms of Use for Datasets, to cite with the figures."
}
},
"description": "Attribution UNHCR requires when these figures are reused.",
"additionalProperties": false
},
"latest_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Newest year this dataset publishes."
},
"applied_scope": {
"type": "object",
"required": [
"origin",
"asylum",
"year_from",
"year_to",
"normalized"
],
"properties": {
"asylum": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the asylum dimension was queried.",
"additionalProperties": false
},
"origin": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the origin dimension was queried.",
"additionalProperties": false
},
"year_to": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Last year sent upstream, after filling and clamping."
},
"year_from": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "First year sent upstream, after filling and clamping."
},
"normalized": {
"type": "array",
"items": {
"type": "object",
"required": [
"input",
"iso3"
],
"properties": {
"iso3": {
"type": "string",
"description": "The ISO3 code it was rewritten to."
},
"input": {
"type": "string",
"description": "The code as given."
}
},
"description": "One ISO2 → ISO3 rewrite.",
"additionalProperties": false
},
"description": "ISO 3166 alpha-2 codes rewritten to ISO3."
}
},
"description": "The scope actually sent upstream, including clamped years and code rewrites.",
"additionalProperties": false
},
"nowcast_total": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Nowcast rows before the cut at limit. Present whenever nowcast is."
},
"footnotes_total": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Caveats matching the full result, before the cap."
},
"nowcast_dataset": {
"type": "object",
"required": [
"name",
"row_count",
"expires_at"
],
"properties": {
"name": {
"type": "string",
"description": "Dataframe handle (df_XXXXX_XXXXX) for unhcr_dataframe_query."
},
"evicted": {
"type": "array",
"items": {
"type": "string"
},
"description": "Older dataframes dropped, oldest first, to keep the staged total within the 1,000,000-row budget; they can no longer be queried. Present only when staging this result evicted any."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows staged."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 time the staged table expires."
}
},
"description": "Present when the nowcast was staged as its own dataframe, because it overflowed limit or stage was set: columns year, month, asylum_iso3, asylum_unhcr_code, asylum_name, asylum_unhcr_region, asylum_unsd_region, refugees, asylum_seekers, source, and no origin columns. It stays apart from dataset because both count largely the same people at different dates; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.",
"additionalProperties": false
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true
}unhcr_get_demographics — UNHCR demographics
Get UNHCR year-end stocks (2001 to the latest year) broken down by population type, sex, and age band (0–4, 5–11, 12–17, 18–59, 60+, unknown age), by country of origin and/or asylum. Coverage is partial: each row gives the share of its total that UNHCR could disaggregate by sex, and age bands are null where no breakdown exists. These totals come from a separate collection and need not match unhcr_get_population.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"limit": {
"type": "integer",
"default": 25,
"minimum": 1,
"multipleOf": 1,
"description": "Inline rows. Default 25; a larger value returns at most 2000 and says so. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
},
"stage": {
"type": "boolean",
"default": false,
"description": "Stage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so."
},
"asylum": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules and limit as origin. Omit to sum every asylum country into one row, or set expand to list each."
},
"expand": {
"enum": [
"none",
"origin",
"asylum",
"both"
],
"type": "string",
"default": "none",
"description": "List every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected."
},
"origin": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 250 distinct codes, enough to list every country in UNHCR's country list. Omit to sum every origin into one row, or set expand to list each."
},
"sort_by": {
"enum": [
"year",
"total"
],
"type": "string",
"default": "year",
"description": "Order of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3, then population type; total orders largest first, nulls last."
},
"year_to": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "Last year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported."
},
"year_from": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "First year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected."
},
"population_types": {
"type": "array",
"items": {
"enum": [
"REF",
"ASY",
"OIP",
"IDP",
"STA",
"OOC",
"HST",
"RET",
"RDP"
],
"type": "string",
"description": "A population-type code."
},
"maxItems": 9,
"description": "Keep only these population types, case-insensitive: REF refugees, ASY asylum-seekers, OIP other people in need of international protection, IDP internally displaced, STA stateless, OOC others of concern, HST host community, RET returned refugees, RDP returned IDPs. Decode them with unhcr_list_reference (topic population_types). Omit for every type."
}
},
"additionalProperties": false
}{
"type": "object",
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"rows",
"total_rows",
"complete",
"measure",
"applied_scope",
"latest_year",
"data_notes",
"attribution",
"footnotes",
"footnotes_total"
]
},
{
"required": [
"error"
]
}
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"cap": {
"type": "number",
"description": "The limit that was applied."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"year",
"origin_iso3",
"origin_unhcr_code",
"origin_name",
"asylum_iso3",
"asylum_unhcr_code",
"asylum_name",
"population_type",
"total",
"female_0_4",
"female_5_11",
"female_12_17",
"female_18_59",
"female_60_plus",
"female_unknown_age",
"female_total",
"male_0_4",
"male_5_11",
"male_12_17",
"male_18_59",
"male_60_plus",
"male_unknown_age",
"male_total",
"disaggregated",
"sex_disaggregated_share"
],
"properties": {
"year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Calendar year of the figure."
},
"total": {
"type": [
"number",
"null"
],
"description": "Everyone of this population type in this scope, broken down or not. Null when UNHCR marks it not applicable or not collected."
},
"male_0_4": {
"type": [
"number",
"null"
],
"description": "Males aged 0–4. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"male_5_11": {
"type": [
"number",
"null"
],
"description": "Males aged 5–11. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"female_0_4": {
"type": [
"number",
"null"
],
"description": "Females aged 0–4. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"male_12_17": {
"type": [
"number",
"null"
],
"description": "Males aged 12–17. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"male_18_59": {
"type": [
"number",
"null"
],
"description": "Males aged 18–59. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"male_total": {
"type": [
"number",
"null"
],
"description": "Males of all ages (the sum of the bands). Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "Country of asylum, ISO3. Null when asylum countries are summed into this row."
},
"asylum_name": {
"type": [
"string",
"null"
],
"description": "Asylum country name. Null when summed."
},
"female_5_11": {
"type": [
"number",
"null"
],
"description": "Females aged 5–11. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"origin_iso3": {
"type": [
"string",
"null"
],
"description": "Country of origin, ISO3. Null when origins are summed into this row."
},
"origin_name": {
"type": [
"string",
"null"
],
"description": "Origin country name. Null when summed."
},
"female_12_17": {
"type": [
"number",
"null"
],
"description": "Females aged 12–17. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"female_18_59": {
"type": [
"number",
"null"
],
"description": "Females aged 18–59. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"female_total": {
"type": [
"number",
"null"
],
"description": "Females of all ages (the sum of the bands). Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"male_60_plus": {
"type": [
"number",
"null"
],
"description": "Males aged 60 or older. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"disaggregated": {
"type": "boolean",
"description": "True when UNHCR has any sex breakdown for this row; false means every band is null."
},
"female_60_plus": {
"type": [
"number",
"null"
],
"description": "Females aged 60 or older. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"population_type": {
"type": [
"string",
"null"
],
"description": "Population-type code (REF, ASY, OIP, IDP, STA, OOC, HST, RET, RDP); decode with unhcr_list_reference (topic population_types)."
},
"male_unknown_age": {
"type": [
"number",
"null"
],
"description": "Males of unknown age. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"asylum_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the asylum country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"origin_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the origin country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"female_unknown_age": {
"type": [
"number",
"null"
],
"description": "Females of unknown age. Null when UNHCR has no sex and age breakdown for the row, or marks it not applicable — never zero."
},
"sex_disaggregated_share": {
"type": [
"number",
"null"
],
"description": "Fraction on a 0–1 scale, 4 decimal places: (female_total + male_total) ÷ total, the share of the row UNHCR could break down by sex. Null when total is 0."
}
},
"description": "One year of one population type for one origin/asylum scope.",
"additionalProperties": false
},
"description": "Inline rows, sorted, up to limit."
},
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "JSON-RPC error code for this failure."
},
"data": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"examples": [
"unknown_country_code",
"invalid_year_window",
"year_out_of_coverage",
"conflicting_scope",
"too_many_country_codes",
"upstream_busy"
],
"description": "Machine-readable failure mode. Declared by this tool: `unknown_country_code`: An origin or asylum value is not an ISO3 code in UNHCR's country list (after ISO2 normalization). `invalid_year_window`: year_from is later than year_to. `year_out_of_coverage`: The whole requested window lies outside the dataset's published years. `conflicting_scope`: expand names a dimension that origin or asylum already filters. `too_many_country_codes`: origin or asylum lists more distinct codes than one filter accepts. `upstream_busy`: This server's UNHCR request queue cannot start the call's requests before its deadline, or UNHCR answered 429. Other values are possible when a failure originates below the handler."
},
"recovery": {
"type": "object",
"required": [
"hint"
],
"properties": {
"hint": {
"type": "string"
}
},
"description": "Actionable next step for the caller.",
"additionalProperties": {}
},
"retryable": {
"type": "boolean",
"description": "Whether retrying may succeed."
}
},
"additionalProperties": {}
},
"message": {
"type": "string",
"description": "Human-readable description of what went wrong."
}
},
"description": "Present when the call failed. Absent on success.",
"additionalProperties": {}
},
"shown": {
"type": "number",
"description": "Rows returned inline."
},
"notice": {
"type": "string",
"description": "Guidance for this result: empty-result hints, year and limit clamps, where the full set was staged, or how to narrow."
},
"dataset": {
"type": "object",
"required": [
"name",
"row_count",
"expires_at"
],
"properties": {
"name": {
"type": "string",
"description": "Dataframe handle (df_XXXXX_XXXXX) for unhcr_dataframe_query."
},
"evicted": {
"type": "array",
"items": {
"type": "string"
},
"description": "Older dataframes dropped, oldest first, to keep the staged total within the 1,000,000-row budget; they can no longer be queried. Present only when staging this result evicted any."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows staged."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 time the staged table expires."
}
},
"description": "Present when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.",
"additionalProperties": false
},
"measure": {
"enum": [
"stock",
"flow"
],
"type": "string",
"description": "stock: people in a situation on 31 December; flow: events during the year."
},
"complete": {
"type": "boolean",
"description": "False when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow."
},
"footnotes": {
"type": "array",
"items": {
"type": "object",
"required": [
"text",
"years",
"origin_iso3",
"asylum_iso3",
"population_types",
"rows_matched"
],
"properties": {
"text": {
"type": "string",
"description": "UNHCR's caveat text, verbatim."
},
"years": {
"type": "string",
"description": "Years the caveat covers, as UNHCR writes them (e.g. \"2019 - 2022\")."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "ISO3 of the asylum country the caveat names; null when it applies to any asylum country."
},
"origin_iso3": {
"type": [
"string",
"null"
],
"description": "ISO3 of the origin country the caveat names; null when it applies to any origin."
},
"rows_matched": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows of the full result the caveat applies to: rows in its years and countries that carry one of its population types."
},
"population_types": {
"type": "array",
"items": {
"type": "string"
},
"description": "Population-type codes the caveat applies to (decode with unhcr_list_reference)."
}
},
"description": "One UNHCR data caveat that applies to rows of this result.",
"additionalProperties": false
},
"description": "UNHCR caveats matching rows of the full result, at most 20. Caveats on inline rows come before those only on rows past the cut; within each group, country-specific first, then in the order of the first row each matches."
},
"truncated": {
"type": "boolean",
"description": "True when rows were cut at limit."
},
"data_notes": {
"type": "array",
"items": {
"type": "string"
},
"description": "How to read the counts: stock or flow, rounding, the meaning of null, caveats."
},
"total_rows": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result."
},
"attribution": {
"type": "object",
"required": [
"source",
"license",
"terms_url",
"providers"
],
"properties": {
"source": {
"type": "string",
"description": "Source to cite: \"UNHCR Refugee Population Statistics Database\"."
},
"license": {
"type": "string",
"description": "Dataset licence (CC BY 4.0)."
},
"providers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Third-party series in this result (IDMC, UNRWA), whose own conditions may apply."
},
"terms_url": {
"type": "string",
"description": "URL of UNHCR's Terms of Use for Datasets, to cite with the figures."
}
},
"description": "Attribution UNHCR requires when these figures are reused.",
"additionalProperties": false
},
"latest_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Newest year this dataset publishes."
},
"applied_scope": {
"type": "object",
"required": [
"origin",
"asylum",
"year_from",
"year_to",
"normalized"
],
"properties": {
"asylum": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the asylum dimension was queried.",
"additionalProperties": false
},
"origin": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the origin dimension was queried.",
"additionalProperties": false
},
"year_to": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Last year sent upstream, after filling and clamping."
},
"year_from": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "First year sent upstream, after filling and clamping."
},
"normalized": {
"type": "array",
"items": {
"type": "object",
"required": [
"input",
"iso3"
],
"properties": {
"iso3": {
"type": "string",
"description": "The ISO3 code it was rewritten to."
},
"input": {
"type": "string",
"description": "The code as given."
}
},
"description": "One ISO2 → ISO3 rewrite.",
"additionalProperties": false
},
"description": "ISO 3166 alpha-2 codes rewritten to ISO3."
}
},
"description": "The scope actually sent upstream, including clamped years and code rewrites.",
"additionalProperties": false
},
"footnotes_total": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Caveats matching the full result, before the cap."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true
}unhcr_get_asylum_applications — UNHCR asylum applications
Get asylum applications lodged per year (2000 to the latest year) by country of origin and/or asylum, split by default into application stage — new, repeat, appeal, and the combined stages some countries report — so new claims are not added to appeals of old ones. Counts given as cases are never added to counts of persons; each row states its unit. Decode stage, authority, and decision-level codes with unhcr_list_reference (topic asylum_codes).
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"limit": {
"type": "integer",
"default": 25,
"minimum": 1,
"multipleOf": 1,
"description": "Inline rows. Default 25; a larger value returns at most 2000 and says so. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
},
"stage": {
"type": "boolean",
"default": false,
"description": "Stage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so."
},
"asylum": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules and limit as origin. Omit to sum every asylum country into one row, or set expand to list each."
},
"expand": {
"enum": [
"none",
"origin",
"asylum",
"both"
],
"type": "string",
"default": "none",
"description": "List every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected."
},
"origin": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 250 distinct codes, enough to list every country in UNHCR's country list. Omit to sum every origin into one row, or set expand to list each."
},
"stages": {
"type": "array",
"items": {
"enum": [
"N",
"R",
"A",
"NA",
"NR",
"FA",
"J",
"BL",
"SP",
"V",
"RA"
],
"type": "string",
"description": "An application-stage code."
},
"maxItems": 11,
"description": "Keep only these application stages before summing, case-insensitive: N new, R repeat, A appeal, NA new and appeal together, NR new and repeat together, FA first and appeal, J judiciary, BL backlog, SP subsidiary protection; V and RA appear in the data without a published definition. [\"N\"] gives new applications only, the basis of UNHCR's headline figure. Omit for every stage."
},
"sort_by": {
"enum": [
"year",
"applied"
],
"type": "string",
"default": "year",
"description": "Order of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3; applied orders largest first, nulls last."
},
"year_to": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "Last year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported."
},
"split_by": {
"type": "array",
"items": {
"enum": [
"authority",
"stage",
"decision_level"
],
"type": "string",
"description": "A procedure dimension to keep separate."
},
"default": [
"stage"
],
"maxItems": 3,
"description": "Procedure dimensions kept as separate rows: authority (government, UNHCR, or joint), stage (new, repeat, appeal, …), decision_level. Every dimension left out is summed. Default [\"stage\"]; [] gives one total per year and scope for each unit. Unit is always kept separate."
},
"year_from": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "First year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected."
}
},
"additionalProperties": false
}{
"type": "object",
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"rows",
"total_rows",
"complete",
"measure",
"applied_scope",
"latest_year",
"data_notes",
"attribution"
]
},
{
"required": [
"error"
]
}
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"cap": {
"type": "number",
"description": "The limit that was applied."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"year",
"origin_iso3",
"origin_unhcr_code",
"origin_name",
"asylum_iso3",
"asylum_unhcr_code",
"asylum_name",
"authorities",
"stages",
"decision_levels",
"unit",
"applied"
],
"properties": {
"unit": {
"enum": [
"persons",
"cases"
],
"type": "string",
"description": "What applied counts: persons, or cases that can cover several people."
},
"year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Calendar year of the figure."
},
"stages": {
"type": "array",
"items": {
"type": "string",
"description": "One stage code."
},
"description": "Application-stage codes summed into this row; a single code when split_by keeps stage separate."
},
"applied": {
"type": [
"number",
"null"
],
"description": "Applications lodged during the year, in this row’s unit. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "Country of asylum, ISO3. Null when asylum countries are summed into this row."
},
"asylum_name": {
"type": [
"string",
"null"
],
"description": "Asylum country name. Null when summed."
},
"authorities": {
"type": "array",
"items": {
"type": "string",
"description": "One authority code."
},
"description": "Authority codes summed into this row; a single code when split_by keeps authority separate."
},
"origin_iso3": {
"type": [
"string",
"null"
],
"description": "Country of origin, ISO3. Null when origins are summed into this row."
},
"origin_name": {
"type": [
"string",
"null"
],
"description": "Origin country name. Null when summed."
},
"decision_levels": {
"type": "array",
"items": {
"type": "string",
"description": "One decision level code."
},
"description": "Decision-level codes summed into this row; a single code when split_by keeps decision level separate."
},
"asylum_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the asylum country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"origin_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the origin country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
}
},
"description": "One year of applications for one origin/asylum scope, stage split, and unit.",
"additionalProperties": false
},
"description": "Inline rows, sorted, up to limit."
},
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "JSON-RPC error code for this failure."
},
"data": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"examples": [
"unknown_country_code",
"invalid_year_window",
"year_out_of_coverage",
"conflicting_scope",
"too_many_country_codes",
"upstream_busy"
],
"description": "Machine-readable failure mode. Declared by this tool: `unknown_country_code`: An origin or asylum value is not an ISO3 code in UNHCR's country list (after ISO2 normalization). `invalid_year_window`: year_from is later than year_to. `year_out_of_coverage`: The whole requested window lies outside the dataset's published years. `conflicting_scope`: expand names a dimension that origin or asylum already filters. `too_many_country_codes`: origin or asylum lists more distinct codes than one filter accepts. `upstream_busy`: This server's UNHCR request queue cannot start the call's requests before its deadline, or UNHCR answered 429. Other values are possible when a failure originates below the handler."
},
"recovery": {
"type": "object",
"required": [
"hint"
],
"properties": {
"hint": {
"type": "string"
}
},
"description": "Actionable next step for the caller.",
"additionalProperties": {}
},
"retryable": {
"type": "boolean",
"description": "Whether retrying may succeed."
}
},
"additionalProperties": {}
},
"message": {
"type": "string",
"description": "Human-readable description of what went wrong."
}
},
"description": "Present when the call failed. Absent on success.",
"additionalProperties": {}
},
"shown": {
"type": "number",
"description": "Rows returned inline."
},
"notice": {
"type": "string",
"description": "Guidance for this result: empty-result hints, year and limit clamps, where the full set was staged, or how to narrow."
},
"dataset": {
"type": "object",
"required": [
"name",
"row_count",
"expires_at"
],
"properties": {
"name": {
"type": "string",
"description": "Dataframe handle (df_XXXXX_XXXXX) for unhcr_dataframe_query."
},
"evicted": {
"type": "array",
"items": {
"type": "string"
},
"description": "Older dataframes dropped, oldest first, to keep the staged total within the 1,000,000-row budget; they can no longer be queried. Present only when staging this result evicted any."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows staged."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 time the staged table expires."
}
},
"description": "Present when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.",
"additionalProperties": false
},
"measure": {
"enum": [
"stock",
"flow"
],
"type": "string",
"description": "stock: people in a situation on 31 December; flow: events during the year."
},
"complete": {
"type": "boolean",
"description": "False when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow."
},
"truncated": {
"type": "boolean",
"description": "True when rows were cut at limit."
},
"data_notes": {
"type": "array",
"items": {
"type": "string"
},
"description": "How to read the counts: stock or flow, rounding, the meaning of null, caveats."
},
"total_rows": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result."
},
"attribution": {
"type": "object",
"required": [
"source",
"license",
"terms_url",
"providers"
],
"properties": {
"source": {
"type": "string",
"description": "Source to cite: \"UNHCR Refugee Population Statistics Database\"."
},
"license": {
"type": "string",
"description": "Dataset licence (CC BY 4.0)."
},
"providers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Third-party series in this result (IDMC, UNRWA), whose own conditions may apply."
},
"terms_url": {
"type": "string",
"description": "URL of UNHCR's Terms of Use for Datasets, to cite with the figures."
}
},
"description": "Attribution UNHCR requires when these figures are reused.",
"additionalProperties": false
},
"latest_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Newest year this dataset publishes."
},
"applied_scope": {
"type": "object",
"required": [
"origin",
"asylum",
"year_from",
"year_to",
"normalized"
],
"properties": {
"asylum": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the asylum dimension was queried.",
"additionalProperties": false
},
"origin": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the origin dimension was queried.",
"additionalProperties": false
},
"year_to": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Last year sent upstream, after filling and clamping."
},
"year_from": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "First year sent upstream, after filling and clamping."
},
"normalized": {
"type": "array",
"items": {
"type": "object",
"required": [
"input",
"iso3"
],
"properties": {
"iso3": {
"type": "string",
"description": "The ISO3 code it was rewritten to."
},
"input": {
"type": "string",
"description": "The code as given."
}
},
"description": "One ISO2 → ISO3 rewrite.",
"additionalProperties": false
},
"description": "ISO 3166 alpha-2 codes rewritten to ISO3."
}
},
"description": "The scope actually sent upstream, including clamped years and code rewrites.",
"additionalProperties": false
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true
}unhcr_get_asylum_decisions — UNHCR asylum decisions
Get asylum decisions per year (2000 to the latest year) by country of origin and/or asylum: recognized as refugees, complementary protection, rejected, and otherwise closed, with UNHCR's Refugee Recognition Rate and Total Protection Rate computed over substantive decisions (otherwise-closed cases excluded). By default all decision levels are summed and each row lists the levels it includes; appeal-stage decisions can concern people already decided at first instance, so split_by decision_level or filter decision_levels to FI for first-instance rates. Cases and persons are never added together.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"limit": {
"type": "integer",
"default": 25,
"minimum": 1,
"multipleOf": 1,
"description": "Inline rows. Default 25; a larger value returns at most 2000 and says so. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
},
"stage": {
"type": "boolean",
"default": false,
"description": "Stage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so."
},
"asylum": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules and limit as origin. Omit to sum every asylum country into one row, or set expand to list each."
},
"expand": {
"enum": [
"none",
"origin",
"asylum",
"both"
],
"type": "string",
"default": "none",
"description": "List every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected."
},
"origin": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 250 distinct codes, enough to list every country in UNHCR's country list. Omit to sum every origin into one row, or set expand to list each."
},
"sort_by": {
"enum": [
"year",
"total_decisions",
"substantive_decisions",
"recognized",
"rejected"
],
"type": "string",
"default": "year",
"description": "Order of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3; a count field orders largest first, nulls last. Rates are not sortable, since rates on small rounded counts would crowd the top."
},
"year_to": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "Last year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported."
},
"split_by": {
"type": "array",
"items": {
"enum": [
"authority",
"decision_level"
],
"type": "string",
"description": "A procedure dimension to keep separate."
},
"default": [],
"maxItems": 2,
"description": "Procedure dimensions kept as separate rows: authority (government, UNHCR, or joint) and decision_level (first instance, administrative review, …). Every dimension left out is summed. Default [] sums all authorities and levels, as UNHCR does for its rates. Unit is always kept separate."
},
"year_from": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "First year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected."
},
"decision_levels": {
"type": "array",
"items": {
"enum": [
"NA",
"FI",
"AR",
"RA",
"IN",
"EO",
"JR",
"SP",
"FA",
"TP",
"TA",
"BL",
"TR",
"CA"
],
"type": "string",
"description": "A decision-level code."
},
"maxItems": 14,
"description": "Keep only these decision levels before summing, case-insensitive: NA new applications, FI first instance, AR administrative review, RA repeat/reopened, IN US Citizenship and Immigration Services, EO US Executive Office for Immigration Review, JR judicial review, SP subsidiary protection, FA first instance and appeal, TP temporary protection, TA temporary asylum, BL backlog, TR temporary leave to remain, CA cantonal regulations (Switzerland). [\"FI\"] gives first-instance decisions. Omit for every level."
}
},
"additionalProperties": false
}{
"type": "object",
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"rows",
"total_rows",
"complete",
"measure",
"applied_scope",
"latest_year",
"data_notes",
"attribution"
]
},
{
"required": [
"error"
]
}
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"cap": {
"type": "number",
"description": "The limit that was applied."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"year",
"origin_iso3",
"origin_unhcr_code",
"origin_name",
"asylum_iso3",
"asylum_unhcr_code",
"asylum_name",
"authorities",
"decision_levels",
"unit",
"recognized",
"complementary_protection",
"rejected",
"otherwise_closed",
"total_decisions",
"substantive_decisions",
"refugee_recognition_rate",
"total_protection_rate"
],
"properties": {
"unit": {
"enum": [
"persons",
"cases"
],
"type": "string",
"description": "What the counts count: persons, or cases that can cover several people."
},
"year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Calendar year of the figure."
},
"rejected": {
"type": [
"number",
"null"
],
"description": "Decisions rejecting the claim on its merits. Null when UNHCR marks it not applicable or not collected — never zero."
},
"recognized": {
"type": [
"number",
"null"
],
"description": "Decisions granting refugee status. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "Country of asylum, ISO3. Null when asylum countries are summed into this row."
},
"asylum_name": {
"type": [
"string",
"null"
],
"description": "Asylum country name. Null when summed."
},
"authorities": {
"type": "array",
"items": {
"type": "string",
"description": "One authority code."
},
"description": "Authority codes summed into this row; a single code when split_by keeps authority separate."
},
"origin_iso3": {
"type": [
"string",
"null"
],
"description": "Country of origin, ISO3. Null when origins are summed into this row."
},
"origin_name": {
"type": [
"string",
"null"
],
"description": "Origin country name. Null when summed."
},
"decision_levels": {
"type": "array",
"items": {
"type": "string",
"description": "One decision level code."
},
"description": "Decision-level codes summed into this row; a single code when split_by keeps decision level separate."
},
"total_decisions": {
"type": [
"number",
"null"
],
"description": "Sum of UNHCR’s published decision totals; rounding can set it apart from the four outcomes. Null when UNHCR marks it not applicable or not collected — never zero."
},
"otherwise_closed": {
"type": [
"number",
"null"
],
"description": "Cases closed without a substantive decision, such as withdrawn or abandoned claims. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the asylum country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"origin_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the origin country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"substantive_decisions": {
"type": [
"number",
"null"
],
"description": "recognized + complementary_protection + rejected: the rates’ denominator, null when any of the three is null in any upstream row summed into this row, rather than summed from the rest. Null when UNHCR marks it not applicable or not collected — never zero."
},
"total_protection_rate": {
"type": [
"number",
"null"
],
"description": "Percent on a 0–100 scale, 1 decimal place. Total Protection Rate: (recognized + complementary_protection) ÷ substantive_decisions × 100. Null when substantive_decisions is 0 or null."
},
"complementary_protection": {
"type": [
"number",
"null"
],
"description": "Decisions granting complementary protection instead of refugee status. Null when UNHCR marks it not applicable or not collected — never zero."
},
"refugee_recognition_rate": {
"type": [
"number",
"null"
],
"description": "Percent on a 0–100 scale, 1 decimal place. Refugee Recognition Rate: recognized ÷ substantive_decisions × 100. Null when substantive_decisions is 0 or null."
}
},
"description": "One year of decisions for one origin/asylum scope, level split, and unit.",
"additionalProperties": false
},
"description": "Inline rows, sorted, up to limit."
},
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "JSON-RPC error code for this failure."
},
"data": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"examples": [
"unknown_country_code",
"invalid_year_window",
"year_out_of_coverage",
"conflicting_scope",
"too_many_country_codes",
"upstream_busy"
],
"description": "Machine-readable failure mode. Declared by this tool: `unknown_country_code`: An origin or asylum value is not an ISO3 code in UNHCR's country list (after ISO2 normalization). `invalid_year_window`: year_from is later than year_to. `year_out_of_coverage`: The whole requested window lies outside the dataset's published years. `conflicting_scope`: expand names a dimension that origin or asylum already filters. `too_many_country_codes`: origin or asylum lists more distinct codes than one filter accepts. `upstream_busy`: This server's UNHCR request queue cannot start the call's requests before its deadline, or UNHCR answered 429. Other values are possible when a failure originates below the handler."
},
"recovery": {
"type": "object",
"required": [
"hint"
],
"properties": {
"hint": {
"type": "string"
}
},
"description": "Actionable next step for the caller.",
"additionalProperties": {}
},
"retryable": {
"type": "boolean",
"description": "Whether retrying may succeed."
}
},
"additionalProperties": {}
},
"message": {
"type": "string",
"description": "Human-readable description of what went wrong."
}
},
"description": "Present when the call failed. Absent on success.",
"additionalProperties": {}
},
"shown": {
"type": "number",
"description": "Rows returned inline."
},
"notice": {
"type": "string",
"description": "Guidance for this result: empty-result hints, year and limit clamps, where the full set was staged, or how to narrow."
},
"dataset": {
"type": "object",
"required": [
"name",
"row_count",
"expires_at"
],
"properties": {
"name": {
"type": "string",
"description": "Dataframe handle (df_XXXXX_XXXXX) for unhcr_dataframe_query."
},
"evicted": {
"type": "array",
"items": {
"type": "string"
},
"description": "Older dataframes dropped, oldest first, to keep the staged total within the 1,000,000-row budget; they can no longer be queried. Present only when staging this result evicted any."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows staged."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 time the staged table expires."
}
},
"description": "Present when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.",
"additionalProperties": false
},
"measure": {
"enum": [
"stock",
"flow"
],
"type": "string",
"description": "stock: people in a situation on 31 December; flow: events during the year."
},
"complete": {
"type": "boolean",
"description": "False when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow."
},
"truncated": {
"type": "boolean",
"description": "True when rows were cut at limit."
},
"data_notes": {
"type": "array",
"items": {
"type": "string"
},
"description": "How to read the counts: stock or flow, rounding, the meaning of null, caveats."
},
"total_rows": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result."
},
"attribution": {
"type": "object",
"required": [
"source",
"license",
"terms_url",
"providers"
],
"properties": {
"source": {
"type": "string",
"description": "Source to cite: \"UNHCR Refugee Population Statistics Database\"."
},
"license": {
"type": "string",
"description": "Dataset licence (CC BY 4.0)."
},
"providers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Third-party series in this result (IDMC, UNRWA), whose own conditions may apply."
},
"terms_url": {
"type": "string",
"description": "URL of UNHCR's Terms of Use for Datasets, to cite with the figures."
}
},
"description": "Attribution UNHCR requires when these figures are reused.",
"additionalProperties": false
},
"latest_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Newest year this dataset publishes."
},
"applied_scope": {
"type": "object",
"required": [
"origin",
"asylum",
"year_from",
"year_to",
"normalized"
],
"properties": {
"asylum": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the asylum dimension was queried.",
"additionalProperties": false
},
"origin": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the origin dimension was queried.",
"additionalProperties": false
},
"year_to": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Last year sent upstream, after filling and clamping."
},
"year_from": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "First year sent upstream, after filling and clamping."
},
"normalized": {
"type": "array",
"items": {
"type": "object",
"required": [
"input",
"iso3"
],
"properties": {
"iso3": {
"type": "string",
"description": "The ISO3 code it was rewritten to."
},
"input": {
"type": "string",
"description": "The code as given."
}
},
"description": "One ISO2 → ISO3 rewrite.",
"additionalProperties": false
},
"description": "ISO 3166 alpha-2 codes rewritten to ISO3."
}
},
"description": "The scope actually sent upstream, including clamped years and code rewrites.",
"additionalProperties": false
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true
}unhcr_get_solutions — UNHCR durable solutions
Get durable solutions per year (1959 to the latest year) by country of origin and/or asylum: refugees who returned home, refugees resettled to a third country, refugees naturalised, and IDPs who returned. The asylum country means something different per column: the country refugees returned from, the country they were resettled to, the country that naturalised them; IDP returns sit on the origin country itself. Null means the figure was not collected for that country and year, not zero.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"limit": {
"type": "integer",
"default": 25,
"minimum": 1,
"multipleOf": 1,
"description": "Inline rows. Default 25; a larger value returns at most 2000 and says so. Sorting runs over the full result first; a larger result is staged as a dataframe where dataframes are enabled."
},
"stage": {
"type": "boolean",
"default": false,
"description": "Stage the full result as a dataframe even when it fits inline, e.g. to join it with another unhcr_get_* result in unhcr_dataframe_query. Where dataframes are unavailable it is ignored, and the notice says so."
},
"asylum": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of asylum — where people sought or hold protection; for returns, the country they returned from — as ISO3 codes (DEU, TUR), case-insensitive, same rules and limit as origin. Omit to sum every asylum country into one row, or set expand to list each."
},
"expand": {
"enum": [
"none",
"origin",
"asylum",
"both"
],
"type": "string",
"default": "none",
"description": "List every country, one row each, for a dimension that origin or asylum leaves unfiltered: origin, asylum, or both. Default none, where an unfiltered dimension is summed into one row. Expanding a dimension that origin or asylum already filters is rejected."
},
"origin": {
"anyOf": [
{
"type": "string",
"maxLength": 1750,
"description": "One code, or several separated by commas or spaces, e.g. \"SYR\" or \"SYR, AFG\"."
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 1000,
"description": "Codes as a list, e.g. [\"SYR\", \"AFG\"]."
}
],
"description": "Country of origin — where people fled from — as ISO3 codes (SYR, AFG), case-insensitive. ISO 3166 alpha-2 codes (SY) are rewritten to ISO3 and echoed in applied_scope. UNHCR's own codes (GFR) are rejected with the ISO3 to pass instead, and country names are rejected: resolve a name with unhcr_list_reference (topic countries, name_contains). Each listed code returns its own rows; codes are never summed together. At most 250 distinct codes, enough to list every country in UNHCR's country list. Omit to sum every origin into one row, or set expand to list each."
},
"sort_by": {
"enum": [
"year",
"returned_refugees",
"resettlement",
"naturalisation",
"returned_idps"
],
"type": "string",
"default": "year",
"description": "Order of the full result before the inline cut. year (default) orders by year, then origin ISO3, then asylum ISO3; a count field orders largest first, nulls last."
},
"year_to": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "Last year of the window. When omitted, the window runs to the latest published year (latest_year in the result). A year past the latest published year is clamped to it and the clamp is reported."
},
"year_from": {
"type": "integer",
"maximum": 2100,
"minimum": 1900,
"description": "First year of the window. When omitted, the window starts at the dataset's first year. A year before the dataset's first year is clamped to it and the clamp is reported; a window entirely outside the dataset's years is rejected."
}
},
"additionalProperties": false
}{
"type": "object",
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"rows",
"total_rows",
"complete",
"measure",
"applied_scope",
"latest_year",
"data_notes",
"attribution",
"footnotes",
"footnotes_total"
]
},
{
"required": [
"error"
]
}
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"cap": {
"type": "number",
"description": "The limit that was applied."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"year",
"origin_iso3",
"origin_unhcr_code",
"origin_name",
"asylum_iso3",
"asylum_unhcr_code",
"asylum_name",
"returned_refugees",
"resettlement",
"naturalisation",
"returned_idps"
],
"properties": {
"year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Calendar year of the figure."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "Country of asylum, ISO3. Null when asylum countries are summed into this row."
},
"asylum_name": {
"type": [
"string",
"null"
],
"description": "Asylum country name. Null when summed."
},
"origin_iso3": {
"type": [
"string",
"null"
],
"description": "Country of origin, ISO3. Null when origins are summed into this row."
},
"origin_name": {
"type": [
"string",
"null"
],
"description": "Origin country name. Null when summed."
},
"resettlement": {
"type": [
"number",
"null"
],
"description": "Refugees resettled during the year, recorded against the country they were resettled to. Null when UNHCR marks it not applicable or not collected — never zero."
},
"returned_idps": {
"type": [
"number",
"null"
],
"description": "IDPs who returned during the year, recorded against the origin country itself. Null when UNHCR marks it not applicable or not collected — never zero."
},
"naturalisation": {
"type": [
"number",
"null"
],
"description": "Refugees naturalised during the year, recorded against the naturalising country. Null when UNHCR marks it not applicable or not collected — never zero."
},
"asylum_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the asylum country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"origin_unhcr_code": {
"type": [
"string",
"null"
],
"description": "UNHCR's own code for the origin country (GFR for Germany), for matching UNHCR publications; origin and asylum take the ISO3 code, not this. Null when summed."
},
"returned_refugees": {
"type": [
"number",
"null"
],
"description": "Refugees who returned to their origin country during the year, recorded against the country they returned from. Null when UNHCR marks it not applicable or not collected — never zero."
}
},
"description": "One year of durable solutions for one origin/asylum scope.",
"additionalProperties": false
},
"description": "Inline rows, sorted, up to limit."
},
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "JSON-RPC error code for this failure."
},
"data": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"examples": [
"unknown_country_code",
"invalid_year_window",
"year_out_of_coverage",
"conflicting_scope",
"too_many_country_codes",
"upstream_busy"
],
"description": "Machine-readable failure mode. Declared by this tool: `unknown_country_code`: An origin or asylum value is not an ISO3 code in UNHCR's country list (after ISO2 normalization). `invalid_year_window`: year_from is later than year_to. `year_out_of_coverage`: The whole requested window lies outside the dataset's published years. `conflicting_scope`: expand names a dimension that origin or asylum already filters. `too_many_country_codes`: origin or asylum lists more distinct codes than one filter accepts. `upstream_busy`: This server's UNHCR request queue cannot start the call's requests before its deadline, or UNHCR answered 429. Other values are possible when a failure originates below the handler."
},
"recovery": {
"type": "object",
"required": [
"hint"
],
"properties": {
"hint": {
"type": "string"
}
},
"description": "Actionable next step for the caller.",
"additionalProperties": {}
},
"retryable": {
"type": "boolean",
"description": "Whether retrying may succeed."
}
},
"additionalProperties": {}
},
"message": {
"type": "string",
"description": "Human-readable description of what went wrong."
}
},
"description": "Present when the call failed. Absent on success.",
"additionalProperties": {}
},
"shown": {
"type": "number",
"description": "Rows returned inline."
},
"notice": {
"type": "string",
"description": "Guidance for this result: empty-result hints, year and limit clamps, where the full set was staged, or how to narrow."
},
"dataset": {
"type": "object",
"required": [
"name",
"row_count",
"expires_at"
],
"properties": {
"name": {
"type": "string",
"description": "Dataframe handle (df_XXXXX_XXXXX) for unhcr_dataframe_query."
},
"evicted": {
"type": "array",
"items": {
"type": "string"
},
"description": "Older dataframes dropped, oldest first, to keep the staged total within the 1,000,000-row budget; they can no longer be queried. Present only when staging this result evicted any."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows staged."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 time the staged table expires."
}
},
"description": "Present when the full result was staged as a dataframe; read its columns with unhcr_dataframe_describe, then query it with unhcr_dataframe_query.",
"additionalProperties": false
},
"measure": {
"enum": [
"stock",
"flow"
],
"type": "string",
"description": "stock: people in a situation on 31 December; flow: events during the year."
},
"complete": {
"type": "boolean",
"description": "False when the server row cap stopped the upstream fetch; the notice says how many upstream rows were fetched and how to narrow."
},
"footnotes": {
"type": "array",
"items": {
"type": "object",
"required": [
"text",
"years",
"origin_iso3",
"asylum_iso3",
"population_types",
"rows_matched"
],
"properties": {
"text": {
"type": "string",
"description": "UNHCR's caveat text, verbatim."
},
"years": {
"type": "string",
"description": "Years the caveat covers, as UNHCR writes them (e.g. \"2019 - 2022\")."
},
"asylum_iso3": {
"type": [
"string",
"null"
],
"description": "ISO3 of the asylum country the caveat names; null when it applies to any asylum country."
},
"origin_iso3": {
"type": [
"string",
"null"
],
"description": "ISO3 of the origin country the caveat names; null when it applies to any origin."
},
"rows_matched": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows of the full result the caveat applies to: rows in its years and countries that carry one of its population types."
},
"population_types": {
"type": "array",
"items": {
"type": "string"
},
"description": "Population-type codes the caveat applies to (decode with unhcr_list_reference)."
}
},
"description": "One UNHCR data caveat that applies to rows of this result.",
"additionalProperties": false
},
"description": "UNHCR caveats matching rows of the full result, at most 20. Caveats on inline rows come before those only on rows past the cut; within each group, country-specific first, then in the order of the first row each matches."
},
"truncated": {
"type": "boolean",
"description": "True when rows were cut at limit."
},
"data_notes": {
"type": "array",
"items": {
"type": "string"
},
"description": "How to read the counts: stock or flow, rounding, the meaning of null, caveats."
},
"total_rows": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows in the full result before the inline cut. When complete is false, the result is built from only the upstream rows fetched before the cap, so rows and summed counts can fall short of the complete result."
},
"attribution": {
"type": "object",
"required": [
"source",
"license",
"terms_url",
"providers"
],
"properties": {
"source": {
"type": "string",
"description": "Source to cite: \"UNHCR Refugee Population Statistics Database\"."
},
"license": {
"type": "string",
"description": "Dataset licence (CC BY 4.0)."
},
"providers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Third-party series in this result (IDMC, UNRWA), whose own conditions may apply."
},
"terms_url": {
"type": "string",
"description": "URL of UNHCR's Terms of Use for Datasets, to cite with the figures."
}
},
"description": "Attribution UNHCR requires when these figures are reused.",
"additionalProperties": false
},
"latest_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Newest year this dataset publishes."
},
"applied_scope": {
"type": "object",
"required": [
"origin",
"asylum",
"year_from",
"year_to",
"normalized"
],
"properties": {
"asylum": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the asylum dimension was queried.",
"additionalProperties": false
},
"origin": {
"type": "object",
"required": [
"mode",
"codes"
],
"properties": {
"mode": {
"enum": [
"summed",
"listed",
"each"
],
"type": "string",
"description": "summed: every country added into one row; listed: one row per code in codes; each: one row per country (expand)."
},
"codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "ISO3 codes sent upstream; empty unless mode is listed."
}
},
"description": "How the origin dimension was queried.",
"additionalProperties": false
},
"year_to": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Last year sent upstream, after filling and clamping."
},
"year_from": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "First year sent upstream, after filling and clamping."
},
"normalized": {
"type": "array",
"items": {
"type": "object",
"required": [
"input",
"iso3"
],
"properties": {
"iso3": {
"type": "string",
"description": "The ISO3 code it was rewritten to."
},
"input": {
"type": "string",
"description": "The code as given."
}
},
"description": "One ISO2 → ISO3 rewrite.",
"additionalProperties": false
},
"description": "ISO 3166 alpha-2 codes rewritten to ISO3."
}
},
"description": "The scope actually sent upstream, including clamped years and code rewrites.",
"additionalProperties": false
},
"footnotes_total": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Caveats matching the full result, before the cap."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true
}unhcr_dataframe_describe — Describe staged dataframes
Describe a dataframe (df_XXXXX_XXXXX) staged by the unhcr_get_* tools — any response carrying a dataset or nowcast_dataset handle staged its full result here — or list them all where this deployment allows listing. Each entry gives the source tool, query parameters, creation and expiry time, row count, whether the upstream fetch was complete, and the column schema. Read the columns here before writing SQL for unhcr_dataframe_query.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"name": {
"type": "string",
"pattern": "^df_[A-Z0-9]{5}_[A-Z0-9]{5}$",
"maxLength": 14,
"description": "One dataframe to describe, as df_XXXXX_XXXXX (uppercase letters and digits): the dataset.name or nowcast_dataset.name a unhcr_get_* result returned, or a register_as name. Omit to list every staged dataframe; a deployment that serves unauthenticated callers over HTTP turns listing off, and there the name is required."
}
},
"additionalProperties": false
}{
"type": "object",
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"dataframes"
]
},
{
"required": [
"error"
]
}
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "JSON-RPC error code for this failure."
},
"data": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"examples": [
"canvas_unavailable",
"listing_unavailable"
],
"description": "Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: Dataframes are turned off in this deployment, or the SQL engine behind them could not load. `listing_unavailable`: name was omitted on a deployment that serves unauthenticated callers over HTTP, where a listing would show other callers' dataframes. Other values are possible when a failure originates below the handler."
},
"recovery": {
"type": "object",
"required": [
"hint"
],
"properties": {
"hint": {
"type": "string"
}
},
"description": "Actionable next step for the caller.",
"additionalProperties": {}
},
"retryable": {
"type": "boolean",
"description": "Whether retrying may succeed."
}
},
"additionalProperties": {}
},
"message": {
"type": "string",
"description": "Human-readable description of what went wrong."
}
},
"description": "Present when the call failed. Absent on success.",
"additionalProperties": {}
},
"notice": {
"type": "string",
"description": "Guidance when nothing is staged or the named dataframe is gone."
},
"dataframes": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"source_tool",
"query_params",
"created_at",
"expires_at",
"row_count",
"complete",
"incomplete_sources",
"providers",
"column_schema"
],
"properties": {
"name": {
"type": "string",
"description": "Dataframe name (df_XXXXX_XXXXX) to use in SQL."
},
"complete": {
"type": "boolean",
"description": "False when the server row cap stopped the upstream fetch that produced it."
},
"providers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Third-party series the rows carry (IDMC, UNRWA), for attribution."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows in the dataframe."
},
"created_at": {
"type": "string",
"description": "ISO 8601 time it was staged."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 time it expires."
},
"source_tool": {
"type": "string",
"description": "Tool that staged it: a unhcr_get_* tool, or unhcr_dataframe_query for a register_as result."
},
"query_params": {
"type": "object",
"description": "Arguments the source tool was called with, keyed by input name; { sql } for a register_as result.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"column_schema": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"type",
"nullable"
],
"properties": {
"name": {
"type": "string",
"description": "Column name."
},
"type": {
"type": "string",
"description": "Column type (INTEGER, DOUBLE, VARCHAR, BOOLEAN, …)."
},
"nullable": {
"type": "boolean",
"description": "Whether the column may hold NULL."
}
},
"description": "One column.",
"additionalProperties": false
},
"description": "Columns in table order."
},
"incomplete_sources": {
"type": "array",
"items": {
"type": "string"
},
"description": "Original incomplete upstream handles retained through saved descendants, even after those ancestors expire or are evicted."
}
},
"description": "One staged dataframe.",
"additionalProperties": false
},
"description": "Staged dataframes, newest first. Empty when none are staged."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true
}unhcr_dataframe_query — Query staged dataframes
Run a single-statement SELECT against the dataframes staged by the unhcr_get_* tools. Check a dataframe’s columns with unhcr_dataframe_describe first. Writes, DDL, DROP, COPY, PRAGMA, ATTACH, file references, external-data functions, engine introspection, dynamic table lookup, and system catalogs are rejected; query() accepts only a single SQL string literal, checked by the same gate. Optional register_as saves the result as a new dataframe with a fresh TTL. Recompute rates from summed counts rather than averaging rate columns.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"sql"
],
"properties": {
"sql": {
"type": "string",
"maxLength": 20000,
"minLength": 1,
"description": "One DuckDB SELECT against df_XXXXX_XXXXX tables, at most 20,000 characters — joins, aggregates, window functions, and CTEs work. SUM and COUNT results come back as JSON strings (BIGINT); CAST(… AS DOUBLE) for inline arithmetic. Staged tables add origin/asylum UNHCR and UN region columns for regional GROUP BY."
},
"preview": {
"type": "integer",
"minimum": 0,
"multipleOf": 1,
"description": "Rows returned inline; 0 returns only the columns and counts. Default 25; a larger value returns at most 1500, or row_limit when lower, and says so."
},
"row_limit": {
"type": "integer",
"default": 1000,
"minimum": 1,
"multipleOf": 1,
"description": "Most rows the query materializes. Default 1000; a larger value materializes at most 10000 and says so. When more rows match, row_count_capped is true; use register_as to keep the full result."
},
"register_as": {
"type": "string",
"pattern": "^df_[A-Z0-9]{5}_[A-Z0-9]{5}$",
"maxLength": 14,
"description": "Save the result as a new dataframe under this name (df_ plus two groups of 5 uppercase letters or digits, e.g. df_ABCDE_12345) with a fresh TTL, to chain analyses. The name must not already be staged. The saved rows count toward the 1,000,000-row staging budget: the oldest other dataframes are evicted to make room, and a result larger than the budget is not saved."
}
},
"additionalProperties": false
}{
"type": "object",
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"complete",
"incomplete_sources",
"columns",
"row_count",
"row_count_capped",
"rows",
"attribution"
]
},
{
"required": [
"error"
]
}
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"cap": {
"type": "number",
"description": "The cap that bound: preview when lower than row_limit, otherwise row_limit."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "The first preview rows of the result, one object per row keyed by column name. BIGINT values (SUM, COUNT) arrive as strings."
},
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "JSON-RPC error code for this failure."
},
"data": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"examples": [
"canvas_unavailable",
"missing_table",
"invalid_sql",
"sql_execution_error",
"register_as_clash",
"register_as_too_large",
"non_select_statement",
"multi_statement",
"denied_function",
"plan_operator_not_allowed",
"system_catalog_access"
],
"description": "Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: Dataframes are turned off in this deployment, or the SQL engine behind them could not load. `missing_table`: A df_<id> the SQL names is not staged: it never existed, its TTL expired, or it was evicted to make room for newer dataframes. `invalid_sql`: A statement starting with SELECT, WITH, or FROM does not parse, or the SELECT fails to prepare: an unknown column, table, or function, or an invalid expression. `sql_execution_error`: The SELECT prepared but failed on the data it read: a cast or conversion that does not fit, an out-of-range value, or invalid input to a function. `register_as_clash`: The register_as name is already a staged dataframe. `register_as_too_large`: The register_as result alone holds more rows than the 1,000,000-row staging budget, so it was not saved. `non_select_statement`: The statement is not a read-only SELECT: an INSERT, UPDATE, DDL, PRAGMA, or other write the engine refuses, or SQL that fails to parse and does not start with SELECT, WITH, or FROM (such as a misspelled SELEC). `multi_statement`: The SQL holds more than one statement. `denied_function`: The SQL calls a denied external-data or introspection function, uses query_table, or passes query() anything other than a single SQL string literal. `plan_operator_not_allowed`: The query plan uses an operator outside the read-only allowlist, such as the range() or generate_series() table functions. `system_catalog_access`: The SQL references a system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*). Other values are possible when a failure originates below the handler."
},
"recovery": {
"type": "object",
"required": [
"hint"
],
"properties": {
"hint": {
"type": "string"
}
},
"description": "Actionable next step for the caller.",
"additionalProperties": {}
},
"retryable": {
"type": "boolean",
"description": "Whether retrying may succeed."
}
},
"additionalProperties": {}
},
"message": {
"type": "string",
"description": "Human-readable description of what went wrong."
}
},
"description": "Present when the call failed. Absent on success.",
"additionalProperties": {}
},
"shown": {
"type": "number",
"description": "Rows returned inline."
},
"notice": {
"type": "string",
"description": "Guidance for this result: a clamped count, an incomplete source, an empty result, or rows withheld by preview or row_limit."
},
"columns": {
"type": "array",
"items": {
"type": "string"
},
"description": "Column names in projection order."
},
"evicted": {
"type": "array",
"items": {
"type": "string"
},
"description": "Older dataframes dropped, oldest first, to keep the staged total within the 1,000,000-row budget once register_as saved this result; they can no longer be queried. Present only when any were evicted."
},
"complete": {
"type": "boolean",
"description": "False when any original source fetch was incomplete, independently of display truncation."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows the query produced, up to row_limit; with register_as, every row of the saved result. When row_count_capped is true this is the cap, not the full size."
},
"truncated": {
"type": "boolean",
"description": "True when preview or row_limit withheld rows."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 expiry of the new dataframe, when register_as was set."
},
"attribution": {
"type": "object",
"required": [
"source",
"license",
"terms_url",
"providers"
],
"properties": {
"source": {
"type": "string",
"description": "Source to cite: \"UNHCR Refugee Population Statistics Database\"."
},
"license": {
"type": "string",
"description": "Dataset licence (CC BY 4.0)."
},
"providers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Third-party series in this result (IDMC, UNRWA), whose own conditions may apply."
},
"terms_url": {
"type": "string",
"description": "URL of UNHCR's Terms of Use for Datasets, to cite with the figures."
}
},
"description": "Attribution UNHCR requires when these figures are reused.",
"additionalProperties": false
},
"registered_as": {
"type": "string",
"description": "The new dataframe, when register_as was set."
},
"row_count_capped": {
"type": "boolean",
"description": "True when more rows matched than row_limit allowed through."
},
"incomplete_sources": {
"type": "array",
"items": {
"type": "string"
},
"description": "Original incomplete upstream dataframe handles; retained through saved descendants."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true
}Prompts
0 advertised
Resources
1 advertised
unhcr-refugees-guide
Gates for answering displacement and asylum questions with the unhcr_* tools of unhcr-refugees-mcp-server — which columns a total sums, stateless people under origin XXA, the two Palestine refugee series, the nowcast's missing origin, bureau and EU totals in SQL, stage and decision-level filters that drop countries, switching units, demographic shares, solutions start years, and footnotes. Use before ranking, summing, or comparing UNHCR figures across countries, years, or tools.
skill://unhcr-refugees-guide/SKILL.mdio.modelcontextprotocol/skills
skill://{+path}30-day availability
Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.
- Successful checks
- 1 of 1 (100%)
- Average latency
- 715 ms
- 95th percentile latency
- 715 ms
Maintenance history
Public check and source-refresh events. Editorial and ownership records remain private.
- · probe · passed · 715 ms · metadata changed · 8 tool(s), 1 resource(s), 1 resource template(s), 0 prompt(s)
Connect from your client
Each snippet registers the same endpoint; pick the client you use.
Claude Code
claude mcp add --transport http unhcr-refugees-mcp-server https://unhcr-refugees.caseyjhand.com/mcpCodex
codex mcp add unhcr-refugees-mcp-server --url https://unhcr-refugees.caseyjhand.com/mcpCursor
{
"mcpServers": {
"unhcr-refugees-mcp-server": {
"url": "https://unhcr-refugees.caseyjhand.com/mcp"
}
}
}Cline
{
"mcpServers": {
"unhcr-refugees-mcp-server": {
"type": "streamableHttp",
"url": "https://unhcr-refugees.caseyjhand.com/mcp",
"disabled": false
}
}
}VS Code
{
"servers": {
"unhcr-refugees-mcp-server": {
"type": "http",
"url": "https://unhcr-refugees.caseyjhand.com/mcp"
}
}
}Gemini CLI
gemini mcp add --transport http unhcr-refugees-mcp-server https://unhcr-refugees.caseyjhand.com/mcpClaude Desktop
https://unhcr-refugees.caseyjhand.com/mcpWindsurf
{
"mcpServers": {
"unhcr-refugees-mcp-server": {
"serverUrl": "https://unhcr-refugees.caseyjhand.com/mcp"
}
}
}Let your agent find its tools
Find servers like unhcr-refugees-mcp-server from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.