{
    "openapi": "3.0.0",
    "info": {
        "title": "Twins on Ice (twinsonice.link) API",
        "description": "Official REST API documentation for twinsonice.link link hub & short link services.",
        "version": "1.0.0",
        "api_version": "v1",
        "git_commit": "d07c1a5",
        "docs_url": "https://twinsonice.link/docs/api"
    },
    "servers": [
        {
            "url": "https://twinsonice.link",
            "description": "Production Server"
        }
    ],
    "endpoints": {
        "/api/v1/ping": {
            "method": "GET",
            "summary": "API Liveness Ping",
            "description": "Leichtgewichtiger Liveness-Check. Gibt \"pong\" und den aktuellen Server-Zeitstempel zurück. Aliase: /api/ping, /ping.",
            "example_code": "GET https://twinsonice.link/api/v1/ping",
            "test_url": "https://twinsonice.link/api/v1/ping",
            "return_example": "{\n  \"status\": \"success\",\n  \"message\": \"pong\",\n  \"timestamp\": 1792336899,\n  \"datetime\": \"2026-10-18T17:21:39+02:00\"\n}"
        },
        "/api/v1/latest": {
            "method": "GET",
            "summary": "Application & Version Metadata",
            "description": "Gibt Systemversion, Git Commit Hash ID, Server-Uhrzeit & Umgebungsdaten im JSON-Format zurück. Aliase: /api/v/latest, /api/latest.",
            "example_code": "GET https://twinsonice.link/api/v1/latest",
            "test_url": "https://twinsonice.link/api/v1/latest",
            "return_example": "{\n  \"status\": \"success\",\n  \"app\": \"twinsonice.link\",\n  \"name\": \"Twins on Ice\",\n  \"version\": \"1.0.0\",\n  \"commit\": \"d07c1a5\",\n  \"commit_id\": \"d07c1a5\",\n  \"environment\": \"production\",\n  \"php_version\": \"8.3.6\",\n  \"api_version\": \"v1\",\n  \"timestamp\": 1792336899\n}"
        },
        "/api/v1/commit": {
            "method": "GET",
            "summary": "Git Commit Hash ID",
            "description": "Gibt die exakte 7-stellige Git Commit Hash ID des aktuellen Deployments zurück. Aliase: /api/commit, /api/git, /commit.",
            "example_code": "GET https://twinsonice.link/api/v1/commit",
            "test_url": "https://twinsonice.link/api/v1/commit",
            "return_example": "{\n  \"status\": \"success\",\n  \"commit\": \"d07c1a5\",\n  \"commit_id\": \"d07c1a5\",\n  \"git_commit\": \"d07c1a5\",\n  \"api_version\": \"v1\"\n}"
        },
        "/api/v1/links": {
            "method": "GET",
            "summary": "Short Link Registry Catalog",
            "description": "Liefert alle registrierten Short Links, Ziel-URLs, Kurz-URLs, Kategorien und Tracking-Links. Aliase: /api/links, /links.",
            "example_code": "GET https://twinsonice.link/api/v1/links",
            "test_url": "https://twinsonice.link/api/v1/links",
            "return_example": "{\n  \"status\": \"success\",\n  \"count\": 15,\n  \"links\": {\n    \"website\": {\n      \"slug\": \"website\",\n      \"title\": \"Offizielle Website\",\n      \"target_url\": \"https://www.twinsonice.de\",\n      \"short_url\": \"https://icelnk.de/website\",\n      \"category\": \"Info\"\n    }\n  }\n}"
        },
        "/api/v1/stories": {
            "method": "GET",
            "summary": "Instagram Live Stories",
            "description": "Liefert die neuesten Instagram Stories aus dem StoryGrab Cache. Aliase: /api/stories, /stories.",
            "query_params": {
                "limit": "integer (optional, default: 10)"
            },
            "example_code": "GET https://twinsonice.link/api/v1/stories?limit=10",
            "test_url": "https://twinsonice.link/api/v1/stories?limit=10",
            "return_example": "{\n  \"status\": \"success\",\n  \"count\": 2,\n  \"stories\": [\n    {\n      \"id\": \"18023849201\",\n      \"type\": \"image\",\n      \"image_url\": \"https://media.storygrab.net/stories/example.jpg\",\n      \"date_label\": \"Heute\"\n    }\n  ]\n}"
        },
        "/api/v1/songs": {
            "method": "GET",
            "summary": "Songs & Discography Catalog",
            "description": "Liefert Musik- & Discografie-Daten inklusive Cover-Artwork und Streaming-Plattform-Links. Aliase: /api/songs, /songs.",
            "example_code": "GET https://twinsonice.link/api/v1/songs",
            "test_url": "https://twinsonice.link/api/v1/songs",
            "return_example": "{\n  \"status\": \"success\",\n  \"count\": 1,\n  \"songs\": [\n    {\n      \"id\": \"check-das\",\n      \"title\": \"CHECK DAS\",\n      \"artist\": \"Twins on Ice\",\n      \"smart_link\": \"https://twinsonice.link/check-das\"\n    }\n  ]\n}"
        },
        "/api/v1/health": {
            "method": "GET",
            "summary": "System Health Metrics",
            "description": "System Health-Check Status für Datenbank-Verbindung, Story Cache Dateistatus & Uptime. Aliase: /api/health, /health.",
            "example_code": "GET https://twinsonice.link/api/v1/health",
            "test_url": "https://twinsonice.link/api/v1/health",
            "return_example": "{\n  \"status\": \"ok\",\n  \"system\": \"operational\",\n  \"database\": \"connected\",\n  \"cache\": {\n    \"exists\": true,\n    \"size_bytes\": 39631\n  }\n}"
        },
        "/api/v1/qr/{slug}": {
            "method": "GET",
            "summary": "QR Code Metadata Generator",
            "description": "Erstellt QR-Code Metadaten und Direct-Image URLs für einen spezifischen Short-Link Slug. Aliase: /api/qr/{slug}, /qr/{slug}.",
            "path_params": {
                "slug": "string (required, e.g. check-das, instagram, ninetysix)"
            },
            "example_code": "GET https://twinsonice.link/api/v1/qr/check-das",
            "test_url": "https://twinsonice.link/api/v1/qr/check-das",
            "return_example": "{\n  \"status\": \"success\",\n  \"slug\": \"check-das\",\n  \"target_url\": \"https://icelnk.de/check-das\",\n  \"qr_image_url\": \"https://twinsonice.link/qr/check-das\"\n}"
        },
        "/api/v1/shorten": {
            "method": "POST",
            "summary": "Create Short Link",
            "description": "Generiert eine verkürzte URL für eine übergebene Ziel-URL mit optionalen Header-Optionen (noindex, nocache, custom headers). Wenn für dieselbe Ziel-URL abweichende Header-Optionen angefordert werden, wird automatisch ein neuer Short-Link erstellt. Aliase: /api/shorten, /shorten.",
            "request_body": {
                "url": "string (required, valid HTTP/HTTPS URL)",
                "label": "string (optional title/label)",
                "custom_slug": "string (optional custom slug/short code, requires API key)",
                "noindex": "boolean (optional, emits X-Robots-Tag: noindex, nofollow on redirect)",
                "noarchive": "boolean (optional, emits X-Robots-Tag: noarchive on redirect)",
                "nosnippet": "boolean (optional, emits X-Robots-Tag: nosnippet on redirect)",
                "nocache": "boolean (optional, emits Cache-Control no-cache headers on redirect)",
                "redirect_code": "integer (optional, HTTP redirect status code 301, 302, 307, 308)",
                "headers": "object (optional key-value map of custom response headers to emit on redirect)"
            },
            "example_code": "POST https://twinsonice.link/api/v1/shorten\nContent-Type: application/json\n\n{\n  \"url\": \"https://example.com/target-page\",\n  \"label\": \"Custom Link Title\",\n  \"noindex\": true,\n  \"nocache\": true\n}",
            "test_url": null,
            "return_example": "{\n  \"status\": \"success\",\n  \"target_url\": \"https://example.com/target-page\",\n  \"short_url\": \"https://icelnk.de/c/a1b2c3\",\n  \"short_code\": \"a1b2c3\",\n  \"options\": {\n    \"noindex\": true,\n    \"nocache\": true,\n    \"headers\": {\n      \"X-Robots-Tag\": \"noindex, nofollow\"\n    }\n  }\n}"
        },
        "/api/v1/reveal-email": {
            "method": "POST",
            "summary": "Turnstile Protected Email Reveal",
            "description": "Schaltet Kontakt-E-Mail-Adressen frei nach erfolgreicher Cloudflare Turnstile Sicherheitsüberprüfung. Aliase: /api/reveal-email.",
            "request_body": {
                "cf-turnstile-response": "string (required, Cloudflare Turnstile response token)",
                "type": "string (optional: \"contact\" or \"dnbx\", default: \"contact\")"
            },
            "example_code": "POST https://twinsonice.link/api/v1/reveal-email\nContent-Type: application/json\n\n{\n  \"cf-turnstile-response\": \"TOKEN\",\n  \"type\": \"contact\"\n}",
            "test_url": null,
            "return_example": "{\n  \"status\": \"success\",\n  \"email\": \"hello@twinsonice.de\",\n  \"mailto\": \"mailto:hello@twinsonice.de\"\n}"
        },
        "/api/v1/docs": {
            "method": "GET",
            "summary": "API Documentation Specification",
            "description": "Gibt die vollständige API-Spezifikation im strukturierten OpenAPI / JSON-Format zurück. Aliase: /api/docs, /docs.",
            "example_code": "GET https://twinsonice.link/api/v1/docs",
            "test_url": "https://twinsonice.link/api/v1/docs",
            "return_example": "{\n  \"openapi\": \"3.0.0\",\n  \"info\": {\n    \"title\": \"Twins on Ice API\",\n    \"version\": \"1.0.0\"\n  },\n  \"endpoints\": { ... }\n}"
        }
    }
}