{
  "openapi": "3.1.0",
  "info": {
    "title": "Kako u Njemačkoj REST API",
    "description": "Zvanični javni mašinski čitljiv REST API portala Kako u Njemačkoj. Pruža pretragu, dohvat članaka, tema, cjenovnika i kalkulatora za život i rad u Njemačkoj. Podržava besplatan nivo (Free Tier), samoposlužni pristup (Self-Serve) i sandbox okruženje.",
    "version": "1.1.0",
    "contact": {
      "name": "Kako u Njemačkoj Developer Support",
      "url": "https://kakounjemackoj.de/developers",
      "email": "kontakt@kakounjemackoj.de"
    },
    "license": {
      "name": "CC BY-SA 4.0 / Open Knowledge License",
      "url": "https://creativecommons.org/licenses/by-sa/4.0/"
    }
  },
  "servers": [
    {
      "url": "https://kakounjemackoj.de/api/v1",
      "description": "Production API Server (v1)"
    },
    {
      "url": "https://kakounjemackoj.de",
      "description": "Production Root Server"
    }
  ],
  "security": [
    {},
    {
      "BearerAuth": []
    },
    {
      "OAuth2": ["read:guides"]
    }
  ],
  "paths": {
    "/api/v1/posts": {
      "get": {
        "summary": "Dohvati listu objavljenih vodiča i članaka (paginacija)",
        "description": "Vraća paginiranu listu članaka sortiranu od najnovijih prema najstarijim sa metapodacima i sažecima.",
        "operationId": "getPostsListV1",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Broj stranice (počevši od 1)",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Broj članaka po stranici (maksimalno 50)",
            "schema": {
              "type": "integer",
              "default": 8,
              "minimum": 1,
              "maximum": 50
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Filtriraj po slug-u teme/kategorije (npr. 'stanovanje-i-najam', 'vize-i-dozvole')",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Uspješno dohvaćena lista članaka",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedPostsResponse"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequestError" },
          "404": { "$ref": "#/components/responses/NotFoundError" },
          "500": { "$ref": "#/components/responses/InternalServerError" }
        }
      }
    },
    "/api/v1/search": {
      "get": {
        "summary": "Pretraga baze znanja, vodiča i tema",
        "description": "Brza pretraga svih članaka, pojmova, njemačkih izraza i rubrika.",
        "operationId": "searchGuidesAndTopicsV1",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Pojam za pretragu (npr. 'anmeldung', 'viza', 'stan', 'schufa', 'plata')",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Rezultati pretrage",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequestError" },
          "500": { "$ref": "#/components/responses/InternalServerError" }
        }
      }
    },
    "/api/v1/categories": {
      "get": {
        "summary": "Popis svih tema i kategorija vodiča",
        "description": "Vraća hijerarhijski popis svih 26 tematskih cjelina sa opisima i slugovima.",
        "operationId": "getCategoriesListV1",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Popis kategorija",
            "headers": {
              "X-RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "X-RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "X-RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoriesResponse"
                }
              }
            }
          },
          "500": { "$ref": "#/components/responses/InternalServerError" }
        }
      }
    },
    "/api/v1/pricing": {
      "get": {
        "summary": "Cjenovnik, Free Tier i uslovi pristupa",
        "description": "Vraća mašinski čitljive cjenovne planove za čitaoce, registrovane korisnike i autonomne AI agente.",
        "operationId": "getPricingPlansV1",
        "responses": {
          "200": {
            "description": "Uspješno vraćeni planovi i cjenovnik",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricingResponse"
                }
              }
            }
          }
        }
      }
    },
    "/rss.xml": {
      "get": {
        "summary": "RSS 2.0 feed najnovijih članaka",
        "description": "Dohvati najnovije objavljene članke sa naslovima, linkovima i sažecima.",
        "operationId": "getLatestArticlesRss",
        "responses": {
          "200": {
            "description": "RSS XML feed članaka",
            "content": {
              "application/rss+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "summary": "Sažetak za jezičke modele i AI agente (llms.txt)",
        "description": "Strukturirani tekstualni sažetak portala za LLM modele prema standardu llmstxt.org.",
        "operationId": "getLlmsSummary",
        "responses": {
          "200": {
            "description": "Tekstualni sažetak",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/pricing.md": {
      "get": {
        "summary": "Markdown cjenovnik i pravila pristupa portalu",
        "description": "Markdown specifikacija o besplatnom pristupu i komercijalnim uslovima.",
        "operationId": "getPricingDetailsMarkdown",
        "responses": {
          "200": {
            "description": "Markdown cjenovnik",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/index.md": {
      "get": {
        "summary": "Markdown verzija naslovne stranice i pregled tema",
        "description": "Čisti Markdown ekvivalent naslovnice sa popisom svih kategorija.",
        "operationId": "getMarkdownHomepage",
        "responses": {
          "200": {
            "description": "Markdown sadržaj",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Opcionalni Bearer token za autentifikaciju AI agenata ili samoposlužnog sandbox testiranja (npr. 'Bearer sandbox_free_token'). Javni GET endpointi su u potpunosti otvoreni bez obaveznog tokena."
      },
      "OAuth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 autorizacija za korisnike i agente putem Appwrite Auth protokola.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api.kakounjemackoj.de/v1/account/sessions/oauth2/google",
            "tokenUrl": "https://api.kakounjemackoj.de/v1/account/jwt",
            "scopes": {
              "read:guides": "Pristup javnim vodičima i bazama znanja",
              "search:content": "Pretraga indeksa članaka i tema",
              "read:categories": "Pregled rubrika i kategorija",
              "write:bookmarks": "Spremanje omiljenih članaka na profilu"
            }
          }
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Opcionalni jedinstveni ključ idempotencije (UUID v4) koji sprječava višestruko procesiranje istog zahtjeva.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "headers": {
      "RateLimitLimit": {
        "description": "Maksimalni dozvoljeni broj zahtjeva po minuti za klijenta",
        "schema": {
          "type": "integer",
          "example": 100
        }
      },
      "RateLimitRemaining": {
        "description": "Preostali broj zahtjeva unutar trenutnog prozora",
        "schema": {
          "type": "integer",
          "example": 99
        }
      },
      "RateLimitReset": {
        "description": "Broj sekundi do obnove limita",
        "schema": {
          "type": "integer",
          "example": 60
        }
      }
    },
    "schemas": {
      "PostItem": {
        "type": "object",
        "required": ["title", "slug", "category", "categorySlug", "excerpt", "readingTime"],
        "properties": {
          "title": { "type": "string", "example": "Prijava adrese u Njemačkoj (Anmeldung)" },
          "slug": { "type": "string", "example": "prijava-boravka-u-njemackoj" },
          "category": { "type": "string", "example": "Prvi koraci i registracija" },
          "categorySlug": { "type": "string", "example": "prvi-koraci" },
          "excerpt": { "type": "string", "example": "Vodič za prijavu adrese u Bürgeramtu u roku od 14 dana." },
          "readingTime": { "type": "string", "example": "3 min čitanja" },
          "publishedAt": { "type": "string", "format": "date", "example": "2026-10-01" },
          "tags": {
            "type": "array",
            "items": { "type": "string" },
            "example": ["anmeldung", "birokratija", "burgeramt"]
          }
        }
      },
      "CategoryItem": {
        "type": "object",
        "required": ["name", "slug", "description"],
        "properties": {
          "name": { "type": "string", "example": "Stanovanje i najam" },
          "slug": { "type": "string", "example": "stanovanje-i-najam" },
          "description": { "type": "string", "example": "Pronalaženje stana, ugovor o najmu, kaucija i SCHUFA." },
          "parentSlug": { "type": "string", "nullable": true, "example": "zivot" }
        }
      },
      "PaginatedPostsResponse": {
        "type": "object",
        "required": ["page", "totalPages", "total", "hasMore", "posts"],
        "properties": {
          "page": { "type": "integer", "example": 1 },
          "totalPages": { "type": "integer", "example": 23 },
          "total": { "type": "integer", "example": 184 },
          "hasMore": { "type": "boolean", "example": true },
          "posts": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PostItem" }
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "required": ["posts", "categories"],
        "properties": {
          "posts": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PostItem" }
          },
          "categories": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CategoryItem" }
          }
        }
      },
      "CategoriesResponse": {
        "type": "object",
        "required": ["categories"],
        "properties": {
          "categories": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CategoryItem" }
          }
        }
      },
      "PricingTier": {
        "type": "object",
        "required": ["name", "priceEur", "priceBam", "features"],
        "properties": {
          "name": { "type": "string", "example": "AI Agenti & Pretraživači" },
          "priceEur": { "type": "number", "example": 0.0 },
          "priceBam": { "type": "number", "example": 0.0 },
          "billingPeriod": { "type": "string", "example": "free_forever" },
          "features": {
            "type": "array",
            "items": { "type": "string" },
            "example": [
              "Puni pristup REST API v1",
              "MCP Server podrška",
              "LLM index (llms.txt)",
              "Neograničeno čitanje bez API ključa"
            ]
          }
        }
      },
      "PricingResponse": {
        "type": "object",
        "required": ["currency", "tiers", "sandbox"],
        "properties": {
          "currency": { "type": "string", "example": "EUR" },
          "tiers": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PricingTier" }
          },
          "sandbox": {
            "type": "object",
            "properties": {
              "available": { "type": "boolean", "example": true },
              "token": { "type": "string", "example": "sandbox_free_token" },
              "endpoint": { "type": "string", "example": "https://kakounjemackoj.de/api/v1/" }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["error", "code", "message"],
        "properties": {
          "error": { "type": "string", "example": "Not Found" },
          "code": { "type": "integer", "example": 404 },
          "message": { "type": "string", "example": "Traženi resurs ili endpoint nije pronađen." },
          "documentationUrl": { "type": "string", "example": "https://kakounjemackoj.de/developers" }
        }
      }
    },
    "responses": {
      "BadRequestError": {
        "description": "Neispravan zahtjev ili nevažeći parametri",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      },
      "NotFoundError": {
        "description": "Traženi resurs nije pronađen",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      },
      "InternalServerError": {
        "description": "Interna serverska greška",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" }
          }
        }
      }
    }
  }
}