API documentation
Live endpoint today: https://xenqorsystems.com/v1/alerts/ · Bearer API key · JSON
Overview
Xenqor is a B2B incident alerting API. Create an alert with one POST; we store the event, decrement credits, and deliver to your webhooks, email, Telegram, Slack, or Discord when configured.
- HTTPS / HTTP JSON requests
- Auth:
Authorization: Bearer xq_live_… - Event IDs look like
evt_… - Timestamps are ISO-8601 UTC (
created_at)
Register at Create account — your live key appears immediately on the dashboard Overview.
Base URL
This deployment (use in examples below)
https://xenqorsystems.com/v1Local XAMPP
http://localhost/xenqorsystems.com/v1Production API base is the same host: https://xenqorsystems.com/v1 (no separate api. subdomain required).
Authentication
Every request needs your secret key:
Authorization: Bearer xq_live_••••••••- Keys are issued on register and shown under Dashboard → Overview / Settings
- Rotate anytime under Settings or Security (old key stops working immediately)
- Never ship keys in browser bundles or public repos
- Optional: enable IP allowlist under Security — unmatched IPs get
403
Quickstart
- Create an account
- Copy your API key from the dashboard
- Optional: add a webhook URL under Dashboard → Webhooks
- Send
POST /v1/alerts/(examples below) - Confirm the row under Dashboard → Events (retry failed deliveries there)
You can also fire a local alert from Dashboard → Playground without writing code.
POST /v1/alerts
Create an alert, consume one credit, and attempt delivery for the chosen channel.
Headers
Authorization: Bearer …(required)Content-Type: application/jsonIdempotency-Key: …(optional — see below)
Body fields
- service (string, required) — service or component name (max 80)
- severity (string) —
info|warning|critical(defaultwarning) - message (string, required) — summary (max 2,000)
- channel (string) —
webhook(default),email,sms,slack,discord,telegram
When channel is webhook, Xenqor POSTs to every active webhook on your account. Slack/Discord use the URL saved under Channels.
Success response (201)
{
"ok": true,
"id": "evt_a1b2c3d4e5",
"status": "delivered",
"service": "checkout-api",
"severity": "warning",
"channel": "webhook",
"created_at": "2026-08-20T14:32:11+00:00",
"delivery": {
"ok": true,
"status": "delivered",
"results": [
{
"webhook_id": "wh_…",
"url": "https://hooks.example.com/xenqor",
"ok": true,
"status": 200
}
]
}
}
Response headers include credit counters, for example X-Xenqor-Credits-Used and X-Xenqor-Credits-Limit.
GET /v1/events
List recent alerts for the API key’s workspace.
Query
status—all(default) |delivered|failed|retryinglimit— 1–100 (default 50)offset— pagination offset (default 0)
curl "https://xenqorsystems.com/v1/events/?status=failed&limit=20" \
-H "Authorization: Bearer $XENQOR_API_KEY"
Idempotency-Key
On POST /v1/alerts/, send a unique client key (max 256 chars). Replays within 24 hours return the original 201 JSON with header Idempotent-Replayed: true and do not create a second event or consume another credit.
curl https://xenqorsystems.com/v1/alerts/ \
-H "Authorization: Bearer $XENQOR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: deploy-2026-08-20-001" \
-d '{"service":"checkout-api","severity":"warning","message":"Latency spike","channel":"webhook"}'
Webhooks
Manage endpoints in Dashboard → Webhooks: add URL, enable/disable, rotate secret, test ping, delete.
Each delivery is a POST with JSON body:
{
"id": "evt_…",
"type": "alert",
"service": "checkout-api",
"severity": "warning",
"message": "Latency spike",
"channel": "webhook",
"created_at": "2026-08-20T14:32:11+00:00"
}
Headers we send
Content-Type: application/jsonX-Xenqor-Signature: sha256=<hmac>X-Xenqor-Event-Id: evt_…X-Xenqor-Delivery: webhook
Failed deliveries appear as failed / retrying in Events. Use Retry or Retry failed in the dashboard to re-POST.
Verify signatures
Compute HMAC-SHA256 over the raw request body using your webhook signing secret (whsec_…), then compare to the hex digest in X-Xenqor-Signature after the sha256= prefix.
// Node.js
const crypto = require("crypto");
function verify(rawBody, header, secret) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(header || "")
);
}
# PHP
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);
hash_equals($expected, $header);
Channels
- webhook — fan-out to active Webhooks endpoints (signed HTTP)
- email — Resend HTML · destination must be on Verified emails (Channels: send code → confirm)
- slack / discord — POST to your saved webhook URLs
- telegram — Link once in Dashboard → Channels → Telegram (Open bot → Start → Link now), then use
channel: "telegram" - sms — coming soon · Enterprise / Elite plans only
Code examples
curl https://xenqorsystems.com/v1/alerts/ \
-H "Authorization: Bearer $XENQOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"service": "checkout-api",
"severity": "warning",
"message": "Latency spike on checkout",
"channel": "webhook"
}'
const res = await fetch("https://xenqorsystems.com/v1/alerts/", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.XENQOR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
service: "checkout-api",
severity: "warning",
message: "Latency spike on checkout",
channel: "webhook",
}),
});
console.log(await res.json());
import os, requests
r = requests.post(
"https://xenqorsystems.com/v1/alerts/",
headers={"Authorization": f"Bearer {os.environ['XENQOR_API_KEY']}"},
json={
"service": "checkout-api",
"severity": "warning",
"message": "Latency spike on checkout",
"channel": "webhook",
},
)
print(r.status_code, r.json())
$ch = curl_init("https://xenqorsystems.com/v1/alerts/");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("XENQOR_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"service" => "checkout-api",
"severity" => "warning",
"message" => "Latency spike on checkout",
"channel" => "webhook",
]),
]);
echo curl_exec($ch);
Credits & plans
- Each successful create consumes 1 credit from your pool
- Plan limits are shown under Dashboard → Plans. Paid plans are billed by card on pay.xenqorsystems.com. Invoices are still available from billing@
- Credit top-ups open with Stripe Checkout; capacity options also available via billing@
- When the pool is empty, the API returns
402
Rate limits
Burst guidance for clients (also echoed as preview headers in Playground):
X-RateLimit-Limit— soft burst window (e.g. 120)- Respect credits first —
402means top up or upgrade - Enterprise plans can raise limits under a written SLA
Errors
Failures return JSON shaped like:
{ "ok": false, "error": "Service is required." }
- 400 — invalid body (missing service/message, etc.)
- 401 — missing or invalid API key
- 402 — credit limit reached
- 403 — IP not on workspace allowlist
- 405 — method not allowed (use POST)
- 500 — unexpected server error (check Status)
Dashboard tools
- Playground — POST a test alert into Events
- Events — filter, retry failed deliveries, export CSV
- Webhooks / Channels — destinations and secrets
- Audit — security trail + CSV export
- Status — publish component health (also shown on the public Status page)
Roadmap
Paid plans are billed by card on pay.xenqorsystems.com.
- SMS delivery for higher tiers (coming soon)
Use cURL / fetch / any HTTP client against POST /v1/alerts/ — no package registry required.