{
  "ok": true,
  "name": "Oman Fencing Committee, Public API",
  "version": "1.0",
  "note": "Open, unauthenticated JSON endpoints for press, ministries and integrators. Rate limit: 300s shared cache. CORS: *.",
  "endpoints": {
    "events": {
      "url": "/api/public/events?year={YYYY}&tag={tag}",
      "format": "application/json",
      "description": "Upcoming and past tournaments. Optional ?year=YYYY (date prefix match) and ?tag=international (case-insensitive exact)."
    },
    "news": {
      "url": "/api/public/news?year={YYYY}&q={substring}&limit={1-200}",
      "format": "application/json",
      "description": "Recent news articles (title + slug + date + cover). Optional ?year=YYYY date-prefix, ?q=substring NFD-normalised title match, ?limit=N (default 50, max 200)."
    },
    "athletes": {
      "url": "/api/public/athletes?weapon={foil,epee,sabre}&club={substring}&active={0,1}&ageCategory={U11,U13,U15,U17,U20,Senior}",
      "format": "application/json",
      "description": "Active national-team athletes. Optional filters: weapon (NFD-normalised), club (case-insensitive substring), active (0 to include retired)."
    },
    "clubs": {
      "url": "/api/public/clubs",
      "format": "application/json",
      "description": "Member clubs (EN/AR names, city, notes, public contact)."
    },
    "committee": {
      "url": "/api/public/committee",
      "format": "application/json",
      "description": "Active committee members (EN/AR names, role, photo, bio). Email and phone are deliberately omitted, use /api/committee/contact to reach a member."
    },
    "coaches": {
      "url": "/api/public/coaches",
      "format": "application/json",
      "description": "Active national-programme coaches (EN/AR names, role, photo, bio, certification). No email/phone, use /api/committee/contact to reach one."
    },
    "venues": {
      "url": "/api/public/venues",
      "format": "application/json",
      "description": "Training venues for member clubs (EN/AR names, city, address, parking note, Google Maps URL)."
    },
    "disciplines": {
      "url": "/api/public/disciplines",
      "format": "application/json",
      "description": "The three weapons (foil, épée, sabre) with EN/AR names, target area and scoring rules."
    },
    "stats": {
      "url": "/api/public/stats",
      "format": "application/json",
      "description": "Aggregate counts (athletes by weapon/gender, clubs, events, news)."
    },
    "results": {
      "url": "/api/public/results?athleteSlug={slug}&medal={gold,silver,bronze}&year={YYYY}&weapon={foil,epee,sabre}&limit={1-500}",
      "format": "application/json",
      "description": "Tournament results (athlete, tournament, date, medal, placing, level). Optional filters: athleteSlug / athleteId, medal, year (date prefix), weapon, limit (default 200)."
    },
    "upcoming": {
      "url": "/api/public/upcoming",
      "format": "application/json",
      "description": "Only upcoming events (date >= today UTC), sorted soonest first."
    },
    "latest": {
      "url": "/api/public/latest",
      "format": "application/json",
      "description": "One-call combined feed: 5 latest events + 5 latest news + 10 latest results. Use for widgets."
    },
    "now": {
      "url": "/api/public/now",
      "format": "application/json",
      "description": "This-week snapshot: events this week, next 5 upcoming with days-out, last 7 days news, last 30 days results. JSON sibling of /now page."
    },
    "spotlight": {
      "url": "/api/public/spotlight",
      "format": "application/json",
      "description": "Deterministic \"athlete of the day\", same pick for all callers on the same UTC date, rotates at midnight."
    },
    "changelog": {
      "url": "/api/public/changelog",
      "format": "application/json",
      "description": "Every shipped sprint iteration parsed from loop-log.txt. Optional ?limit=N (default 200, max 500)."
    },
    "feeds": {
      "url": "/api/public/feeds.json",
      "format": "application/json",
      "description": "Catalog of every machine-readable surface (RSS, Atom, ICS, CSV, JSON) with descriptions."
    },
    "search": {
      "url": "/api/public/search?q={query}&limit={1-50}&types={athlete,event,news,club,committee}",
      "format": "application/json",
      "description": "Cross-entity search across athletes, news, events, clubs and committee. Returns scored hits with snippets. Optional types= comma-separated filter narrows which buckets are searched."
    },
    "suggest": {
      "url": "/api/public/search/suggest?q={query}&types={athlete,event,news,club,committee}",
      "format": "application/json",
      "description": "Lightweight typeahead, title-only, max 8 results, 30s cache. Optional types= comma-separated filter. For autocomplete dropdowns."
    },
    "rss": {
      "url": "/news.rss.xml",
      "format": "application/rss+xml",
      "description": "News RSS 2.0 feed (40 latest items)."
    },
    "calendar": {
      "url": "/events.ics",
      "format": "text/calendar",
      "description": "Events calendar in iCalendar (RFC 5545) format for Google/Apple/Outlook."
    },
    "sitemap": {
      "url": "/sitemap.xml",
      "format": "application/xml",
      "description": "XML sitemap of all public pages."
    },
    "sitemapJson": {
      "url": "/api/public/sitemap.json",
      "format": "application/json",
      "description": "JSON enumeration of every indexable URL (static pages + dynamic news/events/athletes/clubs)."
    },
    "openapi": {
      "url": "/api/openapi.json",
      "format": "application/json",
      "description": "OpenAPI 3.1 descriptor for every public endpoint (importable into Postman / Insomnia)."
    }
  },
  "contact": "info@fencing.om"
}