{
  "openapi": "3.1.0",
  "info": {
    "title": "erdetdekning? API",
    "version": "1",
    "description": "Mobildekning i Norge fra Telenor, Telia og Ice, for én posisjon om gangen. Bygger på operatørenes egne dekningskart: beregnet dekning, ikke en garanti. Bruk av dataene skal krediteres: «Dekning: erdetdekning.no», lenket til https://erdetdekning.no. For API-et holder en krediteringsside i appen eller på nettstedet; for kartlaget vises kreditten sammen med kartet.",
    "contact": { "url": "https://erdetdekning.no/api.html" }
  },
  "servers": [{ "url": "https://erdetdekning.no" }],
  "security": [{ "apiKey": [] }],
  "paths": {
    "/api/v1/erdetnodnummer": {
      "get": {
        "operationId": "erDetNodnummer",
        "summary": "Kan jeg ringe nødnummeret her?",
        "description": "Har minst én operatør samtaledekning på stedet? Nødsamtaler (112) bruker alle tilgjengelige nett, uansett operatør.",
        "parameters": [
          { "$ref": "#/components/parameters/lat" },
          { "$ref": "#/components/parameters/lng" }
        ],
        "responses": {
          "200": {
            "description": "Svaret, som en JSON-streng.",
            "content": {
              "application/json": {
                "schema": { "type": "string", "enum": ["ja!", "nei"] },
                "example": "ja!"
              }
            }
          },
          "400": { "$ref": "#/components/responses/badRequest" },
          "403": { "$ref": "#/components/responses/forbidden" },
          "404": { "$ref": "#/components/responses/notFound" },
          "429": { "$ref": "#/components/responses/tooManyRequests" }
        }
      }
    },
    "/api/v1/hvilkenettverk": {
      "get": {
        "operationId": "hvilkeNettverk",
        "summary": "Hvilke nett er det her?",
        "description": "Nivå for samtaler og mobildata og mobilnett for hver operatør, og hvilken versjon av dataene svaret bygger på.",
        "parameters": [
          { "$ref": "#/components/parameters/lat" },
          { "$ref": "#/components/parameters/lng" }
        ],
        "responses": {
          "200": {
            "description": "Dekningen hos hver operatør.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Networks" },
                "example": {
                  "operators": {
                    "telenor": { "call": 2, "data": 2, "networks": ["5g", "4g", "2g"] },
                    "telia": { "call": 1, "data": 1, "networks": ["4g"] },
                    "ice": { "call": 2, "data": 2, "networks": ["4g"] }
                  },
                  "dataset": { "version": "2026-10-03", "built": "2026-10-04" }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/badRequest" },
          "403": { "$ref": "#/components/responses/forbidden" },
          "404": { "$ref": "#/components/responses/notFound" },
          "429": { "$ref": "#/components/responses/tooManyRequests" }
        }
      }
    },
    "/maptiles/v1/{set}.json": {
      "get": {
        "operationId": "kartlagBeskrivelse",
        "summary": "Kartlaget: TileJSON",
        "parameters": [
          { "$ref": "#/components/parameters/set" },
          { "$ref": "#/components/parameters/mapKey" }
        ],
        "responses": {
          "200": {
            "description": "Beskrivelsen av laget, med fliseadressen og nøkkelen din.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TileJson" },
                "example": {
                  "tilejson": "3.0.0",
                  "name": "erdetdekning combined",
                  "minzoom": 5,
                  "maxzoom": 12,
                  "attribution": "Dekning: Telenor, Telia, Ice via <a href=\"https://erdetdekning.no\">erdetdekning.no</a>",
                  "tiles": ["https://erdetdekning.no/maptiles/v1/combined/{z}/{x}/{y}.pbf?key=DIN_NØKKEL"]
                }
              }
            }
          },
          "403": { "$ref": "#/components/responses/forbidden" },
          "404": { "description": "Ukjent lag." }
        }
      }
    },
    "/maptiles/v1/{set}/{z}/{x}/{y}.pbf": {
      "get": {
        "operationId": "kartlagFlis",
        "summary": "Kartlaget: en vektorflis",
        "parameters": [
          { "$ref": "#/components/parameters/set" },
          { "$ref": "#/components/parameters/z" },
          { "$ref": "#/components/parameters/x" },
          { "$ref": "#/components/parameters/y" },
          { "$ref": "#/components/parameters/mapKey" }
        ],
        "responses": {
          "200": {
            "description": "Flisen, som Mapbox Vector Tile, gzip-pakket.",
            "content": {
              "application/vnd.mapbox-vector-tile": {
                "schema": { "type": "string", "format": "binary" }
              }
            }
          },
          "204": { "description": "Ingen dekning i denne flisen." },
          "403": { "$ref": "#/components/responses/forbidden" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      },
      "mapKey": {
        "type": "apiKey",
        "in": "query",
        "name": "key"
      }
    },
    "parameters": {
      "set": {
        "name": "set",
        "in": "path",
        "required": true,
        "description": "Laget: telenor, telia, ice eller combined (alle tre i ett).",
        "schema": { "type": "string", "enum": ["telenor", "telia", "ice", "combined"] },
        "example": "combined"
      },
      "z": {
        "name": "z",
        "in": "path",
        "required": true,
        "description": "Zoomnivå, 5 til 12.",
        "schema": { "type": "integer", "minimum": 5, "maximum": 12 }
      },
      "x": {
        "name": "x",
        "in": "path",
        "required": true,
        "description": "Flisens kolonne (XYZ).",
        "schema": { "type": "integer", "minimum": 0 }
      },
      "y": {
        "name": "y",
        "in": "path",
        "required": true,
        "description": "Flisens rad (XYZ, fra nord).",
        "schema": { "type": "integer", "minimum": 0 }
      },
      "mapKey": {
        "name": "key",
        "in": "query",
        "required": true,
        "description": "Kartlagnøkkelen din. Egen nøkkel, ikke den du bruker mot punkt-API-et.",
        "schema": { "type": "string" }
      },
      "lat": {
        "name": "lat",
        "in": "query",
        "required": true,
        "description": "Breddegrad (WGS84).",
        "schema": { "type": "number", "minimum": -85.05, "maximum": 85.05 },
        "example": 61.636
      },
      "lng": {
        "name": "lng",
        "in": "query",
        "required": true,
        "description": "Lengdegrad (WGS84).",
        "schema": { "type": "number", "minimum": -180, "maximum": 180 },
        "example": 8.312
      }
    },
    "responses": {
      "badRequest": {
        "description": "Mangler eller ugyldig lat / lng.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": "lat og lng må være gyldige koordinater" }
          }
        }
      },
      "forbidden": {
        "description": "Mangler eller ukjent API-nøkkel.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/GatewayMessage" },
            "example": { "message": "Forbidden" }
          }
        }
      },
      "notFound": {
        "description": "Ingen dekningsdata på stedet (utenfor Norge).",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": "Ingen dekningsdata her" }
          }
        }
      },
      "tooManyRequests": {
        "description": "For mange forespørsler; vent litt og prøv igjen.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/GatewayMessage" },
            "example": { "message": "Too Many Requests" }
          }
        }
      }
    },
    "schemas": {
      "Level": {
        "type": "integer",
        "enum": [0, 1, 2, 3],
        "description": "0 ingen, 1 svak, 2 god, 3 svært god."
      },
      "Network": {
        "type": "string",
        "enum": ["5g", "4g", "2g"]
      },
      "OperatorCoverage": {
        "type": "object",
        "required": ["call", "data", "networks"],
        "properties": {
          "call": { "$ref": "#/components/schemas/Level", "description": "Nivå for samtaler." },
          "data": { "$ref": "#/components/schemas/Level", "description": "Nivå for mobildata." },
          "networks": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Network" },
            "description": "Mobilnettene som dekker stedet, beste først. Tom uten dekning."
          }
        }
      },
      "Dataset": {
        "type": "object",
        "required": ["version", "built"],
        "properties": {
          "version": { "type": "string", "description": "Hvilken innhenting dataene kommer fra." },
          "built": { "type": "string", "format": "date", "description": "Når dataene ble bygget." }
        }
      },
      "Networks": {
        "type": "object",
        "required": ["operators", "dataset"],
        "properties": {
          "operators": {
            "type": "object",
            "required": ["telenor", "telia", "ice"],
            "properties": {
              "telenor": { "$ref": "#/components/schemas/OperatorCoverage" },
              "telia": { "$ref": "#/components/schemas/OperatorCoverage" },
              "ice": { "$ref": "#/components/schemas/OperatorCoverage" }
            }
          },
          "dataset": { "$ref": "#/components/schemas/Dataset" }
        }
      },
      "TileJson": {
        "type": "object",
        "required": ["tilejson", "tiles", "minzoom", "maxzoom"],
        "properties": {
          "tilejson": { "type": "string" },
          "name": { "type": "string" },
          "attribution": { "type": "string" },
          "minzoom": { "type": "integer" },
          "maxzoom": { "type": "integer" },
          "bounds": { "type": "array", "items": { "type": "number" } },
          "tiles": { "type": "array", "items": { "type": "string" } },
          "vector_layers": { "type": "array", "items": { "type": "object" } }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": { "error": { "type": "string" } }
      },
      "GatewayMessage": {
        "type": "object",
        "required": ["message"],
        "properties": { "message": { "type": "string" } }
      }
    }
  }
}
