{"components":{"schemas":{"Archive":{"properties":{"archived_at":{"format":"date-time","type":"string"},"checksum":{"type":"string"},"commit_count":{"type":"integer"},"commit_ref":{"type":"string"},"compression":{"enum":["zip","git_bundle","tar","custom"],"type":"string"},"deleted_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"repository_id":{"format":"uuid","type":"string"},"size_bytes":{"type":"integer"},"status":{"enum":["pending","fetching","processing","archived","verification_failed","failed"],"type":"string"},"storage":{"properties":{"key":{"type":"string"},"provider":{"type":"string"}},"type":"object"}},"type":"object"},"ArchiveResponse":{"properties":{"archive":{"$ref":"#/components/schemas/Archive"},"download_url":{"type":"string"},"storage_provider":{"type":"string"}},"type":"object"},"CreateArchiveRequest":{"properties":{"full_name":{"description":"owner/repo","type":"string"}},"required":["full_name"],"type":"object"},"CreateArchiveResponse":{"properties":{"archive_id":{"format":"uuid","type":"string"},"message":{"type":"string"},"status":{"type":"string"}},"type":"object"},"ErrorBody":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"message":{"type":"string"}},"type":"object"},"HealthResponse":{"properties":{"database":{"enum":["ok","unreachable"],"type":"string"},"status":{"type":"string"},"uptime_secs":{"type":"integer"},"version":{"type":"string"}},"type":"object"},"HistoryArchive":{"properties":{"archived_at":{"format":"date-time","type":"string"},"checksum":{"type":"string"},"commit_count":{"type":"integer"},"commit_ref":{"type":"string"},"id":{"format":"uuid","type":"string"},"size_bytes":{"type":"integer"},"status":{"type":"string"}},"type":"object"},"HistoryResponse":{"properties":{"archives":{"items":{"$ref":"#/components/schemas/HistoryArchive"},"type":"array"},"owner":{"type":"string"},"repo":{"type":"string"}},"type":"object"},"OwnerResponse":{"properties":{"avatar_url":{"type":"string"},"bio":{"type":"string"},"followers":{"type":"integer"},"following":{"type":"integer"},"html_url":{"type":"string"},"login":{"type":"string"},"name":{"type":"string"},"pinned_repos":{"items":{"$ref":"#/components/schemas/PinnedRepo"},"type":"array"},"preserved_count":{"type":"integer"},"public_repos":{"type":"integer"},"top_repos":{"items":{"$ref":"#/components/schemas/OwnerTopRepo"},"type":"array"}},"type":"object"},"OwnerTopRepo":{"properties":{"description":{"type":"string"},"full_name":{"type":"string"},"html_url":{"type":"string"},"language":{"type":"string"},"name":{"type":"string"},"stars_count":{"type":"integer"}},"type":"object"},"PinnedRepo":{"properties":{"description":{"type":"string"},"full_name":{"type":"string"},"html_url":{"type":"string"},"name":{"type":"string"},"primary_language":{"type":"string"},"stargazer_count":{"type":"integer"}},"type":"object"},"ReadmeResponse":{"properties":{"html_url":{"type":"string"},"readme":{"type":"string"},"source":{"enum":["salsyx","github"],"type":"string"}},"type":"object"},"RefreshRequest":{"properties":{"full_name":{"description":"owner/repo","type":"string"}},"required":["full_name"],"type":"object"},"RefreshResponse":{"properties":{"archive_id":{"format":"uuid","type":"string"},"full_name":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"}},"type":"object"},"RepoResponse":{"properties":{"archive":{"type":"object"},"download_url":{"type":"string"},"message":{"type":"string"},"repository":{"type":"object"},"source":{"enum":["github","salsyx"],"type":"string"},"status":{"enum":["live","archived","not_found"],"type":"string"}},"type":"object"},"SearchItem":{"properties":{"archived_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"forks_count":{"type":"integer"},"full_name":{"type":"string"},"has_archive":{"type":"boolean"},"html_url":{"type":"string"},"id":{"format":"uuid","type":"string"},"is_deleted":{"type":"boolean"},"language":{"type":"string"},"license":{"type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"stars_count":{"type":"integer"},"topics":{"items":{"type":"string"},"type":"array"}},"type":"object"},"SearchResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/SearchItem"},"type":"array"},"page":{"type":"integer"},"per_page":{"type":"integer"},"query":{"type":"string"},"total":{"type":"integer"}},"type":"object"},"StatsResponse":{"properties":{"archived_repositories":{"type":"integer"},"deleted_archived":{"type":"integer"},"indexed_bytes":{"type":"integer"},"total_archived_bytes":{"type":"integer"},"total_archives":{"type":"integer"},"total_downloads":{"type":"integer"},"total_owners":{"type":"integer"},"total_repositories":{"type":"integer"}},"type":"object"},"TopResponse":{"properties":{"languages":{"items":{"properties":{"count":{"type":"integer"},"language":{"type":"string"}},"type":"object"},"type":"array"},"top_repositories":{"items":{"type":"object"},"type":"array"}},"type":"object"},"TreeEntry":{"properties":{"path":{"type":"string"},"size":{"type":"integer"},"type":{"enum":["blob","tree","commit"],"type":"string"}},"type":"object"},"TreeResponse":{"properties":{"archive_id":{"format":"uuid","type":"string"},"commit_ref":{"type":"string"},"entries":{"items":{"$ref":"#/components/schemas/TreeEntry"},"type":"array"},"regenerated":{"type":"boolean"}},"type":"object"},"WebhookResponse":{"properties":{"received":{"type":"boolean"},"scheduled":{"items":{"type":"string"},"type":"array"}},"type":"object"}}},"info":{"description":"Search and preservation platform for public GitHub repositories. Nothing open-source should disappear forever.","license":{"name":"MIT"},"title":"Salsyx API","version":"0.1.0"},"openapi":"3.1.0","paths":{"/archive":{"post":{"operationId":"createArchive","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArchiveRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArchiveResponse"}}},"description":"Archive job queued"}},"summary":"Enqueue an archive job","tags":["archive"]}},"/archive/{id}":{"get":{"operationId":"getArchive","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArchiveResponse"}}},"description":"Archive metadata"}},"summary":"Get archive metadata","tags":["archive"]}},"/archive/{id}/blob":{"get":{"operationId":"archiveBlob","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"description":"File path within the archive","in":"query","name":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/octet-stream":{"schema":{"format":"binary","type":"string"}}},"description":"File bytes"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}},"description":"Path not present in the archive"}},"summary":"Stream one preserved file","tags":["archive"]}},"/archive/{id}/tree":{"get":{"operationId":"archiveTree","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TreeResponse"}}},"description":"Recursive file listing"}},"summary":"Browse the preserved file tree","tags":["archive"]}},"/download/{id}":{"get":{"description":"Streams the archived snapshot with integrity verification.","operationId":"downloadArchive","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"Binary archive stream"}},"summary":"Download archived blob","tags":["archive"]}},"/health":{"get":{"operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}},"description":"Service is healthy"}},"summary":"Health check","tags":["health"]}},"/owner/{login}":{"get":{"description":"Live GitHub profile (followers/following/public repos/pinned) plus preserved-repo counts.","operationId":"getOwner","parameters":[{"in":"path","name":"login","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerResponse"}}},"description":"Owner profile"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}},"description":"Owner not found on GitHub"}},"summary":"Owner profile","tags":["owner"]}},"/refresh":{"post":{"operationId":"refreshRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshResponse"}}},"description":"Refresh result"}},"summary":"Force-refresh a repository","tags":["repository"]}},"/repo/{owner}/{repo}":{"get":{"description":"Checks GitHub first; if deleted, falls back to the Salsyx archive database.","operationId":"resolveRepository","parameters":[{"in":"path","name":"owner","required":true,"schema":{"type":"string"}},{"in":"path","name":"repo","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepoResponse"}}},"description":"Resolution result"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}},"description":"Not found on GitHub and not archived"}},"summary":"Resolve a repository","tags":["repository"]}},"/repo/{owner}/{repo}/archives":{"get":{"operationId":"repoArchiveHistory","parameters":[{"in":"path","name":"owner","required":true,"schema":{"type":"string"}},{"in":"path","name":"repo","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryResponse"}}},"description":"Archives, newest first"}},"summary":"Archive history for a repository","tags":["repository"]}},"/repo/{owner}/{repo}/readme":{"get":{"description":"Returns the default-branch README, preferring the preserved snapshot and falling back to a live GitHub fetch.","operationId":"getReadme","parameters":[{"in":"path","name":"owner","required":true,"schema":{"type":"string"}},{"in":"path","name":"repo","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadmeResponse"}}},"description":"README content"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}},"description":"No README available"}},"summary":"Get the README","tags":["repository"]}},"/search":{"get":{"description":"Searches by repository name, owner, description, language, license, topics, and star range. Supports exact, partial, and fuzzy matching. When the local index has no matches, falls back to a live GitHub search and indexes the results.","operationId":"search","parameters":[{"description":"Search term","in":"query","name":"q","schema":{"type":"string"}},{"description":"Match mode","in":"query","name":"mode","schema":{"enum":["exact","partial","fuzzy","full_text"],"type":"string"}},{"description":"Filter by owner login","in":"query","name":"owner","schema":{"type":"string"}},{"description":"Filter by primary language","in":"query","name":"language","schema":{"type":"string"}},{"description":"Filter by SPDX license","in":"query","name":"license","schema":{"type":"string"}},{"description":"Comma-separated topics (OR)","in":"query","name":"topics","schema":{"type":"string"}},{"description":"Minimum star count","in":"query","name":"min_stars","schema":{"type":"integer"}},{"description":"Include deleted repos","in":"query","name":"include_deleted","schema":{"type":"boolean"}},{"description":"Only repos with archives","in":"query","name":"archived_only","schema":{"type":"boolean"}},{"description":"Sort key","in":"query","name":"sort","schema":{"enum":["relevance","stars","forks","name","updated_at","archived_at","commit_count"],"type":"string"}},{"description":"Sort direction","in":"query","name":"order","schema":{"enum":["asc","desc"],"type":"string"}},{"in":"query","name":"page","schema":{"default":1,"type":"integer"}},{"in":"query","name":"per_page","schema":{"default":20,"maximum":100,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}},"description":"Search results"}},"summary":"Search repositories","tags":["search"]}},"/stats":{"get":{"operationId":"stats","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}},"description":"Aggregate metrics"}},"summary":"Platform statistics","tags":["stats"]}},"/stats/top":{"get":{"operationId":"statsTop","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopResponse"}}},"description":"Top lists"}},"summary":"Top languages and repositories","tags":["stats"]}},"/webhook/github":{"post":{"description":"Receives GitHub deliveries. Sits at the host root (not under /api/v1).","operationId":"githubWebhook","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}},"description":"Webhook acknowledged"}},"summary":"GitHub webhook (event-driven refresh)","tags":["webhook"]}}},"servers":[{"description":"Default base path","url":"/api/v1"}],"tags":[{"description":"Liveness and readiness","name":"health"},{"description":"Repository search","name":"search"},{"description":"Repository resolution","name":"repository"},{"description":"Archived snapshots","name":"archive"},{"description":"Platform statistics","name":"stats"},{"description":"GitHub owner profiles","name":"owner"},{"description":"Event-driven integrations","name":"webhook"}]}