API v1

Minimal public docs
for the SHAER API.

Everything needed to authenticate, create links, update them, delete them safely, inspect analytics, and manage branded domains.

Authentication

Authenticate every request with a SHAER API key using the `Authorization: Bearer ...` header. Keys are shown once at creation time, stored hash-only, and cannot be retrieved later.

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxx

Create key: POST /api/dashboard/api-keys/create
Revoke key: POST /api/dashboard/api-keys/revoke

Analytics

Fetch lightweight programmable analytics for a single owned link.

GET /api/v1/links/:id/analytics

{
  "clicks": 182,
  "recentActivity": [],
  "topReferrers": [],
  "topDestinations": [],
  "timeline": []
}

Domains

Add, verify, rename, disable, and mark branded routing domains as primary from the dashboard or domain endpoints.

POST /api/domains
PATCH /api/domains/:id
POST /api/domains/verify

Webhooks

Register webhook endpoints to receive `link.clicked`, `link.disabled`, and `link.deleted` events as signed JSON POST payloads. SHAER signs the raw payload with HMAC SHA-256 and sends it in `x-shaer-signature`.

POST /api/webhooks
POST /api/webhooks/revoke
POST /api/webhooks/test
Header: x-shaer-signature

{
  "name": "Production events",
  "url": "https://hooks.example.com/shaer",
  "events": ["link.clicked", "link.disabled"]
}

Verify In Node

Minimal raw-body verification in plain Node.

import { createHmac } from "node:crypto";

const expected = "sha256=" + createHmac("sha256", process.env.SHAER_WEBHOOK_SECRET)
  .update(rawBody)
  .digest("hex");

Verify In Next.js

Minimal verification inside a Route Handler with `await req.text()`.

export async function POST(req: Request) {
  const rawBody = await req.text();
  const signature = req.headers.get("x-shaer-signature");
}

Verify In Express

Minimal verification with `express.raw` so the payload stays untouched.

app.post("/shaer", express.raw({ type: "application/json" }), (req, res) => {
  const rawBody = req.body.toString("utf8");
  const signature = req.get("x-shaer-signature");
});

Errors

SHAER uses straightforward JSON errors with consistent HTTP codes: `401` unauthorized, `403` forbidden, `404` not found, `409` conflict.

{
  "success": false,
  "error": "Forbidden"
}

Rate Limits

API access is reserved for Expert. The public pricing model still defines the underlying distribution ceilings by plan.

FREE   → No API
PRO    → No API
EXPERT → Unlimited records • 1000 req/min