{"openapi":"3.0.0","info":{"title":"Kite News API","version":"1.0.0","description":"API for accessing news aggregation data from Kite, including batches, categories, stories, and media information.","x-logo":{"url":"/svg/kagi_news_compact.svg","altText":"Kite Logo","backgroundColor":"#FFFFFF"}},"servers":[{"url":"https://kite.kagi.com","description":"Production server"},{"url":"http://localhost:5173","description":"Local development server"}],"tags":[{"name":"Batches","description":"Operations related to news batch management"},{"name":"Categories","description":"News category operations"},{"name":"Stories","description":"Individual news story/cluster operations"},{"name":"OnThisDay","description":"Historical events that occurred on this day"},{"name":"Media","description":"Media source information and metadata"},{"name":"Localization","description":"UI localization and translation strings"},{"name":"Chaos Index","description":"World tension index based on global news analysis"}],"x-tagGroups":[{"name":"Core API","tags":["Batches","Categories","Stories"]},{"name":"Special Features","tags":["OnThisDay","Media","Localization","Chaos Index"]}],"components":{"schemas":{"Story":{"type":"object","required":["cluster_number","title","short_summary","articles"],"properties":{"id":{"type":"string","description":"Unique identifier for the story cluster"},"cluster_number":{"type":"integer","description":"Sequential number of this cluster in the category"},"title":{"type":"string","description":"Main headline of the story cluster"},"short_summary":{"type":"string","description":"Brief summary of the story (2-3 sentences)"},"category":{"type":"string","description":"Category or subcategory name for the story"},"did_you_know":{"type":"string","description":"Interesting fact related to the story"},"talking_points":{"type":"array","items":{"type":"string"},"description":"Key discussion points about the story","default":[]},"quote":{"type":"string","description":"Relevant quote from the story"},"quote_author":{"type":"string","description":"Person who said the quote"},"quote_attribution":{"type":"string","description":"Publication that reported the quote"},"quote_source_url":{"type":"string","format":"uri","description":"URL to the source of the quote"},"quote_source_domain":{"type":"string","description":"Domain of the quote source"},"location":{"type":"string","description":"Geographic location relevant to the story"},"emoji":{"type":"string","description":"Emoji representing the story theme"},"unique_domains":{"type":"integer","description":"Number of unique news sources"},"number_of_titles":{"type":"integer","description":"Total number of article titles"},"sourceLanguage":{"type":"string","description":"Language code of the story's source content (e.g., 'en', 'fr', 'de'). Present when lang=default to indicate each story's original language."},"perspectives":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","description":"Name or type of perspective source"},"text":{"type":"string","description":"The perspective content"},"political_leaning":{"type":"string","description":"Political orientation of the source"}}},"description":"Different viewpoints on the story"},"geopolitical_context":{"type":"string","description":"Political and geographical context"},"historical_background":{"type":"string","description":"Historical context and precedents"},"international_reactions":{"type":"array","items":{"type":"string"},"description":"Reactions from different countries/organizations"},"humanitarian_impact":{"type":"string","description":"Impact on people and communities"},"economic_implications":{"type":"string","description":"Economic effects and implications"},"timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","description":"Date or time period"},"content":{"type":"string","description":"What happened"}}},"description":"Chronological sequence of events"},"future_outlook":{"type":"string","description":"Predictions and future implications"},"key_players":{"type":"array","items":{"type":"string"},"description":"Important people or organizations involved"},"technical_details":{"type":"array","items":{"type":"string"},"description":"Technical information and specifications"},"business_angle":{"type":"array","items":{"type":"string"},"description":"Business perspective bullet points (backward-compat alias for business_angle_points)","deprecated":true},"business_angle_text":{"type":"string","description":"Business perspective narrative"},"business_angle_points":{"type":"array","items":{"type":"string"},"description":"Business perspective bullet points"},"user_action_items":{"type":"array","items":{"type":"string"},"description":"Actions users can take"},"scientific_significance":{"type":"array","items":{"type":"string"},"description":"Scientific importance and breakthroughs"},"travel_advisory":{"type":"array","items":{"type":"string"},"description":"Travel warnings and advice"},"destination_highlights":{"type":"string","description":"Key attractions and features of destinations"},"culinary_significance":{"type":"string","description":"Food and cuisine related information"},"performance_statistics":{"type":"array","items":{"type":"string"},"description":"Sports or performance statistics"},"league_standings":{"type":"string","description":"Current sports league positions"},"diy_tips":{"type":"string","description":"Do-it-yourself tips and instructions"},"design_principles":{"type":"string","description":"Design concepts and principles"},"user_experience_impact":{"type":"array","items":{"type":"string"},"description":"Impact on user experience"},"gameplay_mechanics":{"type":"array","items":{"type":"string"},"description":"Gaming mechanics and features"},"industry_impact":{"type":"array","items":{"type":"string"},"description":"Impact on relevant industries"},"technical_specifications":{"type":"array","items":{"type":"string"},"description":"Detailed technical specs"},"suggested_qna":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}}},"description":"Q&A pairs about the story"},"primary_image":{"type":"object","description":"Primary image for the story","properties":{"url":{"type":"string","format":"uri","description":"URL to the primary image"},"caption":{"type":"string","description":"Image caption or alt text"},"credit":{"type":"string","description":"Image attribution or credit"}}},"secondary_image":{"type":"object","description":"Secondary image for the story","properties":{"url":{"type":"string","format":"uri","description":"URL to the secondary image"},"caption":{"type":"string","description":"Image caption or alt text"},"credit":{"type":"string","description":"Image attribution or credit"}}},"articles":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Article headline"},"link":{"type":"string","format":"uri","description":"Full URL to the article"},"domain":{"type":"string","description":"Source domain name"},"date":{"type":"string","format":"date-time","description":"Publication date"},"author":{"type":"string","nullable":true,"description":"Journalist or article author when available"},"image":{"type":"string","format":"uri","description":"Article image URL"},"image_caption":{"type":"string","description":"Article image caption"}}},"description":"Individual articles in this story cluster"},"domains":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Domain name"},"favicon":{"type":"string","format":"uri","description":"URL to domain favicon"}}},"description":"News sources for this story"}},"example":{"id":"c370ef00-bab1-4990-a54a-15d20fb8d353","cluster_number":1,"title":"State trooper fatally shoots Putney resident after standoff","short_summary":"A Vermont State Police trooper shot and killed Scott Garvey, 55, at the Putney Landing apartment complex on Monday afternoon after officers believed he was armed during a day-long standoff. A subsequent search of the apartment found no firearms, and Trooper Peter Romeo, in service since 2023, has been placed on paid leave while an independent investigation proceeds. The case raises fresh scrutiny of police decision-making in mental-health crises.","category":"Policing","did_you_know":"The Westminster State Police Barracks embeds a full-time mental-health clinician who often handles crisis calls alongside troopers.","emoji":"🚔","unique_domains":4,"number_of_titles":6,"sourceLanguage":"en","location":"Putney, VT, USA","talking_points":["Initial concern: The first 911 call about Garvey's mental health came at 11:20 p.m. on Sunday, July 6.","Escalating threats: Neighbors reported Garvey making violent statements on Monday morning, prompting a larger police response.","Warrants obtained: Troopers secured both arrest and search warrants before entering the apartment around 4:30 p.m. Monday.","Autopsy findings: The medical examiner ruled Garvey's death a homicide caused by gunshot wounds to the torso and left leg.","Next steps: Findings will be reviewed by the Vermont Attorney General and county State's Attorney for use-of-force legality."],"quote":"\"We're not always going to see eye to eye, but I know we all have the state's interests at heart.\"","quote_author":"Charity Clark, Vermont Attorney General","quote_attribution":"LWN.net","quote_source_url":"https://lwn.net/Articles/1034158/","quote_source_domain":"lwn.net","perspectives":[{"text":"Vermont State Police: Trooper opened fire after seeing an object he believed was a gun and receiving no compliance.","sources":[{"name":"Vermont Daily Chronicle","url":"https://vermontdailychronicle.com/trooper-shot-man-he-thought-was-armed-no-gun-found/"}]},{"text":"VTDigger reporting: Later search revealed no firearm, prompting questions about threat assessment and training.","sources":[{"name":"VTDigger","url":"https://vtdigger.org/2025/07/08/vermont-state-police-trooper-shoots-and-kills-man-in-putney-reportedly-amid-threats/"}]},{"text":"Community advocates: Emphasize need for expanded non-police mental-health interventions to reduce lethal encounters.","sources":[{"name":"Brattleboro Reformer","url":"https://www.reformer.com/local-news/vermont-state-police-investigate-trooper-involved-shooting-at-putney-landing/article_6c84f561-39b4-4899-9dbb-e4bed4d73290.html"}]}],"geopolitical_context":"In recent years, the US has actively promoted supply chain diversification and localization, and after high-level US-China meetings, it has more closely reviewed economic and trade cooperation with Indo-Pacific partners.","historical_background":"The National Electric Vehicle Infrastructure program was created under the 2021 Infrastructure Investment and Jobs Act to help states build fast-charging corridors. President Trump paused new outlays in February 2025, prompting a multistate lawsuit in May that Vermont joined despite internal reservations.","humanitarian_impact":"The 2023–24 floods damaged homes, businesses, and public utilities across dozens of Vermont communities, leaving hundreds temporarily displaced and placing urgent needs on bridge, road and wastewater system repairs.","international_reactions":["🇦🇺 Australia: Treasury is \"urgently seeking\" details on the proposed 200% pharmaceutical tariff.","🇯🇵 Japan: Trade negotiators signalled willingness to discuss market access to avert the 25% levy.","🌐 WTO: Officials expressed concern that sweeping unilateral tariffs risk breaching multilateral trade rules."],"timeline":["July 6, 2025:: First mental-health call placed to police","July 7, 2025, morning:: Neighbors report threats; troopers respond","July 7, 2025, 4:30 p.m.:: Trooper Romeo shoots Scott Garvey","July 8, 2025:: Autopsy confirms cause of death; trooper's name released"],"technical_details":["Irreparable harm standard: Courts require proof that a funding delay causes concrete, non-compensable damage such as stalled contracts or lost construction season.","NEVI match requirement: States must supply 20% of project costs, influencing whether they deem immediate access to federal dollars essential."],"business_angle":["Trade corridors: The exclusive US development rights over a South Caucasus transit corridor could improve supply-chain reliability for energy and goods."],"business_angle_text":"For a long-term investor, the immediate headline risk masks two durable themes. First, U.S. copper producers and miners with North American assets could see windfall pricing power, but only if tariffs hold.","business_angle_points":["Trade corridors: The exclusive US development rights over a South Caucasus transit corridor could improve supply-chain reliability for energy and goods."],"user_action_items":["Comment period: Vermonters can submit feedback on updated statewide EV-charging plan via the Agency of Transportation website before July 31.","Legislative outreach: Residents may contact their state senators to support bridging funds for chargers in the 2026 capital bill."],"scientific_significance":["Genome reconstruction: Sequencing ancient DNA could refine techniques for conserving present-day endangered birds, though contamination and gaps remain significant challenges.","Surrogate species: Any living \"moa\" would require editing the genome of a distant relative such as the tinamou, raising scientific and ethical questions about species identity."],"travel_advisory":["Safety: Flight schedules may change rapidly | Confirm status with airlines before heading to airport","Health: Air quality degraded near fire zone | Wear an N95 mask if outdoors"],"performance_statistics":["Barrett leadership: Captained NZ to seven wins from eight tests since 2024.","Savea form: Averaging 17 carries and 11 tackles per test in 2025 season."],"league_standings":"Carlton sit 11th on the ladder with a 7-8 record, two wins adrift of eighth-placed Geelong as Round 17 approaches.","user_experience_impact":["Smoother Wayland capture eliminates occasional stutter seen in earlier versions.","One-click multitrack toggle streamlines complex recording setups for podcasters and educators."],"gameplay_mechanics":["Chronological toggle: New main-menu option restructures all 45 chapters in timeline order.","New unlocks: Completing the run grants additional character skins and guitar tracks."],"industry_impact":["Charger installers: Vermont contractors may see fewer 2025 projects, delaying job growth.","Utilities: Green Mountain Power's grid-upgrade timeline could slip without coordinated charger deployment funds."],"suggested_qna":[{"question":"Why did troopers initially refrain from visiting Garvey's apartment on Sunday night?","answer":"An embedded mental-health clinician handled the concern by phone, and no immediate threat was reported at that time."},{"question":"What standard procedure follows a trooper-involved shooting in Vermont?","answer":"The trooper is placed on paid relief-from-duty and the case is reviewed by the Attorney General and county State's Attorney."}],"primary_image":{"url":"https://kagiproxy.com/img/aockbnsDVHK4AkT58Fp96odcNVuTOYxzOYyqBKxVM4ehWzCzXGOVqmIgaVX9Yx2yM5ESRNg7p0YEMfItcDI5AOhxccPaXHwOD_EXwAIhXmq2uAkWtqJj9_3kG5PdYyh2f7GSfA7mDwCnpLTV6BdV7g","caption":"Police response at Putney Landing apartment complex","credit":"Vermont Daily Chronicle"},"secondary_image":{"url":"https://kagiproxy.com/img/NyApXwE39MvgMo45dCiuvSRcm9Ey4Pa4QcxmJs72aVU-bEmsvq27wHVdAUf95ks1rFegxL87Fjq12gerBmcUWarEEdn08AfOCjoOroh1EJeZqqFPc2X5PASFGS5AWXEmAaQ09FUflhlDvsJ_9XWFPCRXSg","caption":"The debt ratio eased year on year to 103.4% of GDP even as the nominal stock hit a record.","credit":"Expansión"},"articles":[{"title":"Vermont State Police trooper shoots and kills man in Putney","link":"https://vtdigger.org/2025/07/08/vermont-state-police-trooper-shoots-and-kills-man-in-putney-reportedly-amid-threats/","domain":"vtdigger.org","date":"2025-07-08T14:30:00Z","author":"Jane Reporter","image":"https://kagiproxy.com/img/example-image-url","image_caption":"Vermont State Police cruiser"},{"title":"Trooper shot man he thought was armed; no gun found","link":"https://vermontdailychronicle.com/trooper-shot-man-he-thought-was-armed-no-gun-found/","domain":"vermontdailychronicle.com","date":"2025-07-08T16:45:00Z"},{"title":"Vermont State Police investigate trooper-involved shooting at Putney Landing","link":"https://www.reformer.com/local-news/vermont-state-police-investigate-trooper-involved-shooting-at-putney-landing/article_6c84f561-39b4-4899-9dbb-e4bed4d73290.html","domain":"reformer.com","date":"2025-07-08T12:00:00Z"}],"domains":[{"name":"vtdigger.org"},{"name":"vermontdailychronicle.com"},{"name":"reformer.com"}]}}}},"paths":{"/api/batches/{batchId}":{"get":{"summary":"Get batch details","description":"Returns details for a specific batch","tags":["Batches"],"parameters":[{"in":"path","name":"batchId","required":true,"schema":{"type":"string"},"description":"Batch identifier. Accepts either:\n- UUID format (e.g., \"123e4567-e89b-12d3-a456-426614174000\")\n- Date slug format (e.g., \"2025-01-15.1\" for the 1st batch of that day)\n"}],"responses":{"200":{"description":"Batch details","content":{"application/json":{"schema":{"type":"object","required":["id","createdAt","totalCategories","totalClusters","totalArticles"],"properties":{"id":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"totalCategories":{"type":"integer"},"totalClusters":{"type":"integer"},"totalArticles":{"type":"integer"},"processingTime":{"type":"integer","description":"Processing time in seconds (may be omitted if null)"}}}}}},"404":{"description":"Batch not found"},"500":{"description":"Server error"}}}},"/api/batches/{batchId}/categories/{categoryId}/stories":{"get":{"summary":"Get stories for a category","description":"Returns news stories (clusters) for a specific category in a batch.\n\n**Important:** Fields with no data are omitted from the response.\nArray fields always return empty arrays `[]` when no data is available.\n","tags":["Stories"],"parameters":[{"in":"path","name":"batchId","required":true,"schema":{"type":"string"},"description":"Batch identifier. Accepts either:\n- UUID format (e.g., \"123e4567-e89b-12d3-a456-426614174000\")\n- Date slug format (e.g., \"2025-01-15.1\" for the 1st batch of that day)\n"},{"in":"path","name":"categoryId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Category UUID identifier (obtain from /api/batches/{batchId}/categories)"},{"in":"query","name":"limit","schema":{"type":"integer","default":50,"minimum":1,"maximum":100},"description":"Number of stories to return"},{"in":"query","name":"offset","schema":{"type":"integer","default":0,"minimum":0},"description":"Pagination offset"},{"in":"query","name":"lang","schema":{"type":"string","default":"default","enum":["default","source","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"]},"description":"Language code for story content. Supports both single language and comma-separated list.\n\n**Single language mode:**\n- 'default': Content in the category's source language\n- 'source': Always show original language\n- Specific language (e.g., 'en', 'fr'): Translated content\n\n**Multi-language mode (comma-separated):**\n- Example: 'en,es,fr'\n- If story's source language matches any in the list, returns source language\n- Otherwise, translates to the first language in the list\n"}],"responses":{"200":{"description":"Stories in the category","content":{"application/json":{"schema":{"type":"object","properties":{"batchId":{"type":"string","format":"uuid"},"categoryId":{"type":"string","format":"uuid"},"categoryName":{"type":"string"},"timestamp":{"type":"integer","description":"Unix timestamp"},"stories":{"type":"array","items":{"$ref":"#/components/schemas/Story"},"description":"Array of story clusters in this category"},"totalStories":{"type":"integer","description":"Total number of stories in this category"},"domains":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"favicon":{"type":"string"}}}},"readCount":{"type":"integer","description":"Number of times this category has been read"}}},"example":{"batchId":"a5271a19-6f23-453f-a6df-6a2e3ea7ebfe","categoryId":"fc51072b-3a2c-4444-a607-ec5fe3b1f1c1","categoryName":"World","timestamp":1753531507,"totalStories":12,"readCount":28,"stories":[{"$ref":"#/components/schemas/Story"}],"domains":[{"name":"vtdigger.org"},{"name":"vermontdailychronicle.com"},{"name":"reformer.com"}]}}}},"404":{"description":"Batch or category not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Batch not found"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Failed to fetch stories"}}}}}}},"/api/batches/{batchId}/categories":{"get":{"summary":"Get categories for a batch","description":"Returns all news categories available in the specified batch","tags":["Categories"],"parameters":[{"in":"path","name":"batchId","required":true,"schema":{"type":"string"},"description":"Batch identifier. Accepts either:\n- UUID format (e.g., \"123e4567-e89b-12d3-a456-426614174000\")\n- Date slug format (e.g., \"2025-01-15.1\" for the 1st batch of that day)\n"},{"in":"query","name":"lang","schema":{"type":"string","default":"default","enum":["default","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"]},"description":"Language code for category names.\nUse 'default' to get categories with names in their source languages.\n"}],"responses":{"200":{"description":"List of categories in the batch","content":{"application/json":{"schema":{"type":"object","properties":{"batchId":{"type":"string","format":"uuid","description":"Batch identifier"},"createdAt":{"type":"string","format":"date-time","description":"When the batch was created"},"hasOnThisDay":{"type":"boolean","description":"Whether this batch includes OnThisDay data (fetch with /api/batches/{batchId}/onthisday)"},"categories":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Category unique identifier"},"categoryId":{"type":"string","description":"Category type (e.g., \"world\", \"technology\")"},"categoryName":{"type":"string","description":"Human-readable category name"},"timestamp":{"type":"integer","description":"Unix timestamp"},"readCount":{"type":"integer","description":"Number of times this category has been read","default":0},"clusterCount":{"type":"integer","description":"Number of news clusters in this category"}}}}}}}}},"404":{"description":"Batch not found"},"500":{"description":"Server error"}}}},"/api/batches/{batchId}/chaos":{"get":{"summary":"Get chaos index for a specific batch","description":"Returns the chaos index data for the specified batch if it included World news processing.\nThe chaos index is a 0-100 scale indicating global instability based on World news analysis.\n\n**Chaos Index Scale:**\n- 0-20: The world is cool and stable (minimal chaos)\n- 21-40: The world is warming up with mild turbulence\n- 41-60: The world is hot with moderate chaos\n- 61-80: The world is very hot with high instability\n- 81-100: The world is on fire with severe chaos\n","tags":["Chaos Index"],"parameters":[{"in":"path","name":"batchId","required":true,"schema":{"type":"string"},"description":"Batch identifier. Accepts either:\n- UUID format (e.g., \"123e4567-e89b-12d3-a456-426614174000\")\n- Date slug format (e.g., \"2025-01-15.1\" for the 1st batch of that day)\n"},{"in":"query","name":"lang","schema":{"type":"string","default":"default","enum":["default","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"]},"description":"Language code for the chaos description.\nFalls back to English if translation is not available.\n"}],"responses":{"200":{"description":"Chaos index data","content":{"application/json":{"schema":{"type":"object","properties":{"chaosIndex":{"type":"integer","minimum":0,"maximum":100,"description":"The chaos index score"},"chaosDescription":{"type":"string","description":"Temperature-based description of global chaos level"},"chaosLastUpdated":{"type":"string","format":"date-time","description":"When the chaos index was calculated"}}}}}},"404":{"description":"Batch not found or chaos index not available"},"500":{"description":"Server error"}}}},"/api/batches/{batchId}/languages":{"get":{"summary":"Get available languages for a batch","description":"Returns all languages that have translations available for this batch","tags":["Batches"],"parameters":[{"in":"path","name":"batchId","required":true,"schema":{"type":"string"},"description":"Batch identifier. Accepts either:\n- UUID format (e.g., \"123e4567-e89b-12d3-a456-426614174000\")\n- Date slug format (e.g., \"2025-01-15.1\" for the 1st batch of that day)\n"}],"responses":{"200":{"description":"List of available languages","content":{"application/json":{"schema":{"type":"object","properties":{"batchId":{"type":"string","format":"uuid","description":"Batch identifier"},"languages":{"type":"array","items":{"type":"object","required":["languageCode","isComplete","totalCategories","totalClusters","totalArticles"],"properties":{"languageCode":{"type":"string","description":"ISO 639-1 language code","example":"en"},"isComplete":{"type":"boolean","description":"Whether all translations for this language are complete"},"totalCategories":{"type":"integer","description":"Number of categories available in this language"},"totalClusters":{"type":"integer","description":"Number of clusters available in this language"},"totalArticles":{"type":"integer","description":"Number of articles available in this language"}}}}}},"example":{"batchId":"123e4567-e89b-12d3-a456-426614174000","languages":[{"languageCode":"en","isComplete":true,"totalCategories":15,"totalClusters":150,"totalArticles":1200},{"languageCode":"es","isComplete":true,"totalCategories":15,"totalClusters":150,"totalArticles":1200},{"languageCode":"fr","isComplete":false,"totalCategories":10,"totalClusters":100,"totalArticles":800}]}}}},"404":{"description":"Batch not found"},"500":{"description":"Server error"}}}},"/api/batches/{batchId}/onthisday":{"get":{"summary":"Get OnThisDay events for a batch","description":"Returns historical events that occurred on this day for the specified batch. Only available if the batch includes OnThisDay data.","tags":["OnThisDay"],"parameters":[{"in":"path","name":"batchId","required":true,"schema":{"type":"string"},"description":"Batch identifier. Accepts either:\n- UUID format (e.g., \"123e4567-e89b-12d3-a456-426614174000\")\n- Date slug format (e.g., \"2025-01-15.1\" for the 1st batch of that day)\n"},{"in":"query","name":"lang","schema":{"type":"string","default":"default"},"description":"Language preference for OnThisDay translations. Supports:\n- Single language code (e.g., 'it', 'fr', 'de')\n- Comma-separated preferences (e.g., 'it,en' - tries Italian first, falls back to English)\n- 'default' is equivalent to 'en'\n\nThe API will try each language in order and return the first available translation.\nIf none of the requested languages are available, it falls back to English.\n\nSupported languages: en, de, fr, es, it, pt, nl, sv, pl, tr, ru, zh, ja, hi, uk\n","example":"it,en"}],"responses":{"200":{"description":"OnThisDay events","content":{"application/json":{"schema":{"type":"object","required":["timestamp","language","events"],"properties":{"timestamp":{"type":"integer","description":"Unix timestamp when the data was generated"},"language":{"type":"string","description":"The actual language code that was used for this response (e.g., 'it', 'en'). Useful for fetching Wikipedia content in the matching language."},"events":{"type":"array","description":"List of historical events","items":{"type":"object","properties":{"year":{"type":"string","description":"Year the event occurred"},"content":{"type":"string","description":"Description of the event"},"sort_year":{"type":"integer","description":"Numeric year for sorting"},"type":{"type":"string","enum":["event","person","people"],"description":"Type of historical entry"},"image":{"type":"string","nullable":true,"description":"Optional image URL"}}}}}}}}},"404":{"description":"Batch not found or OnThisDay data not available"},"500":{"description":"Server error"}}}},"/api/batches":{"get":{"summary":"List available news batches","description":"Returns a list of news batches within the specified time range","tags":["Batches"],"parameters":[{"in":"query","name":"from","schema":{"type":"string","format":"date-time"},"description":"Start date (ISO 8601). Defaults to 24 hours ago.","example":"2025-07-04T12:00:00Z"},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"},"description":"End date (ISO 8601). Defaults to current time.","example":"2025-07-05T12:00:00Z"},{"in":"query","name":"lang","schema":{"type":"string","default":"default","enum":["default","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"]},"description":"Language code. Use 'zh' for Simplified Chinese (automatically maps to 'zh-Hans').\nUse 'zh-Hant' explicitly for Traditional Chinese.\n"}],"responses":{"200":{"description":"List of batches","content":{"application/json":{"schema":{"type":"object","properties":{"batches":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique batch identifier"},"createdAt":{"type":"string","format":"date-time","description":"When the batch was created"},"language":{"type":"string","description":"Language code"},"totalCategories":{"type":"integer","description":"Number of news categories in this batch"},"totalClusters":{"type":"integer","description":"Total number of news clusters across all categories"},"totalArticles":{"type":"integer","description":"Total number of articles across all clusters"}}}}}}}}},"400":{"description":"Invalid request parameters"},"500":{"description":"Server error"}}}},"/api/batches/latest":{"get":{"summary":"Get the latest news batch","description":"Returns the most recent batch for the specified language.\n\n**Language Options:**\n- `default`: Returns the latest batch with content in each category's source language\n  (e.g., German news in German, French news in French)\n- `en`, `de`, `fr`, etc.: Returns the batch with content in the specified language\n  (Note: Only returns batches where the language is available in batch_languages table)\n\n**Note:** When using `lang=default`, each category's content will be in its native language\nas configured in the feed sources. This is the recommended option for displaying\nauthentic regional news.\n\n**Chaos Index:** To get chaos index data, use the `/api/batches/latest/chaos` endpoint.\nThe chaos index is calculated separately and not included in the batch response.\n","tags":["Batches"],"parameters":[{"in":"query","name":"lang","schema":{"type":"string","default":"default","enum":["default","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"]},"description":"Language code for content retrieval.\nUse 'default' to get content in each category's source language.\n"}],"responses":{"200":{"description":"Latest batch details","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique batch identifier"},"createdAt":{"type":"string","format":"date-time","description":"When the batch was created"},"language":{"type":"string","description":"Language code"},"totalCategories":{"type":"integer","description":"Number of news categories in this batch"},"totalClusters":{"type":"integer","description":"Total number of news clusters across all categories"},"totalArticles":{"type":"integer","description":"Total number of articles across all clusters"},"totalReadCount":{"type":"integer","description":"Total number of raw RSS articles fetched across all categories"}}}}}},"404":{"description":"No batches found for the specified language"},"500":{"description":"Server error"}}}},"/api/batches/latest/categories/{categoryId}/stories":{"get":{"summary":"Get stories for a specific category in the latest batch","description":"Fetches all stories for the specified category from the most recent batch run.\n\n**Important:** Fields with no data are omitted from the response.\nArray fields always return empty arrays `[]` when no data is available.\n","tags":["Stories"],"parameters":[{"in":"path","name":"categoryId","required":true,"schema":{"type":"string"},"description":"The UUID of the category","example":"123e4567-e89b-12d3-a456-426614174000"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":12},"description":"Maximum number of stories to return"},{"in":"query","name":"lang","schema":{"type":"string","enum":["default","source","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"],"default":"default"},"description":"Language code for story content. Supports both single language and comma-separated list.\n\n**Single language mode:**\n- 'default': Content in the category's source language\n- 'source': Always show original language\n- Specific language (e.g., 'en', 'fr'): Translated content\n\n**Multi-language mode (comma-separated):**\n- Example: 'en,es,fr'\n- If story's source language matches any in the list, returns source language\n- Otherwise, translates to the first language in the list\n"}],"responses":{"200":{"description":"Stories for the category","content":{"application/json":{"schema":{"type":"object","properties":{"batchId":{"type":"string","description":"UUID of the batch"},"categoryId":{"type":"string","description":"UUID of the category"},"categoryName":{"type":"string","description":"Name of the category"},"stories":{"type":"array","items":{"$ref":"#/components/schemas/Story"}},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of the batch"},"totalStories":{"type":"integer","description":"Total number of stories in this category"},"domains":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"favicon":{"type":"string"}}}},"readCount":{"type":"integer","description":"Number of times this category has been read"}}},"example":{"batchId":"a5271a19-6f23-453f-a6df-6a2e3ea7ebfe","categoryId":"fc51072b-3a2c-4444-a607-ec5fe3b1f1c1","categoryName":"World","timestamp":1753531507,"totalStories":12,"readCount":28,"stories":[{"$ref":"#/components/schemas/Story"}],"domains":[{"name":"vtdigger.org"},{"name":"vermontdailychronicle.com"},{"name":"reformer.com"}]}}}},"404":{"description":"Category not found in latest batch"},"500":{"description":"Database error"}}}},"/api/batches/latest/categories":{"get":{"summary":"Get categories for the latest batch","description":"Returns all news categories available in the most recent batch.\nThis is a convenience endpoint that combines the functionality of\ngetting the latest batch and then fetching its categories, saving an API call.\n","tags":["Categories"],"parameters":[{"in":"query","name":"lang","schema":{"type":"string","default":"default","enum":["default","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"]},"description":"Language code for category names.\nUse 'default' to get categories with names in their source languages.\n"}],"responses":{"200":{"description":"List of categories in the latest batch","content":{"application/json":{"schema":{"type":"object","properties":{"batchId":{"type":"string","format":"uuid","description":"Batch identifier"},"createdAt":{"type":"string","format":"date-time","description":"When the batch was created"},"hasOnThisDay":{"type":"boolean","description":"Whether \"On This Day\" data is available for this batch"},"categories":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Category unique identifier"},"categoryId":{"type":"string","description":"Category type (e.g., \"world\", \"technology\")"},"categoryName":{"type":"string","description":"Human-readable category name"},"timestamp":{"type":"integer","description":"Unix timestamp"},"readCount":{"type":"integer","description":"Number of times this category has been read"},"clusterCount":{"type":"integer","description":"Number of news clusters in this category"}}}}}}}}},"404":{"description":"No batches found"},"500":{"description":"Server error"}}}},"/api/batches/latest/chaos":{"get":{"summary":"Get chaos index from latest batch","description":"Returns the chaos index data from the most recent batch that included World news processing.\nThe chaos index is a 0-100 scale indicating global instability based on World news analysis.\n\n**Chaos Index Scale:**\n- 0-20: The world is cool and stable (minimal chaos)\n- 21-40: The world is warming up with mild turbulence\n- 41-60: The world is hot with moderate chaos\n- 61-80: The world is very hot with high instability\n- 81-100: The world is on fire with severe chaos\n","tags":["Chaos Index"],"parameters":[{"in":"query","name":"lang","schema":{"type":"string","default":"default","enum":["default","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"]},"description":"Language code for the chaos description.\nFalls back to English if translation is not available.\n"}],"responses":{"200":{"description":"Chaos index data","content":{"application/json":{"schema":{"type":"object","required":["chaosIndex","chaosDescription","chaosLastUpdated"],"properties":{"chaosIndex":{"type":"integer","minimum":0,"maximum":100,"description":"The chaos index score"},"chaosDescription":{"type":"string","description":"Temperature-based description of global chaos level"},"chaosLastUpdated":{"type":"string","format":"date-time","description":"When the chaos index was calculated"}}}}}},"404":{"description":"No batches found or chaos index not available"},"500":{"description":"Server error"}}}},"/api/batches/latest/onthisday":{"get":{"summary":"Get OnThisDay events from latest batch","description":"Returns historical events that occurred on this day from the most recent batch. This is a convenience endpoint that automatically uses the latest batch.","tags":["OnThisDay"],"parameters":[{"in":"query","name":"lang","schema":{"type":"string","default":"default"},"description":"Language preference for OnThisDay translations. Supports:\n- Single language code (e.g., 'it', 'fr', 'de')\n- Comma-separated preferences (e.g., 'it,en' - tries Italian first, falls back to English)\n- 'default' is equivalent to 'en'\n\nThe API will try each language in order and return the first available translation.\nIf none of the requested languages are available, it falls back to English.\n\nSupported languages: en, de, fr, es, it, pt, nl, sv, pl, tr, ru, zh, ja, hi, uk\n","example":"it,en"}],"responses":{"200":{"description":"OnThisDay events from latest batch","content":{"application/json":{"schema":{"type":"object","required":["timestamp","language","events"],"properties":{"timestamp":{"type":"integer","description":"Unix timestamp when the data was generated"},"language":{"type":"string","description":"The actual language code that was used for this response (e.g., 'it', 'en'). Useful for fetching Wikipedia content in the matching language."},"events":{"type":"array","description":"List of historical events","items":{"type":"object","required":["year","content","sort_year","type"],"properties":{"year":{"type":"string","description":"Year the event occurred"},"content":{"type":"string","description":"Description of the event"},"sort_year":{"type":"integer","description":"Numeric year for sorting"},"type":{"type":"string","enum":["event","person","people"],"description":"Type of historical entry"},"image":{"type":"string","description":"Image URL (omitted when null)"}}}}}}}}},"404":{"description":"No batches found or OnThisDay data not available"},"500":{"description":"Server error"}}}},"/api/media/{host}":{"get":{"summary":"Get media source information for a specific host","description":"Returns detailed information about a specific media source by its domain/host. This is an optimized endpoint for fetching individual source metadata.","tags":["Media"],"parameters":[{"in":"path","name":"host","required":true,"schema":{"type":"string"},"description":"The domain/host to look up (e.g., \"nytimes.com\")","example":"nytimes.com"},{"in":"query","name":"lang","schema":{"type":"string","default":"default"},"description":"Language code for localized media information"}],"responses":{"200":{"description":"Media source information found","content":{"application/json":{"schema":{"type":"object","properties":{"mediaInfo":{"type":"object","description":"Media source information","properties":{"country":{"type":"string","description":"Country of origin for the media organization","example":"United States"},"organization":{"type":"string","description":"Name of the media organization","example":"The New York Times"},"domains":{"type":"array","items":{"type":"string"},"description":"List of domains associated with this media organization","example":["nytimes.com","nyti.ms"]},"description":{"type":"string","description":"Brief description of the media organization","example":"American daily newspaper based in New York City"},"owner":{"type":"string","description":"Ownership information","example":"The New York Times Company"},"typology":{"type":"string","description":"Media classification or type","example":"Quality newspaper"}}}}}}}},"400":{"description":"Bad request - missing host parameter","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"Host parameter is required"}}}}}},"404":{"description":"Media source not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"No media information found for host: example.com"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"Failed to load media data"}}}}}}}}},"/api/media":{"get":{"summary":"Get all media source information","description":"Returns information about all known media sources including their domains, ownership, and classification. Used for displaying source metadata in the UI.","tags":["Media"],"parameters":[{"in":"query","name":"lang","schema":{"type":"string","default":"default"},"description":"Language code for localized media information"}],"responses":{"200":{"description":"List of all media sources","content":{"application/json":{"schema":{"type":"object","properties":{"mediaData":{"type":"array","description":"Array of media source information","items":{"type":"object","properties":{"country":{"type":"string","description":"Country of origin for the media organization","example":"United States"},"organization":{"type":"string","description":"Name of the media organization","example":"The New York Times"},"domains":{"type":"array","items":{"type":"string"},"description":"List of domains associated with this media organization","example":["nytimes.com","nyti.ms"]},"description":{"type":"string","description":"Brief description of the media organization","example":"American daily newspaper based in New York City"},"owner":{"type":"string","description":"Ownership information","example":"The New York Times Company"},"typology":{"type":"string","description":"Media classification or type","example":"Quality newspaper"}}}}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"Failed to load media data"}}}}}}}}},"/api/locale/{lang}":{"get":{"summary":"Get localized strings","description":"Returns localized UI strings for the specified language. Falls back to English if the requested language is not available.","tags":["Localization"],"parameters":[{"in":"path","name":"lang","required":true,"schema":{"type":"string","enum":["en","es","fr","de","it","pt","ru","zh","ja","ko","ar","hi","nl","sv","pl","da","fi","no","cs","hu","tr","el","he","th","id","ms","vi","ro","uk","bg","hr","sk","sl","lt","lv","et","sr","ca","eu","gl","sw"]},"description":"Language code (ISO 639-1)","example":"en"}],"responses":{"200":{"description":"Localized strings for the requested language","content":{"application/json":{"schema":{"type":"object","properties":{"locale":{"type":"string","description":"The actual language code used (may differ from requested if fallback occurred)","example":"en"},"strings":{"type":"object","description":"Object containing all localized strings","properties":{"title":{"type":"string","example":"Kagi News - Elevated"},"description":{"type":"string","example":"Elevate your news reading experience"},"categories":{"type":"object","description":"Category names","properties":{"World":{"type":"string","example":"World"},"USA":{"type":"string","example":"USA"},"Business":{"type":"string","example":"Business"},"Technology":{"type":"string","example":"Technology"},"Science":{"type":"string","example":"Science"},"Sports":{"type":"string","example":"Sports"},"Entertainment":{"type":"string","example":"Entertainment"},"Health":{"type":"string","example":"Health"}}},"ui":{"type":"object","description":"UI element labels","properties":{"loading":{"type":"string","example":"Loading..."},"error":{"type":"string","example":"Error loading data"},"retry":{"type":"string","example":"Retry"},"showMore":{"type":"string","example":"Show more"},"showLess":{"type":"string","example":"Show less"},"sources":{"type":"string","example":"Sources"},"lastUpdated":{"type":"string","example":"Last updated"},"settings":{"type":"string","example":"Settings"},"language":{"type":"string","example":"Language"},"theme":{"type":"string","example":"Theme"},"darkMode":{"type":"string","example":"Dark mode"},"lightMode":{"type":"string","example":"Light mode"}}},"messages":{"type":"object","description":"User messages and notifications","properties":{"noStories":{"type":"string","example":"No stories available"},"errorLoading":{"type":"string","example":"Error loading stories. Please try again."},"networkError":{"type":"string","example":"Network error. Please check your connection."}}}},"additionalProperties":{"type":"object","description":"Additional nested string objects"}}}},"example":{"locale":"en","strings":{"title":"Kagi News - Elevated","description":"Elevate your news reading experience","categories":{"World":"World","USA":"USA","Business":"Business","Technology":"Technology"},"ui":{"loading":"Loading...","error":"Error loading data","showMore":"Show more","settings":"Settings"}}}}}}}}},"/api/search":{"get":{"summary":"Search stories across all batches","description":"Full-text search across story titles and summaries with date filtering","tags":["Search"],"parameters":[{"in":"query","name":"q","required":true,"schema":{"type":"string","minLength":2},"description":"Search query (minimum 2 characters)","example":"climate change"},{"in":"query","name":"limit","schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"description":"Maximum number of results"},{"in":"query","name":"offset","schema":{"type":"integer","default":0,"minimum":0},"description":"Offset for pagination"},{"in":"query","name":"from","schema":{"type":"string","format":"date-time"},"description":"Start date for search (ISO 8601)","example":"2025-01-01T00:00:00Z"},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"},"description":"End date for search (ISO 8601)","example":"2025-12-31T23:59:59Z"},{"in":"query","name":"lang","schema":{"type":"string","default":"default","enum":["default","en","it","pt","pt-BR","fr","es","de","ja","hi","nl","uk","ca","fi","ko","lb","nb","pl","ru","zh","zh-Hans","zh-Hant","sv","th","tr","ar","he"]},"description":"Language code"},{"in":"query","name":"categoryId","schema":{"type":"string"},"description":"Filter by specific category ID"}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"story":{"$ref":"#/components/schemas/Story"},"batchId":{"type":"string"},"batchDate":{"type":"string","format":"date-time"},"categoryId":{"type":"string"},"categoryName":{"type":"string"}}}},"totalCount":{"type":"integer","description":"Total number of matching results"},"hasMore":{"type":"boolean","description":"Whether more results are available"}}}}}},"400":{"description":"Invalid search parameters"},"429":{"description":"Too many requests"},"500":{"description":"Server error"}}}},"/api/openapi":{"get":{"summary":"Get OpenAPI specification","description":"Returns the OpenAPI 3.0 specification for the Kagi News API in JSON format","tags":["Documentation"],"parameters":[{"in":"query","name":"format","schema":{"type":"string","enum":["json"],"default":"json"},"description":"Output format (currently only JSON is supported)"}],"responses":{"200":{"description":"OpenAPI specification document","content":{"application/json":{"schema":{"type":"object","description":"OpenAPI 3.0 specification object"}}}},"400":{"description":"Bad request - unsupported format","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"Unsupported format. Use \"json\"."}}}}}}}}}}}