Superadmin API
import { Badge } from ‘@astrojs/starlight/components’;
Superadmin API
Section titled “Superadmin API”All superadmin endpoints require the X-Admin-Key header. This is separate from the regular JWT authentication.
X-Admin-Key: {value of SUPER_ADMIN_KEY env var}Demo Requests
Section titled “Demo Requests”GET /api/superadmin/demo-requests
Section titled “GET /api/superadmin/demo-requests”List demo requests from the landing page form.
Query params: status=pending|accepted|rejected|all (default: all)
Response 200:
[ { "id": "uuid", "clinic_name": "Clínica San Salvador", "contact_name": "Juan García", "email": "juan@clinica.com", "phone": "+50377654321", "city": "San Salvador", "doctors_count": 5, "message": "Interested in WhatsApp integration", "status": "pending", "invite_code_id": null, "reviewed_at": null, "created_at": "2026-05-25T00:00:00Z" }]POST /api/superadmin/demo-requests/:id/accept
Section titled “POST /api/superadmin/demo-requests/:id/accept”Accept a demo request and generate a trial invite code.
Request:
{ "expiresInDays": 7}expiresInDays is optional (default 7). The generated invite code has plan trial.
Response 200:
{ "message": "Request accepted", "inviteCode": "ABC123DEF456"}POST /api/superadmin/demo-requests/:id/reject
Section titled “POST /api/superadmin/demo-requests/:id/reject”Reject a demo request.
Response 200: { "message": "Request rejected" }
Invite Codes
Section titled “Invite Codes”GET /api/superadmin/invite-codes
Section titled “GET /api/superadmin/invite-codes”List all invite codes.
Response 200:
[ { "id": "uuid", "code": "ABC123DEF456", "email": null, "plan": "trial", "is_used": false, "used_at": null, "used_by_clinic_id": null, "expires_at": "2026-06-30T00:00:00Z", "source": "manual", "notes": "For Clínica X", "created_at": "2026-05-20T00:00:00Z" }]POST /api/superadmin/invite-codes
Section titled “POST /api/superadmin/invite-codes”Create a new invite code.
Request:
{ "email": "specific@clinic.com", "plan": "pro", "expiresInDays": 30, "notes": "Sent to partner clinic"}All fields optional. Defaults: plan basic, expires in 30 days. Set plan: "forever_free" for permanent access (no expiry).
If email is set, only a user with that email can redeem the code.
Response 201: Invite code object including plaintext code.
PATCH /api/superadmin/invite-codes/:id/revoke
Section titled “PATCH /api/superadmin/invite-codes/:id/revoke”Revoke an unused invite code.
Response 200: { "message": "Code revoked" }
Errors:
| Status | Reason |
|---|---|
409 |
Code is already used |
404 |
Code not found |
Clinics
Section titled “Clinics”GET /api/superadmin/clinics
Section titled “GET /api/superadmin/clinics”List all clinics.
Response 200:
[ { "id": "uuid", "name": "Clínica San Salvador", "slug": "clinica-san-salvador-abc123", "city": "San Salvador", "phone": "+50399999999", "is_active": true, "subscription_plan": "pro", "subscription_expires_at": "2025-12-31T00:00:00Z", "bot_enabled": true, "created_at": "2026-05-01T00:00:00Z", "user_count": 3 }]PATCH /api/superadmin/clinics/:id
Section titled “PATCH /api/superadmin/clinics/:id”Update a clinic’s plan, expiry, or active status.
Request (all optional):
{ "plan": "clinica", "expiresInDays": 365, "is_active": true}plan: changes the subscription plan. Set toforever_freeto grant permanent access.expiresInDays: extends subscription from today. Ignored if plan isforever_free.is_active: deactivate (false) to suspend the clinic.
Response 200: Updated clinic with new plan/expiry.
Statistics
Section titled “Statistics”GET /api/superadmin/stats
Section titled “GET /api/superadmin/stats”Global platform statistics.
Response 200:
{ "totalClinics": 45, "activeClinics": 38, "pendingDemos": 7, "apptToday": 156, "revenueThisMonth": 4250.50, "totalOrders": 62, "planDistribution": { "trial": 20, "basic": 12, "pro": 10, "clinica": 2, "forever_free": 1 }, "recentSignups": 5}recentSignups: clinics registered in the last 7 days.