···11+# Public Status Widget
22+33+We have added a public endpoint where you can access the status of your status
44+page. To access it, you only need the unique `:slug` you have chosen for your
55+page.
66+77+```bash
88+curl https://api.openstatus.dev/public/status/:slug
99+```
1010+1111+The response is a JSON object with the following structure:
1212+1313+```json
1414+{ "status": "operational" }
1515+```
1616+1717+in which the status can be one of the following values:
1818+1919+```ts
2020+enum Status {
2121+ Operational = "operational",
2222+ DegradedPerformance = "degraded_performance",
2323+ PartialOutage = "partial_outage",
2424+ MajorOutage = "major_outage",
2525+ UnderMaintenance = "under_maintenance", // currently not in use
2626+ Unknown = "unknown",
2727+}
2828+```
2929+3030+### How does it work?
3131+3232+The status is calculated by the ratio `uptime / (uptime + downtime)` of the last
3333+5 cron jobs of each monitor which we accumulate together. It is a simple
3434+calculation that gives us a good overview of the status of your services.
3535+3636+```ts
3737+function getStatus(ratio: number) {
3838+ if (isNaN(ratio)) return Status.Unknown;
3939+ if (ratio >= 0.98) return Status.Operational;
4040+ if (ratio >= 0.6) return Status.DegradedPerformance;
4141+ if (ratio >= 0.3) return Status.PartialOutage;
4242+ if (ratio >= 0) return Status.MajorOutage;
4343+ return Status.Unknown;
4444+}
4545+```
4646+4747+We are caching the result for `30 seconds` to reduce the load on our database.
4848+4949+> If you have a doubt about the above calculation, feel free to contact us via
5050+> [ping@openstatus.dev](mailto:ping@openstatus.dev) or
5151+> [discord](https://openstatus.dev/discord).
5252+5353+### React Widget
5454+5555+We currently do not provide any SDK or package to integrate the status into your
5656+stack. But will in the future.
5757+5858+If you are using Nextjs and RSC with the `/app` directory, feel free to use that
5959+Component. Small reminder that we are using shadcn ui and tailwindcss. You might
6060+want to update the `bg-muted` and `text-foreground` classes to your needs.
6161+6262+
6363+6464+We are using `zod` to validate the response. You can use any other library if
6565+you want or just remove it. But better be safe than sorry.
6666+6767+```tsx
6868+import * as z from "zod";
6969+7070+const statusEnum = z.enum([
7171+ "operational",
7272+ "degraded_performance",
7373+ "partial_outage",
7474+ "major_outage",
7575+ "under_maintenance", // currently not in use
7676+ "unknown",
7777+]);
7878+7979+const statusSchema = z.object({ status: statusEnum });
8080+8181+const dictionary = {
8282+ operational: {
8383+ label: "Operational",
8484+ color: "bg-green-500",
8585+ },
8686+ degraded_performance: {
8787+ label: "Degraded Performance",
8888+ color: "bg-yellow-500",
8989+ },
9090+ partial_outage: {
9191+ label: "Partial Outage",
9292+ color: "bg-yellow-500",
9393+ },
9494+ major_outage: {
9595+ label: "Major Outage",
9696+ color: "bg-red-500",
9797+ },
9898+ unknown: {
9999+ label: "Unknown",
100100+ color: "bg-gray-500",
101101+ },
102102+ under_maintenance: {
103103+ label: "Under Maintenance",
104104+ color: "bg-gray-500",
105105+ },
106106+} as const;
107107+108108+export async function StatusWidget({ slug }: { slug: string }) {
109109+ const res = await fetch(`https://api.openstatus.dev/public/status/${slug}`, {
110110+ next: { revalidate: 60 }, // cache request for 60 seconds
111111+ });
112112+ const data = await res.json();
113113+ const parsed = statusSchema.safeParse(data);
114114+115115+ let label = "Unknown";
116116+ let color = "bg-gray-500";
117117+118118+ if (parsed.success) {
119119+ const status = dictionary[parsed.data.status];
120120+ label = status.label;
121121+ color = status.color;
122122+ }
123123+124124+ return (
125125+ <a
126126+ className="border-border text-foreground/70 hover:bg-muted hover:text-foreground inline-flex max-w-fit items-center gap-2 rounded-md border px-3 py-1 text-sm"
127127+ href={`https://${slug}.openstatus.dev`}
128128+ target="_blank"
129129+ rel="noreferrer"
130130+ >
131131+ {label}
132132+ <span className={`inline-block h-2 w-2 rounded-full ${color}`} />
133133+ </a>
134134+ );
135135+}
136136+```
···19192020Use the above snippet to try it out.
21212222-Learn more about [all the endpoints](/rest-api/openapi) we provide.
2222+Learn more about [all the endpoints](/api-server/openapi) we provide.
23232424We currently do not have an SDK to make the best out of it. Any contributions
2525are welcome.