diff --git a/apps/web/src/dashboard/landing.html b/apps/web/src/dashboard/landing.html new file mode 100644 index 0000000..dd342e5 --- /dev/null +++ b/apps/web/src/dashboard/landing.html @@ -0,0 +1,531 @@ + + + + + + PingQL — Uptime monitoring that thinks like a developer + + + + + + + + + + +
+
+
+ +
+
+ + All systems operational +
+

+ Uptime monitoring
that thinks like
a developer
+

+

+ Go beyond simple pings. Write queries against status codes, JSON bodies, HTML selectors, headers, cert expiry — everything your response contains. +

+ +
+ +
+
+
+
+
+
+ query.json +
+
+
{
+  "$and": [
+    { "status": { "$lt": 400 } },
+    { "$json": { "$.latency": { "$lt": 200 } } },
+    { "$certExpiry": { "$gt": 14 } }
+  ]
+}
+
+ // Status < 400 AND latency < 200ms AND cert valid > 14 days +
+
+
+
+
+
+
+ + +
+
+
+

Not just ping

+

+ Most monitoring tools ping a URL and check if it returns 200. That tells you almost nothing. + PingQL lets you query the entire response. +

+
+ + +
+ +
+
Others
+
+
+ + GET /api/health → 200 + UP +
+
+ + GET /api/health → 500 + DOWN +
+
+ That's it. That's all you get. +
+
+
+ + +
+
PingQL
+
+
+ + Status code assertions +
+
+ + JSON body inspection +
+
+ + HTML / CSS selector matching +
+
+ + Response time thresholds +
+
+ + SSL cert expiry checks +
+
+ + Header & regex matching +
+
+
+
+
+
+ + +
+
+
+

Everything you need

+

Powerful primitives, zero bloat.

+
+ +
+ +
+
+ +
+

MongoDB-style queries

+

Use $and, $or, $lt, $gt, $regex — a query language you already know.

+
+ + +
+
+ +
+

CSS selector parsing

+

Monitor any public page with no API. Use $css to extract text from HTML elements.

+
+ + +
+
+ +
+

JSONPath inspection

+

Drill into API responses with $json and JSONPath expressions. Assert on any nested field.

+
+ + +
+
+ +
+

SSL cert monitoring

+

Built-in $certExpiry operator. Get alerted before your cert expires, not after.

+
+ + +
+
+ +
+

Response time assertions

+

Set thresholds on responseTime. Know when your API is slow, not just down.

+
+ + +
+
+ +
+

No-login account keys

+

No email required. Get an account key, start monitoring. Privacy first, always.

+
+
+
+
+ + +
+
+
+
+
+ +
+
+

Privacy by design

+

We built PingQL for developers who care about their data.

+
+
+ +
+
+ $ +
+

No tracking, no analytics, no ads

+

Zero third-party scripts. Zero cookies.

+
+
+
+ $ +
+

Account keys, not passwords

+

Be completely anonymous. No email required.

+
+
+
+ $ +
+

Emails hashed if provided

+

Optional email for recovery only. We hash it.

+
+
+
+ $ +
+

We never sell data

+

Your monitors, your data. Period.

+
+
+
+ +
+ + Hosted in EU (Prague) — GDPR compliant +
+
+
+
+ + +
+
+
+

API-first, always

+

Create monitors, query results, and manage everything from your terminal.

+
+ +
+ +
+
+
+
+
+ Create a monitor +
+
+
$ curl -X POST https://pingql.com/api/monitors \
+  -H "X-Key: XXXX-XXXX-XXXX-XXXX" \
+  -d '{
+    "url": "https://api.example.com/health",
+    "interval": 60,
+    "query": {
+      "status": { "$lt": 400 },
+      "$json": {
+        "$.ok": { "$eq": true }
+      }
+    }
+  }'
+
+// → 201 Created
+{ "id": "mon_a1b2c3", "status": "active" }
+
+
+ + +
+
+
+
+
+ Check results +
+
+
$ curl https://pingql.com/api/monitors/mon_a1b2c3 \
+  -H "X-Key: XXXX-XXXX-XXXX-XXXX"
+
+{
+  "id": "mon_a1b2c3",
+  "url": "https://api.example.com/health",
+  "status": "up",
+  "lastCheck": "2024-01-15T10:30:00Z",
+  "responseTime": 142,
+  "uptime30d": 99.97
+}
+
+
+
+ + +
+
+ + CLI coming soon — pingql watch mon_a1b2c3 +
+
+
+
+ + +
+
+

Simple pricing

+

Start for free. No credit card required.

+ +
+ +
+
Free
+
$0
+
forever
+
    +
  • + + Generous monitor limits +
  • +
  • + + Full query language +
  • +
  • + + API access +
  • +
  • + + No credit card +
  • +
+ + Get Started + +
+ + +
+
+ coming soon +
+
Pro
+
TBD
+
per month
+
    +
  • + + More monitors +
  • +
  • + + Shorter intervals +
  • +
  • + + Webhook notifications +
  • +
  • + + Priority support +
  • +
+
+ Coming Soon +
+
+
+
+
+ + + + + + diff --git a/apps/web/src/index.ts b/apps/web/src/index.ts index f0a2784..a63053d 100644 --- a/apps/web/src/index.ts +++ b/apps/web/src/index.ts @@ -11,7 +11,7 @@ await migrate(); const app = new Elysia() .use(cors()) - .get("/", () => ({ name: "PingQL", version: "0.1.0", docs: "/docs", dashboard: "/dashboard" })) + .get("/", ({ set }) => { set.headers["content-type"] = "text/html"; return Bun.file(`${import.meta.dir}/dashboard/landing.html`); }) .use(dashboard) .use(account) .use(monitors)