{
  "openapi": "3.1.1",
  "info": {
    "title": "Cartograph Flag Finder (find a flag by its colours and layout) API",
    "version": "1.0.0",
    "summary": "Saw a flag and don’t know whose it is? Pick its colours, stripes and symbols to find the country.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://cartographflagfinder.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Saw a flag and don’t know whose it is? Pick its colours, stripes and symbols to find the country.",
        "description": "Finds the flags of 197 countries by their colours (red, dark red, orange, yellow, green, blue, light blue, white, black), their layout (horizontal, vertical or diagonal stripes, cross, saltire, canton, hoist triangle, border) and their symbols (disc, star, crescent, sun, coat of arms, writing, map, Union Jack, animal, plant, weapon), optionally with the number of stripes and a region. Every flag gets a score from 0 to 100; the best matches are shown with their flags. It is the flag-finder engine of the Cartograph app.\n\nMethodology:\n- Colours: every flag picture (flag-icons SVG, 4:3) was drawn once at 200 × 150 pixels and each pixel assigned to the nearest of nine named colours in CIELAB. Colours covering at least 3 % of the flag are its main colours; 0.8–3 % count as small details (emblems, outlines).\n- Layout and symbols: tags curated for every flag and checked against the flag descriptions of The World Factbook; the stripe count is measured at the fly edge (horizontal) and near the top (vertical).\n- Score: each wanted colour counts 1 when it is a main colour, 0.6 when a close colour is (red ↔ dark red/orange, blue ↔ light blue, yellow ↔ orange) and 0.35 when it only appears in details; each wanted feature 1 (0.5 for a close one, e.g. cross ↔ saltire, disc ↔ sun); the stripe count 1 when equal and 0.4 when one off. The sum is divided by the number of wishes; extra main colours cost a little (more with “only these colours”), excluded colours cost 0.5 each.\n- Results are sorted by score, then by English name. Flags are shown in the 4:3 drawing of flag-icons; official proportions differ for many countries.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "cartograph_flag_finder",
        "x-owner-app": "cartograph",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CartographFlagFinderInput"
              },
              "examples": {
                "example1": {
                  "summary": "Red, white and blue in three vertical stripes",
                  "value": {
                    "colours": [
                      "red",
                      "white",
                      "blue"
                    ],
                    "features": [
                      "vstripes"
                    ],
                    "bands": 3
                  }
                },
                "example2": {
                  "summary": "Green flag with a red disc",
                  "value": {
                    "colours": [
                      "green",
                      "red"
                    ],
                    "features": [
                      "disc"
                    ],
                    "onlyColours": true
                  }
                },
                "example3": {
                  "summary": "African flag in green, yellow and red with a star",
                  "value": {
                    "colours": [
                      "green",
                      "yellow",
                      "red"
                    ],
                    "features": [
                      "star"
                    ],
                    "region": "africa",
                    "limit": 8
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CartographFlagFinderResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "CartographFlagFinderInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "colours": {
            "title": "Colours in the flag",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "red",
                "maroon",
                "orange",
                "yellow",
                "green",
                "blue",
                "lightblue",
                "white",
                "black"
              ]
            },
            "default": [
              "red",
              "white",
              "blue"
            ]
          },
          "features": {
            "title": "Layout and symbols",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "hstripes",
                "vstripes",
                "diagonal",
                "cross",
                "saltire",
                "canton",
                "triangle",
                "border",
                "plain",
                "disc",
                "star",
                "crescent",
                "sun",
                "emblem",
                "text",
                "map",
                "unionjack",
                "animal",
                "plant",
                "weapon"
              ]
            },
            "default": []
          },
          "bands": {
            "title": "Number of stripes (0 = any)",
            "type": "integer",
            "minimum": 0,
            "maximum": 15,
            "default": 0
          },
          "exclude": {
            "title": "Colours that are NOT in the flag",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "red",
                "maroon",
                "orange",
                "yellow",
                "green",
                "blue",
                "lightblue",
                "white",
                "black"
              ]
            },
            "default": []
          },
          "region": {
            "title": "Region",
            "type": "string",
            "enum": [
              "world",
              "africa",
              "asia",
              "europe",
              "north-america",
              "south-america",
              "oceania"
            ],
            "default": "world"
          },
          "onlyColours": {
            "title": "Only these colours (penalise flags with more colours)",
            "type": "boolean",
            "default": false
          },
          "limit": {
            "title": "Results",
            "type": "integer",
            "minimum": 1,
            "maximum": 30,
            "default": 12
          }
        },
        "required": []
      },
      "CartographFlagFinderResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "query",
              "total",
              "results",
              "openInApp"
            ],
            "properties": {
              "query": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "colours",
                  "exclude",
                  "features",
                  "bands",
                  "region",
                  "onlyColours"
                ],
                "properties": {
                  "colours": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "exclude": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "features": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "bands": {
                    "type": "integer"
                  },
                  "region": {
                    "type": "string"
                  },
                  "onlyColours": {
                    "type": "boolean"
                  }
                }
              },
              "total": {
                "type": "integer",
                "description": "Flags compared (197 for the whole world)."
              },
              "results": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "rank",
                    "iso2",
                    "iso3",
                    "name",
                    "score",
                    "colours",
                    "features",
                    "matched",
                    "missing"
                  ],
                  "properties": {
                    "rank": {
                      "type": "integer"
                    },
                    "iso2": {
                      "type": "string"
                    },
                    "iso3": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "score": {
                      "type": "integer",
                      "description": "0–100."
                    },
                    "colours": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "matched": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "missing": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "openInApp": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}