Documentation
¶
Overview ¶
Package upstream reads the vendors' own status pages (#971, emo172): a request that fails while Anthropic's or OpenAI's API is down looks, in magpie, like a sign-in or quota problem, and the user signs in again and again for nothing. A vendor whose page says its API is degraded or down is said so where its providers are listed.
Only the page's own parts that the API magpie calls stands on are read (the Claude API and Claude Code, not claude.ai; OpenAI's Chat Completions, Responses and Codex, not ChatGPT's or its desktop app's): a vendor's app being down says nothing of its API. A page that couldn't be read is unknown, never "all well". The pages are read only when the GUI asks, at most once in Fresh, and never on a request's way.
Index ¶
Constants ¶
const Fresh = 5 * time.Minute
Fresh is how long a page read is kept: the pages change by the minute in an outage, but nobody needs them to the second.
Variables ¶
var Vendors = []Vendor{ {ID: "anthropic", Name: "Anthropic", Page: "https://status.claude.com", Summary: "https://status.claude.com/api/v2/summary.json", Hosts: []string{"api.anthropic.com"}, Part: func(n string) bool { return strings.HasPrefix(n, "Claude API") || n == "Claude Code" }}, {ID: "openai", Name: "OpenAI", Page: "https://status.openai.com", Summary: "https://status.openai.com/api/v2/summary.json", Hosts: []string{"api.openai.com", "chatgpt.com"}, Part: func(n string) bool { return slices.Contains([]string{"Chat Completions", "Responses", "Codex", "Codex CLI"}, n) }}, {ID: "moonshot", Name: "Moonshot AI", Page: "https://status.moonshot.cn", Summary: "https://status.moonshot.cn/api/v2/summary.json", Hosts: []string{"api.moonshot.cn", "api.moonshot.ai"}, Part: func(n string) bool { return n == "Open API" || n == "API Service" || n == "Model" || strings.HasSuffix(n, " Model") }}, {ID: "deepseek", Name: "DeepSeek", Page: "https://status.deepseek.com", Hosts: []string{"api.deepseek.com"}}, }
Vendors are the ones whose pages were checked by hand (2026-10-06): each one's summary.json answered with its components.
Functions ¶
Types ¶
type Incident ¶
type Incident struct {
Name string `json:"name"`
Impact string `json:"impact,omitempty"`
URL string `json:"url,omitempty"`
}
Incident is an open incident the page lists.
type Part ¶
Part is a component of the page and its state as the page words it (degraded_performance, partial_outage, major_outage, under_maintenance).
type Status ¶
type Status struct {
Vendor string `json:"vendor"`
Name string `json:"name"`
Page string `json:"page"`
// Level is the worst of its API's parts: "ok", "degraded", "partial"
// (a partial outage), "major" (a major outage) or "maintenance"; ""
// when the page wasn't read (none to read, or it failed: Error).
Level string `json:"level"`
Parts []Part `json:"parts,omitempty"` // the API's parts that aren't operational
Incidents []Incident `json:"incidents,omitempty"` // open incidents on them
Read time.Time `json:"read,omitzero"`
Error string `json:"error,omitempty"`
}
Status is what a vendor's page says of its API.
type Vendor ¶
type Vendor struct {
ID string
Name string
// Page is the status page people read; Summary its Statuspage-style
// JSON (/api/v2/summary.json), "" when it has none magpie can read
// (DeepSeek's, on Flashduty): the page is then only linked.
Page string
Summary string
// Hosts are the API hosts a provider calls the vendor on.
Hosts []string
// Part says whether a component of the page is one the API stands on.
Part func(name string) bool
}
Vendor is a vendor whose status page magpie knows.