API Reference

Account & team

Profile, team management with roles, API keys, support tickets, plan details and a full audit trail.

Profile

MethodEndpointDescription
GET/meCurrent identity and role
PATCH/meUpdate name, avatar, and the panel's persisted UI state (ui_state JSON — per-user view prefs)

Team members

Invite teammates with roles. Roles gate panel sections; API keys map onto the same roles (read ≈ viewer, write ≈ editor for content). Team management itself requires a logged-in user session, not an API key.

MethodEndpointDescription
GET/usersList team members
POST/users/inviteInvite by email — they set their own password
PATCH/users/:uid/roleChange role (owner only)
DELETE/users/:uidRemove from team (owner only)
RoleCan do
ownerEverything, including team and API key management.
adminContent and settings, plus support tickets.
editorContent management (sites, offers, articles…).
viewerRead-only.

API keys

The keys documented on the overview page are manageable from the panel (API Keys page) or by an owner session:

MethodEndpointDescription
GET/api-keysList keys (prefix, name, scope, last used — never the secret)
POST/api-keysCreate — full key returned once
DELETE/api-keys/:kidRevoke instantly (204)
Create a read key (owner JWT session)
curl -X POST $API/api-keys \
  -H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
  -d '{"name":"stats dashboard","scope":"read"}'
# → {"id":"…","key":"vd_live_…","prefix":"vd_live_7f2a…"}  — store "key" NOW, it won't be shown again

We store only a SHA-256 hash of the key. Sessions authenticated with a key cannot manage keys or team members — a leaked key can't escalate.

Support tickets

MethodEndpointDescription
GET/ticketsYour tickets (subject, status, dates)
POST/ticketsOpen one — {"subject", "body"}
GET/tickets/:tidTicket detail with the full message thread
POST/tickets/:tid/messagesReply — {"body"}; notifies our team
PATCH/tickets/:tidSet status — {"status": "closed"} to resolve

Plan

GET /plan returns your current plan and its feature flags — the same flags that gate link health, cloaking, postbacks, comparison tables, media library, lead generation and the audit log. Check it before scripting against gated endpoints; a missing feature returns 403 with the flag name.

Subscription expiry enforcement. The live subscription is the effective source of truth: while it is in period its plan wins, and once current_period_end passes the account falls back to Free limits. The response exposes this via subscription_expired (bool) and expired_plan_name. Existing content keeps serving; creates and gated features return 403 until the subscription is renewed.

Limits. max_sites and max_offers_per_site are hard caps enforced on create (403 with a plan-limit error). The Enterprise plan reports -1 for both, meaning unlimited — treat any negative limit as "no cap".

Audit log

GET /audit-log?limit=200 — who changed what, when: every create/update/delete with the actor (user or API key), the action, and the diff summary. Plan-gated: audit_log. Use it to answer "which integration renamed this offer at 3 AM".