Skip to content
VibeAdmin

API reference

Everything in the dashboard is available over HTTPS. Authenticate with a scoped key, send users and events, read stats and manage broadcasts. The OpenAPI document is at /v1/openapi.json.

Quickstart

1. Create a project and an API key (API Keys page). 2. Send a user. 3. Send an event. Both appear in the dashboard within seconds.

export VIBEADMIN_API_KEY=adm_test_...

curl -X POST https://www.easy-admin.solutions/v1/users \
  -H "Authorization: Bearer $VIBEADMIN_API_KEY" -H "Content-Type: application/json" \
  -d '{"id":"user_123","email":"ada@example.com","name":"Ada","plan":"pro"}'

curl -X POST https://www.easy-admin.solutions/v1/events \
  -H "Authorization: Bearer $VIBEADMIN_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"workflow.created","userId":"user_123"}'

Prefer to have your coding agent do it? The Get started page generates a prompt for your stack (Next.js, React, Node, Python, Supabase, Firebase).

Authentication

Send Authorization: Bearer <key>. Keys are per environment: adm_test_… for development and preview, adm_live_… for production. A key can only ever see its own environment and only the scopes it was given (users.read, users.write, users.delete, analytics.read, events.write, broadcast.read, broadcast.create, broadcast.send). Keep keys on your server: never ship them in browser code.

REST API

Full machine-readable spec: /v1/openapi.json (OpenAPI 3.1). Users are keyed by your own id; omitted fields stay unchanged, metadata keys merge, and null removes a key.

EndpointWhat it doesScope
GET/v1/usersList usersusers.read
POST/v1/usersCreate or update a userusers.write
POST/v1/users/bulkUpsert up to 500 usersusers.write
GET/v1/users/{id}Get a userusers.read
PATCH/v1/users/{id}Update a userusers.write
DELETE/v1/users/{id}Delete a userusers.delete
POST/v1/users/{id}/suspendSuspend a userusers.write
POST/v1/users/{id}/restoreRestore a suspended userusers.write
GET/v1/broadcastsList broadcastsbroadcast.read
POST/v1/broadcastsCreate a draft broadcastbroadcast.create
GET/v1/broadcasts/{id}Get a broadcastbroadcast.read
POST/v1/broadcasts/{id}/sendSend a draft broadcastbroadcast.send
GET/v1/eventsList eventsanalytics.read
POST/v1/eventsSend eventsevents.write
GET/v1/event-definitionsList discovered event namesanalytics.read
GET/v1/statsHeadline statisticsanalytics.read
POST/v1/webhooks/{id}Inbound webhook—
# list users on the pro plan
curl "https://www.easy-admin.solutions/v1/users?plan=pro&limit=20" -H "Authorization: Bearer $VIBEADMIN_API_KEY"

# bulk upsert (up to 500)
curl -X POST https://www.easy-admin.solutions/v1/users/bulk -H "Authorization: Bearer $VIBEADMIN_API_KEY" \
  -H "Content-Type: application/json" -d '{"users":[{"id":"a","email":"a@x.co"},{"id":"b","email":"b@x.co"}]}'

JavaScript / TypeScript SDK

@vibeadmin/sdk wraps the API with batching, retries and idempotency for events. It has not been published to npm yet; until then, use the REST examples above (the SDK lives in the repo under packages/sdk).

import { AdminClient } from "@vibeadmin/sdk";

const admin = new AdminClient({ apiKey: process.env.VIBEADMIN_API_KEY!, baseUrl: "https://www.easy-admin.solutions" });

await admin.users.upsert({ id: "user_123", email: "ada@example.com", plan: "pro" });
admin.track("workflow.created", { userId: "user_123", properties: { template: "welcome" } });
const stats = await admin.stats();

const draft = await admin.broadcasts.create({ subject: "What's new", html: "<p>Hi {{first_name|there}}</p>", category: "product_updates" });
// a person reviews the recipient count in the dashboard, then:
await admin.broadcasts.send(draft.id, { confirmRecipients: 120 });
await admin.shutdown(); // flushes queued events

Webhooks

Let your backend push changes instead of calling the API: create a webhook under Webhooks to get a URL and a signing secret, then POST user.created / user.updated / user.deleted / payment events to it. Each request must carry X-VibeAdmin-Signature: t=<unix seconds>,v1=<hex hmac-sha256 of "t.body">; requests older than 5 minutes are rejected.

import { createHmac } from "node:crypto";

const body = JSON.stringify({ type: "user.created", data: { id: "user_123", email: "ada@example.com" } });
const t = Math.floor(Date.now() / 1000);
const v1 = createHmac("sha256", process.env.VIBEADMIN_WEBHOOK_SECRET!).update(`${t}.${body}`).digest("hex");

await fetch(WEBHOOK_URL, {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-VibeAdmin-Signature": `t=${t},v1=${v1}` },
  body,
});

Email

Connect your own Resend account under Broadcasts → Email settings. Create drafts via the API or MCP, review the audience in the dashboard, and send. Marketing and product-update emails always include an unsubscribe link and skip people who opted out; security and transactional emails do not. Merge tags: {{first_name|there}} {{name}} {{email}} {{plan}} {{meta.field}}.

Limits & errors

600 requests per minute per key (MCP: 300). Bodies up to 2 MB, bulk up to 500 users. Errors look like {"error":{"code":"invalid_request","message":"…"}} with status 400 (invalid), 401 (bad key), 402 (plan limit reached), 403 (missing scope), 404, 409 (conflict, e.g. a user managed by an integration or a changed audience), 413, 429 (rate limit, see Retry-After).