{
  "schema_version": "1.0",
  "name": "Community News API",
  "description": "Public API for community journalism — articles, communities, memberships, and search",
  "url": "https://alaskanews.news",
  "capabilities": [
    {
      "name": "list_articles",
      "method": "GET",
      "endpoint": "/api/v1/articles?community={slug}",
      "auth_required": true,
      "description": "List published articles for a community"
    },
    {
      "name": "create_article",
      "method": "POST",
      "endpoint": "/api/v1/articles",
      "auth_required": true,
      "description": "Create a new draft article"
    },
    {
      "name": "get_article",
      "method": "GET",
      "endpoint": "/api/v1/articles/{id}",
      "auth_required": true,
      "description": "Get a single article by ID"
    },
    {
      "name": "update_article",
      "method": "PUT",
      "endpoint": "/api/v1/articles/{id}",
      "auth_required": true,
      "description": "Update a draft article"
    },
    {
      "name": "submit_article",
      "method": "POST",
      "endpoint": "/api/v1/articles/{id}/submit",
      "auth_required": true,
      "description": "Submit article for peer review"
    },
    {
      "name": "list_communities",
      "method": "GET",
      "endpoint": "/api/v1/communities",
      "auth_required": true,
      "description": "List communities accessible to your API key"
    },
    {
      "name": "get_community",
      "method": "GET",
      "endpoint": "/api/v1/communities/{slug}",
      "auth_required": true,
      "description": "Get community details by slug"
    },
    {
      "name": "list_community_articles",
      "method": "GET",
      "endpoint": "/api/v1/communities/{slug}/articles",
      "auth_required": true,
      "description": "List published articles in a community"
    },
    {
      "name": "list_community_members",
      "method": "GET",
      "endpoint": "/api/v1/communities/{slug}/members",
      "auth_required": true,
      "description": "List members of a community"
    },
    {
      "name": "list_memberships",
      "method": "GET",
      "endpoint": "/api/v1/memberships",
      "auth_required": true,
      "description": "List your community memberships and roles"
    },
    {
      "name": "join_community",
      "method": "POST",
      "endpoint": "/api/v1/memberships",
      "auth_required": true,
      "description": "Join a community"
    },
    {
      "name": "search",
      "method": "GET",
      "endpoint": "/api/v1/search?q={query}",
      "auth_required": true,
      "description": "Full-text search across articles, communities, and users"
    },
    {
      "name": "list_topics",
      "method": "GET",
      "endpoint": "/api/v1/topics",
      "auth_required": true,
      "description": "List all topics with article stats"
    },
    {
      "name": "get_topic",
      "method": "GET",
      "endpoint": "/api/v1/topics/{slug}",
      "auth_required": true,
      "description": "Get topic details and articles by slug"
    },
    {
      "name": "list_sources",
      "method": "GET",
      "endpoint": "/api/v1/communities/{slug}/sources",
      "auth_required": true,
      "description": "List content sources for a community (video, audio, email, web scrape, RSS, PDF, manual)"
    },
    {
      "name": "create_source",
      "method": "POST",
      "endpoint": "/api/v1/communities/{slug}/sources",
      "auth_required": true,
      "description": "Create a new content source"
    },
    {
      "name": "get_source",
      "method": "GET",
      "endpoint": "/api/v1/communities/{slug}/sources/{id}",
      "auth_required": true,
      "description": "Get content source details with transcript chunks and drafted articles"
    },
    {
      "name": "classify_source",
      "method": "POST",
      "endpoint": "/api/v1/communities/{slug}/sources/{id}/classify",
      "auth_required": true,
      "description": "Trigger LLM classification for newsworthiness, category, topics, and entities"
    },
    {
      "name": "draft_from_source",
      "method": "POST",
      "endpoint": "/api/v1/communities/{slug}/sources/{id}/draft",
      "auth_required": true,
      "description": "Trigger article drafting from a content source via pipeline"
    },
    {
      "name": "list_coauthors",
      "method": "GET",
      "endpoint": "/api/v1/articles/{id}/coauthors",
      "auth_required": true,
      "description": "List co-authors for an article"
    },
    {
      "name": "invite_coauthor",
      "method": "POST",
      "endpoint": "/api/v1/articles/{id}/coauthors",
      "auth_required": true,
      "description": "Invite a co-author to an article"
    },
    {
      "name": "respond_coauthor_invite",
      "method": "PUT",
      "endpoint": "/api/v1/articles/{id}/coauthors/{coauthorId}",
      "auth_required": true,
      "description": "Accept or decline a co-author invitation"
    },
    {
      "name": "list_reviews",
      "method": "GET",
      "endpoint": "/api/v1/articles/{id}/reviews",
      "auth_required": true,
      "description": "List reviews for an article"
    },
    {
      "name": "submit_review",
      "method": "POST",
      "endpoint": "/api/v1/articles/{id}/reviews",
      "auth_required": true,
      "description": "Submit a review (approve/request_changes/reject)"
    },
    {
      "name": "list_comments",
      "method": "GET",
      "endpoint": "/api/v1/articles/{id}/comments",
      "auth_required": true,
      "description": "List comments on an article"
    },
    {
      "name": "add_comment",
      "method": "POST",
      "endpoint": "/api/v1/articles/{id}/comments",
      "auth_required": true,
      "description": "Add a comment to an article"
    },
    {
      "name": "edit_comment",
      "method": "PUT",
      "endpoint": "/api/v1/articles/{id}/comments/{commentId}",
      "auth_required": true,
      "description": "Edit a comment (within 1 hour of creation)"
    },
    {
      "name": "delete_comment",
      "method": "DELETE",
      "endpoint": "/api/v1/articles/{id}/comments/{commentId}",
      "auth_required": true,
      "description": "Delete your own comment"
    },
    {
      "name": "get_reactions",
      "method": "GET",
      "endpoint": "/api/v1/articles/{id}/reactions",
      "auth_required": true,
      "description": "Get reaction counts for an article"
    },
    {
      "name": "toggle_reaction",
      "method": "POST",
      "endpoint": "/api/v1/articles/{id}/reactions",
      "auth_required": true,
      "description": "Toggle an emoji reaction on an article"
    },
    {
      "name": "toggle_bookmark",
      "method": "POST",
      "endpoint": "/api/v1/articles/{id}/bookmarks",
      "auth_required": true,
      "description": "Toggle bookmark on an article"
    },
    {
      "name": "list_notifications",
      "method": "GET",
      "endpoint": "/api/v1/notifications",
      "auth_required": true,
      "description": "List user notifications"
    },
    {
      "name": "mark_notification_read",
      "method": "PATCH",
      "endpoint": "/api/v1/notifications/{id}",
      "auth_required": true,
      "description": "Mark a notification as read"
    },
    {
      "name": "mark_all_notifications_read",
      "method": "POST",
      "endpoint": "/api/v1/notifications/mark-all-read",
      "auth_required": true,
      "description": "Mark all notifications as read"
    },
    {
      "name": "report_article",
      "method": "POST",
      "endpoint": "/api/v1/articles/{id}/report",
      "auth_required": true,
      "description": "Report an article for violating community guidelines"
    },
    {
      "name": "report_comment",
      "method": "POST",
      "endpoint": "/api/v1/articles/{id}/comments/{commentId}/report",
      "auth_required": true,
      "description": "Report a comment for violating community guidelines"
    },
    {
      "name": "list_reports",
      "method": "GET",
      "endpoint": "/api/v1/communities/{slug}/moderation/reports",
      "auth_required": true,
      "description": "List content reports for a community (admin only)"
    },
    {
      "name": "resolve_report",
      "method": "PUT",
      "endpoint": "/api/v1/communities/{slug}/moderation/reports/{id}",
      "auth_required": true,
      "description": "Resolve a content report (admin only)"
    },
    {
      "name": "get_profile",
      "method": "GET",
      "endpoint": "/api/v1/me",
      "auth_required": true,
      "description": "Get authenticated user's profile with memberships and roles"
    },
    {
      "name": "update_profile",
      "method": "PUT",
      "endpoint": "/api/v1/me",
      "auth_required": true,
      "description": "Update authenticated user's profile"
    },
    {
      "name": "list_bookmarks",
      "method": "GET",
      "endpoint": "/api/v1/me/bookmarks",
      "auth_required": true,
      "description": "List user's bookmarked articles"
    },
    {
      "name": "create_api_key",
      "method": "POST",
      "endpoint": "/api/v1/api-keys",
      "auth_required": true,
      "description": "Create a new API key programmatically"
    },
    {
      "name": "api_discovery",
      "method": "GET",
      "endpoint": "/api/v1",
      "auth_required": false,
      "description": "API discovery with links to all resources"
    },
    {
      "name": "get_voice_profile",
      "method": "GET",
      "endpoint": "/api/v1/voice-profile",
      "auth_required": true,
      "description": "Get active voice profile and version history"
    },
    {
      "name": "calibrate_voice",
      "method": "POST",
      "endpoint": "/api/v1/voice-profile",
      "auth_required": true,
      "description": "Calibrate a new voice profile version from writing samples"
    },
    {
      "name": "update_voice_profile",
      "method": "PUT",
      "endpoint": "/api/v1/voice-profile/{id}",
      "auth_required": true,
      "description": "Activate a voice version or manually update the profile"
    },
    {
      "name": "delete_voice_profile",
      "method": "DELETE",
      "endpoint": "/api/v1/voice-profile/{id}",
      "auth_required": true,
      "description": "Delete a non-active voice profile version"
    },
    {
      "name": "get_worker_profile",
      "method": "GET",
      "endpoint": "/api/v1/worker/profile",
      "auth_required": true,
      "description": "Get citizen worker profile and stats (worker auth)"
    },
    {
      "name": "get_available_job",
      "method": "GET",
      "endpoint": "/api/v1/worker/jobs/available",
      "auth_required": true,
      "description": "Get next available transcription job for worker to claim"
    },
    {
      "name": "claim_job",
      "method": "POST",
      "endpoint": "/api/v1/worker/jobs/{id}/claim",
      "auth_required": true,
      "description": "Claim a transcription job (worker auth)"
    },
    {
      "name": "send_heartbeat",
      "method": "POST",
      "endpoint": "/api/v1/worker/jobs/{id}/heartbeat",
      "auth_required": true,
      "description": "Send heartbeat for claimed job to prevent timeout"
    },
    {
      "name": "upload_chunk",
      "method": "POST",
      "endpoint": "/api/v1/worker/jobs/{id}/chunks",
      "auth_required": true,
      "description": "Upload an audio chunk for transcription"
    },
    {
      "name": "complete_job",
      "method": "POST",
      "endpoint": "/api/v1/worker/jobs/{id}/complete",
      "auth_required": true,
      "description": "Mark job as complete after all chunks uploaded"
    },
    {
      "name": "fail_job",
      "method": "POST",
      "endpoint": "/api/v1/worker/jobs/{id}/fail",
      "auth_required": true,
      "description": "Report job failure with error details"
    },
    {
      "name": "list_workers",
      "method": "GET",
      "endpoint": "/api/v1/workers",
      "auth_required": true,
      "description": "List citizen workers (platform admin only)"
    },
    {
      "name": "get_worker",
      "method": "GET",
      "endpoint": "/api/v1/workers/{id}",
      "auth_required": true,
      "description": "Get worker details (platform admin only)"
    },
    {
      "name": "approve_worker",
      "method": "POST",
      "endpoint": "/api/v1/workers/{id}/approve",
      "auth_required": true,
      "description": "Approve pending worker application (platform admin only)"
    },
    {
      "name": "suspend_worker",
      "method": "POST",
      "endpoint": "/api/v1/workers/{id}/suspend",
      "auth_required": true,
      "description": "Suspend worker with reason (platform admin only)"
    },
    {
      "name": "reinstate_worker",
      "method": "POST",
      "endpoint": "/api/v1/workers/{id}/reinstate",
      "auth_required": true,
      "description": "Reinstate suspended worker (platform admin only)"
    },
    {
      "name": "list_jobs",
      "method": "GET",
      "endpoint": "/api/v1/jobs",
      "auth_required": true,
      "description": "List transcription jobs (platform admin only)"
    },
    {
      "name": "create_job",
      "method": "POST",
      "endpoint": "/api/v1/jobs",
      "auth_required": true,
      "description": "Create transcription job (platform admin only)"
    },
    {
      "name": "get_job",
      "method": "GET",
      "endpoint": "/api/v1/jobs/{id}",
      "auth_required": true,
      "description": "Get job details (platform admin only)"
    },
    {
      "name": "update_job_priority",
      "method": "PATCH",
      "endpoint": "/api/v1/jobs/{id}",
      "auth_required": true,
      "description": "Update job priority (platform admin only)"
    },
    {
      "name": "cancel_job",
      "method": "POST",
      "endpoint": "/api/v1/jobs/{id}/cancel",
      "auth_required": true,
      "description": "Cancel a job (platform admin only)"
    },
    {
      "name": "retry_job",
      "method": "POST",
      "endpoint": "/api/v1/jobs/{id}/retry",
      "auth_required": true,
      "description": "Force retry failed job (platform admin only)"
    }
  ],
  "authentication": {
    "type": "bearer",
    "header": "Authorization",
    "prefix": "Bearer",
    "key_prefix": "cn_"
  },
  "documentation": "https://alaskanews.news/docs/api",
  "rate_limits": {
    "read": "100 requests per minute",
    "write": "20 requests per minute"
  },
  "supports_hateoas": true,
  "sorting": {
    "description": "Article and community list endpoints support sorting via query parameters",
    "modes": {
      "hot": "Trending content based on recent engagement (default)",
      "new": "Most recently published first",
      "nearby": "Sorted by geographic proximity — requires lat, lng query params",
      "top": "Highest rated within a time window — use t param (today, week, month, all)",
      "rising": "Recent articles gaining traction quickly",
      "controversial": "High engagement but mixed/polarized reactions",
      "foryou": "Personalized feed; excludes already-read articles"
    },
    "parameters": {
      "sort": "Sort mode: hot, new, nearby, top, rising, controversial, foryou (default: hot)",
      "t": "Time window for top sort: today, week, month, all (default: week)",
      "lat": "Latitude for nearby sort",
      "lng": "Longitude for nearby sort",
      "r": "Radius in miles for nearby sort (default: 50, min: 5, max: 500)"
    }
  }
}
