{
  "openapi": "3.1.0",
  "info": {
    "title": "REKO-ringar Public API",
    "version": "1.0.0",
    "summary": "Read-only API for Sweden's REKO rings.",
    "description": "A small, read-only HTTP API for the REKO-ringar dataset: where Sweden's REKO rings are, their pickup point, schedule, link and status. Access is gated by an API key issued by the REKO-ringar team. Request one at we@remagine.one.",
    "contact": { "name": "We Remagine One AB", "email": "we@remagine.one", "url": "https://rekoringar.app" }
  },
  "servers": [
    { "url": "https://api.rekoringar.app/functions/v1", "description": "Production (Supabase Edge Function)" }
  ],
  "security": [{ "bearerAuth": [] }, { "apiKeyHeader": [] }],
  "paths": {
    "/rings": {
      "get": {
        "operationId": "listRings",
        "summary": "List rings",
        "description": "Returns all rings, optionally filtered by status or modification time.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only rings with this status.",
            "schema": { "type": "string", "enum": ["active", "uncertain", "closed"] }
          },
          {
            "name": "modified_since",
            "in": "query",
            "required": false,
            "description": "Only rings updated at or after this ISO-8601 timestamp (for incremental syncs).",
            "schema": { "type": "string", "format": "date-time" }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RingsResponse" } } }
          },
          "401": {
            "description": "Missing, invalid, or revoked API key.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          },
          "500": {
            "description": "Server error.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "description": "Authorization: Bearer <key>" },
      "apiKeyHeader": { "type": "apiKey", "in": "header", "name": "x-api-key" }
    },
    "schemas": {
      "RingsResponse": {
        "type": "object",
        "required": ["count", "generated_at", "rings"],
        "properties": {
          "count": { "type": "integer", "example": 294 },
          "generated_at": { "type": "string", "format": "date-time" },
          "rings": { "type": "array", "items": { "$ref": "#/components/schemas/Ring" } }
        }
      },
      "Ring": {
        "type": "object",
        "required": ["id", "name", "status"],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "city": { "type": ["string", "null"] },
          "lat": {
            "type": ["number", "null"],
            "description": "Effective pin latitude: the exact pickup point if known, else the city coordinate."
          },
          "lon": { "type": ["number", "null"], "description": "Effective pin longitude." },
          "has_pickup": {
            "type": "boolean",
            "description": "True when lat/lon is the exact pickup point (not just the city)."
          },
          "pickup_location": { "type": ["string", "null"] },
          "schedule": { "type": ["string", "null"] },
          "website": { "type": ["string", "null"] },
          "status": { "type": "string", "enum": ["active", "uncertain", "closed"] },
          "data_quality": { "type": "string", "enum": ["high", "medium", "low", "incomplete"] },
          "verified": { "type": "boolean" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": { "error": { "type": "string" } }
      }
    }
  }
}
