{
  "openapi": "3.1.0",
  "info": {
    "title": "Geotone API",
    "version": "1.0.0",
    "summary": "Live media-intelligence signals derived from global news coverage",
    "description": "Read-only JSON mirrors of every Geotone dashboard: coverage volume, tone, surge z-scores, and article samples for 40 geopolitical topics and 196 countries. Derived data is CC BY 4.0 — attribute 'Geotone / GDELT'. Endpoints mirror pages one-to-one; there are intentionally no bulk-export routes. Rate limit: 60 uncached requests/minute/IP (cached responses are unlimited).",
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    },
    "contact": {
      "email": "contact@geotone.news",
      "url": "https://geotone.news/about"
    }
  },
  "servers": [
    {
      "url": "https://geotone.news"
    }
  ],
  "paths": {
    "/api/v1/topics": {
      "get": {
        "operationId": "listTopics",
        "summary": "All tracked topics with current stats (no series)",
        "responses": {
          "200": {
            "description": "Topic list",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api/v1/topics/{slug}": {
      "get": {
        "operationId": "getTopic",
        "summary": "One topic: 90-day volume/tone series, z-score, WoW change, article sample",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "ukraine-war"
          }
        ],
        "responses": {
          "200": {
            "description": "Topic detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "slug": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "snapshots": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string",
                                "format": "date"
                              },
                              "volIntensity": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Percent of all GDELT-monitored coverage"
                              },
                              "toneAvg": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Mean GDELT tone, roughly -10..+10"
                              }
                            }
                          }
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "description": "License and attribution — present on every response",
                      "properties": {
                        "license": {
                          "type": "string",
                          "const": "CC BY 4.0"
                        },
                        "attribution": {
                          "type": "string",
                          "const": "Geotone / GDELT"
                        },
                        "source": {
                          "type": "string"
                        },
                        "docs": {
                          "type": "string"
                        },
                        "generated": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown topic"
          },
          "429": {
            "description": "Rate limited (60 uncached req/min/IP)"
          }
        }
      }
    },
    "/api/v1/countries": {
      "get": {
        "operationId": "listCountries",
        "summary": "All tracked countries with current stats (no series)",
        "responses": {
          "200": {
            "description": "Country list",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api/v1/countries/{iso2}": {
      "get": {
        "operationId": "getCountry",
        "summary": "One country: 90-day volume/tone series, active topics, armed-conflict totals (UCDP), displacement stocks (UNHCR), and coverage origin (local vs international share)",
        "parameters": [
          {
            "name": "iso2",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2
            },
            "example": "ua"
          }
        ],
        "responses": {
          "200": {
            "description": "Country detail",
            "content": {
              "application/json": {}
            }
          },
          "404": {
            "description": "Unknown country"
          }
        }
      }
    },
    "/api/v1/trending": {
      "get": {
        "operationId": "getTrending",
        "summary": "Surging topics (z ≥ 2), biggest week-over-week movers, surging countries",
        "responses": {
          "200": {
            "description": "Trending signals",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api/v1/relations/{pair}": {
      "get": {
        "operationId": "getRelation",
        "summary": "Bilateral co-coverage series for a monitored country pair",
        "parameters": [
          {
            "name": "pair",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-zA-Z]{2}-[a-zA-Z]{2}$"
            },
            "example": "cn-us"
          }
        ],
        "responses": {
          "200": {
            "description": "Relation detail (series may be empty until collection begins)"
          },
          "404": {
            "description": "Pair not monitored"
          }
        }
      }
    },
    "/api/v1/briefings/{date}": {
      "get": {
        "operationId": "getBriefing",
        "summary": "Daily briefings for a date (publishing begins in a later release)",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-07-02"
          }
        ],
        "responses": {
          "200": {
            "description": "Briefings for the date"
          },
          "404": {
            "description": "No briefing for that date"
          }
        }
      }
    }
  }
}