activity

3 endpoints

GET/api/activity

Activity Tracking API

GET - Get activity feed for a user

POST - Track an activity event

Example
curl -X GET 'https://api.nexxss.com/api/activity' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/activity

Activity Tracking API

GET - Get activity feed for a user

POST - Track an activity event

Example
curl -X POST 'https://api.nexxss.com/api/activity' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/activity/engagement

Activity Engagement Score API

GET - Get engagement score for a user

Example
curl -X GET 'https://api.nexxss.com/api/activity/engagement' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

agents

12 endpoints

GET/api/agents/conversations
Example
curl -X GET 'https://api.nexxss.com/api/agents/conversations' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true"
}
GET/api/agents/conversations/:id
Example
curl -X GET 'https://api.nexxss.com/api/agents/conversations/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/agents/conversations/:id/export
Example
curl -X GET 'https://api.nexxss.com/api/agents/conversations/{id}/export' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/agents/conversations/:id/share
Example
curl -X POST 'https://api.nexxss.com/api/agents/conversations/{id}/share' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "data": "...",
  "token": "...",
  "shareId": "...",
  "shareUrl": "...",
  "expiresAt": "...",
  "allowClone": "..."
}
POST/api/agents/run
Example
curl -X POST 'https://api.nexxss.com/api/agents/run' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/agents/schedules
Example
curl -X GET 'https://api.nexxss.com/api/agents/schedules' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true"
}
POST/api/agents/schedules
Example
curl -X POST 'https://api.nexxss.com/api/agents/schedules' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true"
}
DELETE/api/agents/schedules/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/agents/schedules/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
PATCH/api/agents/schedules/:id
Example
curl -X PATCH 'https://api.nexxss.com/api/agents/schedules/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/agents/share/:token
Example
curl -X GET 'https://api.nexxss.com/api/agents/share/{token}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/agents/share/:token/clone
Example
curl -X POST 'https://api.nexxss.com/api/agents/share/{token}/clone' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "data": "..."
}
DELETE/api/agents/shares/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/agents/shares/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true"
}

ai

5 endpoints

GET/api/ai/image

POST /api/ai/image — generate images through the Vercel AI Gateway.

GET /api/ai/image — list available models and the current auth mode.

Auth: required. Uses the standard session / bearer / internal-secret flow

via `requireAuth` from customer-auth-lite.

Input shape (POST):

{

"prompt": "A futuristic city skyline at dusk",

"model": "bfl/flux-pro-1.1", // optional

"size": "1024x1024", // optional

"n": 1, // 1-4, optional

"seed": 42, // optional

"aspectRatio": "16:9" // optional, ignored if size given

}

Output (POST):

{

"success": true,

"data": {

"model": "bfl/flux-pro-1.1",

"images": [{ "dataUrl": "data:image/png;base64,..." }],

"latencyMs": 2840,

"usedOidc": true

}

}

Example
curl -X GET 'https://api.nexxss.com/api/ai/image' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "...",
  "defaultModel": "...",
  "models": "...",
  "auth": "...",
  "configured": "..."
}
Zod schemas (1)
bodySchema = z.object({
  prompt: z
    .string()
    .trim()
    .min(3, "Prompt must be at least 3 characters")
    .max(4000, "Prompt must be 4000 characters or fewer"),
  // Zod v4 accepts `as const` tuples directly and infers literal types.
  model: z.enum(IMAGE_MODEL_IDS).optional(),
  size: z
    .string()
    .regex(/^\d{3,5}x\d{3,5}$/, "Size must look like 1024x1024")
    .optional(),
  n: z.number().int().min(1).max(4).optional(),
  seed: z.number().int().optional(),
  aspectRatio: z
    .string()
    .regex(/^\d+:\d+$/, "Aspect ratio must look like 16:9")
    .optional(),
POST/api/ai/image

POST /api/ai/image — generate images through the Vercel AI Gateway.

GET /api/ai/image — list available models and the current auth mode.

Auth: required. Uses the standard session / bearer / internal-secret flow

via `requireAuth` from customer-auth-lite.

Input shape (POST):

{

"prompt": "A futuristic city skyline at dusk",

"model": "bfl/flux-pro-1.1", // optional

"size": "1024x1024", // optional

"n": 1, // 1-4, optional

"seed": 42, // optional

"aspectRatio": "16:9" // optional, ignored if size given

}

Output (POST):

{

"success": true,

"data": {

"model": "bfl/flux-pro-1.1",

"images": [{ "dataUrl": "data:image/png;base64,..." }],

"latencyMs": 2840,

"usedOidc": true

}

}

Example
curl -X POST 'https://api.nexxss.com/api/ai/image' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"model":"value","n":0,"seed":0}'
Response
{
  "success": "true",
  "data": "...",
  "defaultModel": "...",
  "models": "...",
  "auth": "...",
  "configured": "..."
}
Zod schemas (1)
bodySchema = z.object({
  prompt: z
    .string()
    .trim()
    .min(3, "Prompt must be at least 3 characters")
    .max(4000, "Prompt must be 4000 characters or fewer"),
  // Zod v4 accepts `as const` tuples directly and infers literal types.
  model: z.enum(IMAGE_MODEL_IDS).optional(),
  size: z
    .string()
    .regex(/^\d{3,5}x\d{3,5}$/, "Size must look like 1024x1024")
    .optional(),
  n: z.number().int().min(1).max(4).optional(),
  seed: z.number().int().optional(),
  aspectRatio: z
    .string()
    .regex(/^\d+:\d+$/, "Aspect ratio must look like 16:9")
    .optional(),
POST/api/ai/optimizations

AI Optimizations API Route

POST - Apply AI cost optimization recommendations

Example
curl -X POST 'https://api.nexxss.com/api/ai/optimizations' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"action":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
optimizationSchema = z.object({
  action: z.enum([
    "downgrade-idle-models",
    "enable-response-caching",
    "optimize-prompts",
  ]),
GET/api/ai/usage

AI Usage & Costs API Route

Returns AI credit usage, model breakdown, and cost data

Example
curl -X GET 'https://api.nexxss.com/api/ai/usage' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/ai/usage/export

AI Usage Export API Route

GET - Export AI usage data as CSV

Example
curl -X GET 'https://api.nexxss.com/api/ai/usage/export' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

analytics

5 endpoints

GET/api/analytics

Analytics Overview API Route

Returns dashboard analytics and KPIs

Example
curl -X GET 'https://api.nexxss.com/api/analytics' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/analytics/advanced/cohorts

Advanced Analytics - Cohort Analysis API

GET - Perform cohort analysis on metrics

Example
curl -X GET 'https://api.nexxss.com/api/analytics/advanced/cohorts' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/analytics/advanced/funnels

Advanced Analytics - Funnel Analysis API

GET - Perform funnel analysis on event steps

Example
curl -X GET 'https://api.nexxss.com/api/analytics/advanced/funnels' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/analytics/channels

Channel Performance Analytics API Route

Returns performance metrics per communication channel

Example
curl -X GET 'https://api.nexxss.com/api/analytics/channels' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

audio

5 endpoints

POST/api/audio/analyze

Audio Analysis API Route

POST - Analyze audio properties

Example
curl -X POST 'https://api.nexxss.com/api/audio/analyze' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"audioUrl":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
analyzeSchema = z.object({
  audioUrl: z.string().url("audioUrl must be a valid URL"),
POST/api/audio/transcribe

Audio Transcription API Route

POST - Transcribe audio from URL

Example
curl -X POST 'https://api.nexxss.com/api/audio/transcribe' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"audioUrl":"string","language":"string","enableDiarization":true,"maxSpeakers":0,"vocabulary":[],"punctuate":true,"profanityFilter":true,"timestamps":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
transcribeSchema = z.object({
  audioUrl: z.string().url("audioUrl must be a valid URL"),
  provider: z
    .enum(["openai", "deepgram", "assemblyai", "google", "aws"] as const)
    .optional(),
  language: z.string().optional(),
  enableDiarization: z.boolean().optional(),
  maxSpeakers: z.number().int().positive().optional(),
  vocabulary: z.array(z.string()).optional(),
  punctuate: z.boolean().optional(),
  profanityFilter: z.boolean().optional(),
  timestamps: z.enum(["word", "segment", "none"]).optional(),
GET/api/audio/transcriptions

Audio Transcriptions Search API Route

GET - Search transcriptions

Example
curl -X GET 'https://api.nexxss.com/api/audio/transcriptions' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/audio/transcriptions/:id

Audio Transcription Detail API Route

GET - Get transcription by ID

Example
curl -X DELETE 'https://api.nexxss.com/api/audio/transcriptions/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/audio/transcriptions/:id

Audio Transcription Detail API Route

GET - Get transcription by ID

Example
curl -X GET 'https://api.nexxss.com/api/audio/transcriptions/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

audit

4 endpoints

GET/api/audit
Example
curl -X GET 'https://api.nexxss.com/api/audit' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/audit/compliance

Audit Compliance Report API

GET - Generate a compliance report for a given framework and date range

Example
curl -X GET 'https://api.nexxss.com/api/audit/compliance' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/audit/logs

Audit Logs API

GET - List audit logs with filters

Example
curl -X GET 'https://api.nexxss.com/api/audit/logs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/audit/logs/export
Example
curl -X GET 'https://api.nexxss.com/api/audit/logs/export' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

auth

23 endpoints

GET/api/auth/callback

OAuth Callback Route

Handles the redirect from Supabase OAuth (Google, etc.)

Exchanges the auth code for a session, upserts the user, and sets the session cookie.

Example
curl -X GET 'https://api.nexxss.com/api/auth/callback' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/auth/callback/facebook

Compatibility alias for Meta OAuth callback URL.

Facebook app settings commonly use /api/auth/callback/facebook while this

codebase handles the flow at /api/auth/facebook/callback.

Example
curl -X GET 'https://api.nexxss.com/api/auth/callback/facebook' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/auth/change-password

Change Password API Route

Allows authenticated users to change their password.

Requires the current password for verification.

Example
curl -X POST 'https://api.nexxss.com/api/auth/change-password' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"currentPassword":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
ChangePasswordSchema = z.object({
  currentPassword: z.string().min(1, "Current password is required"),
  newPassword: z
    .string()
    .min(8, "Password must be at least 8 characters")
    .regex(/[A-Z]/, "Password must contain an uppercase letter")
    .regex(/[a-z]/, "Password must contain a lowercase letter")
    .regex(/\d/, "Password must contain a number")
    .regex(/[!@#$%^&*]/, "Password must contain a special character"),
GET/api/auth/facebook

Facebook + Instagram OAuth init.

Sends the user to Meta's OAuth dialog with the right scopes for Pages,

Page DM messaging, Instagram Business management, and reading public

profile/email. After auth they land on /api/auth/facebook/callback.

Scopes:

- pages_show_list — list pages user manages

- pages_manage_metadata — subscribe pages to webhooks

- pages_messaging — read/send Page Messenger messages

- pages_read_engagement — read comments + reactions on posts

- pages_manage_posts — publish to FB feed

- pages_manage_engagement — moderate comments (hide/delete/reply)

- instagram_basic — read IG Business profile/posts

- instagram_manage_messages — IG Direct DMs

- instagram_manage_comments — IG comment moderation

- instagram_content_publish — publish IG photo posts

- business_management — manage Business assets (optional)

Example
curl -X GET 'https://api.nexxss.com/api/auth/facebook' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/auth/facebook/callback

Facebook OAuth callback.

Exchanges the auth code for a short-lived user token, then for a long-lived

one, then lists the user's managed Pages and persists each one (along with

any linked Instagram Business account) to facebook_pages. Finally subscribes

each Page to webhook events so inbound DMs and comments arrive at our

/api/webhooks/facebook endpoint.

The user must already be authenticated to NEXXSS — we use their session to

scope the connection to their organization. Without auth we redirect to

/login so the connect flow can resume after sign-in.

Example
curl -X GET 'https://api.nexxss.com/api/auth/facebook/callback' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/auth/forgot-password

Forgot Password API Route

Generates a password reset token and stores it in the database.

In production, this would send the reset link via email.

Always returns success to prevent email enumeration attacks.

Example
curl -X POST 'https://api.nexxss.com/api/auth/forgot-password' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"email":"string"}'
Response
{
  "success": "true",
  "message": "..."
}
Zod schemas (1)
ForgotPasswordSchema = z.object({
  email: z.string().email("Invalid email format"),
GET/api/auth/github
Example
curl -X GET 'https://api.nexxss.com/api/auth/github' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/auth/google
Example
curl -X GET 'https://api.nexxss.com/api/auth/google' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/auth/login

Login API Route

Authenticates users with email and password credentials.

Returns a session token on successful authentication.

Falls back to in-memory auth in development when Supabase is unavailable.

Example
curl -X POST 'https://api.nexxss.com/api/auth/login' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"email":"string","password":"string","remember":true}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
LoginSchema = z.object({
  email: z.string().email("Invalid email format"),
  password: z.string().min(1, "Password is required"),
  remember: z.boolean().optional().default(false),
POST/api/auth/logout

Logout API Route

Clears the session cookie and revokes the session token in Redis.

Example
curl -X POST 'https://api.nexxss.com/api/auth/logout' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true"
}
POST/api/auth/magic-link

Magic Link API Route

Sends a passwordless sign-in email via Supabase Auth (signInWithOtp).

Reduces signup/login friction to a single field — perfect plug-and-play

entry. The user clicks the link in their inbox and lands on the OAuth

callback (/api/auth/callback) which exchanges the code for a Supabase

session and provisions our app session.

Rate-limited per IP (5/hour) to prevent abuse, mirroring the registration

route's stance.

Example
curl -X POST 'https://api.nexxss.com/api/auth/magic-link' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"email":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
MagicLinkSchema = z.object({
  email: z.string().email("Invalid email format"),
POST/api/auth/mfa-verify

MFA Login Verification API Route

Completes the login flow for users with MFA enabled.

Accepts the temporary MFA pending token from /api/auth/login and the TOTP code.

Issues a full session cookie upon successful MFA verification.

SECURITY: This endpoint does NOT require full auth - it verifies the MFA pending token

which was issued after successful password verification.

Example
curl -X POST 'https://api.nexxss.com/api/auth/mfa-verify' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/auth/oidc/:idpId/callback

GET /api/auth/oidc/[idpId]/callback?code=...&state=...

Handles the IdP redirect-back. Validates state, exchanges the code for

tokens, fetches userinfo, calls linkOrCreateUser to materialize the app

user, and mints a one-time SSO handoff token. Then 302s the browser to

/login/sso/complete?handoff=<token>, which finalizes the NextAuth session.

Example
curl -X GET 'https://api.nexxss.com/api/auth/oidc/{idpId}/callback' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/auth/oidc/:idpId/initiate

GET /api/auth/oidc/[idpId]/initiate?returnTo=/dashboard

Starts the OIDC sign-in flow:

- Generates PKCE + state + nonce

- Stashes them in Redis keyed by state

- 302s to the IdP's authorization URL

No auth required (this IS the auth flow). `returnTo` is captured so the

callback can land the user back where they came from.

Example
curl -X GET 'https://api.nexxss.com/api/auth/oidc/{idpId}/initiate' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/auth/register

Registration API Route

Creates a new organization and owner user.

Protected by rate limiting to prevent abuse.

Example
curl -X POST 'https://api.nexxss.com/api/auth/register' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","email":"string","organizationName":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
RegisterSchema = z.object({
  name: z.string().min(2, "Name is required"),
  email: z.string().email("Invalid email format"),
  password: z
    .string()
    .min(8, "Password must be at least 8 characters")
    .regex(/[A-Z]/, "Password must contain an uppercase letter")
    .regex(/[a-z]/, "Password must contain a lowercase letter")
    .regex(/\d/, "Password must contain a number")
    .regex(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/, "Password must contain a special character"),
  organizationName: z.string().min(2, "Organization name is required"),
POST/api/auth/reset-password

Reset Password API Route

Consumes a password reset token and updates the user's password.

Tokens are single-use and expire after 1 hour.

Example
curl -X POST 'https://api.nexxss.com/api/auth/reset-password' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"token":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
ResetPasswordSchema = z.object({
  token: z.string().min(1, "Reset token is required"),
  password: z
    .string()
    .min(8, "Password must be at least 8 characters")
    .regex(/[A-Z]/, "Password must contain an uppercase letter")
    .regex(/[a-z]/, "Password must contain a lowercase letter")
    .regex(/\d/, "Password must contain a number")
    .regex(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/, "Password must contain a special character"),
POST/api/auth/saml/:idpId/acs

POST /api/auth/saml/[idpId]/acs

SAML Assertion Consumer Service. Accepts a base64-encoded SAMLResponse via

form-urlencoded POST (per the HTTP-POST binding). Validates the signature

against the IdP's stored x509Cert, extracts the assertion, materializes the

app user, mints a handoff token, and 302s to /login/sso/complete.

Example
curl -X POST 'https://api.nexxss.com/api/auth/saml/{idpId}/acs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/auth/saml/:idpId/initiate

GET /api/auth/saml/[idpId]/initiate?returnTo=/dashboard

Builds an AuthnRequest and 302s the browser to the IdP's SSO endpoint

(HTTP-Redirect binding).

Example
curl -X GET 'https://api.nexxss.com/api/auth/saml/{idpId}/initiate' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/auth/saml/:idpId/metadata

GET /api/auth/saml/[idpId]/metadata

Returns the SP metadata XML that an admin uploads into their IdP. The

EntityID/ACS URLs are derived from the request origin so this works in

preview deployments without per-env config.

Example
curl -X GET 'https://api.nexxss.com/api/auth/saml/{idpId}/metadata' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/auth/session

Session API Route

Returns the current authenticated user's session data.

Used by the AuthProvider to hydrate client-side auth state.

Example
curl -X GET 'https://api.nexxss.com/api/auth/session' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/auth/signup
Example
curl -X POST 'https://api.nexxss.com/api/auth/signup' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","email":"string","password":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
SignupSchema = z.object({
  name: z.string().min(1, "Name is required"),
  email: z.string().email("Invalid email"),
  password: z.string().min(8, "Password must be at least 8 characters"),
POST/api/auth/sso/discover

POST /api/auth/sso/discover

Body: { email: string, returnTo?: string }

Returns { redirect: "/api/auth/(oidc|saml)/[idpId]/initiate?..." } when an

IdP is configured for the email's domain; { found: false } otherwise.

The /login/sso page uses this to choose between SSO and password sign-in.

Example
curl -X POST 'https://api.nexxss.com/api/auth/sso/discover' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/auth/verify-email

Email Verification API Route

Consumes an email verification token and marks the user as verified.

Tokens are single-use and expire after 24 hours.

Example
curl -X POST 'https://api.nexxss.com/api/auth/verify-email' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"token":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
VerifyEmailSchema = z.object({
  token: z.string().min(1, "Verification token is required"),

bi

3 endpoints

GET/api/bi/dashboard

Business Intelligence KPI Dashboard API

GET - Get the executive KPI dashboard

Example
curl -X GET 'https://api.nexxss.com/api/bi/dashboard' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/bi/reports

Business Intelligence Reports API

GET - List BI reports for the organization

POST - Create/generate a new BI report

Example
curl -X GET 'https://api.nexxss.com/api/bi/reports' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/bi/reports

Business Intelligence Reports API

GET - List BI reports for the organization

POST - Create/generate a new BI report

Example
curl -X POST 'https://api.nexxss.com/api/bi/reports' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

billing

7 endpoints

POST/api/billing/checkout

POST /api/billing/checkout

Tier-aware Stripe Checkout entrypoint. Caller posts { plan } where plan

is one of 'starter' | 'pro' | 'enterprise'. We resolve the corresponding

Stripe Price ID from env, create a subscription Checkout Session, and

persist the resulting Stripe customer ID on the organization so the

billing portal + webhook can correlate later.

Builds on top of the existing /api/stripe/checkout helper (general-purpose)

but offers a simple, plan-driven surface for the upgrade UI.

Required env:

STRIPE_SECRET_KEY

STRIPE_PRICE_STARTER, STRIPE_PRICE_PRO, STRIPE_PRICE_ENTERPRISE

NEXT_PUBLIC_APP_URL (for success/cancel redirects)

Example
curl -X POST 'https://api.nexxss.com/api/billing/checkout' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"plan":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
bodySchema = z.object({
  plan: z.enum(["starter", "pro", "enterprise"]),
GET/api/billing/history

Billing History API Route

Returns billing transaction history for the authenticated user's organization.

Requires authentication and analytics:read permission.

Example
curl -X GET 'https://api.nexxss.com/api/billing/history' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/billing/invoices

GET /api/billing/invoices

Returns the most recent invoices (default 5) for the org's Stripe customer.

Used by /dashboard/settings/billing — separate from the legacy

/api/billing/history (which reads our internal billing_transactions table)

so the UI can show real-time Stripe invoice state including the hosted

invoice URL and PDF link for download.

Example
curl -X GET 'https://api.nexxss.com/api/billing/invoices' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/billing/portal

POST /api/billing/portal

Creates a Stripe billing-portal session for the current org's customer

and returns the redirect URL. Lets users self-serve subscription management

(update card, change plan, view invoices, cancel) without us building a

full billing UI.

Example
curl -X POST 'https://api.nexxss.com/api/billing/portal' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/billing/price-id

GET /api/billing/price-id?tier=starter|pro|enterprise

Resolves a Stripe Price ID for the requested tier from environment

variables. Returns null when not configured so the upgrade-prompt

provider can fall back to ad-hoc price_data Checkout sessions.

Configure these env vars in Vercel for production:

STRIPE_PRICE_STARTER_MONTHLY

STRIPE_PRICE_PRO_MONTHLY

STRIPE_PRICE_ENTERPRISE_MONTHLY (optional — usually contact-sales)

Example
curl -X GET 'https://api.nexxss.com/api/billing/price-id' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string",
  "priceId": "..."
}
GET/api/billing/status

GET /api/billing/status

Returns the org's current subscription tier, trial countdown, AI-credit

usage, and tier limits. Used by the dashboard's trial banner and any

upgrade-prompt UI surfaces.

Example
curl -X GET 'https://api.nexxss.com/api/billing/status' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/billing/webhook

POST /api/billing/webhook

Plan-aware Stripe webhook handler that mirrors subscription state onto

the `organizations` row (subscription_tier, subscription_status,

stripe_customer_id, stripe_subscription_id). Idempotent — uses

event.id as a dedup key via the shared webhook_events table.

Coexists with /api/webhooks/stripe (which maintains the legacy

subscriptions + invoices tables); this one is the source of truth for

org-level plan + status used by feature gating.

Required env: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET

Configure in Stripe dashboard:

https://your-domain.com/api/billing/webhook

Events: checkout.session.completed, customer.subscription.updated,

customer.subscription.deleted, invoice.paid, invoice.payment_failed

Example
curl -X POST 'https://api.nexxss.com/api/billing/webhook' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

campaigns

6 endpoints

GET/api/campaigns

Campaigns API Routes

REST endpoints for campaign management

Example
curl -X GET 'https://api.nexxss.com/api/campaigns' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/campaigns

Campaigns API Routes

REST endpoints for campaign management

Example
curl -X POST 'https://api.nexxss.com/api/campaigns' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/campaigns/:id

Campaign Detail API Routes

GET, PUT, DELETE for individual campaigns

Example
curl -X DELETE 'https://api.nexxss.com/api/campaigns/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/campaigns/:id

Campaign Detail API Routes

GET, PUT, DELETE for individual campaigns

Example
curl -X GET 'https://api.nexxss.com/api/campaigns/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PUT/api/campaigns/:id

Campaign Detail API Routes

GET, PUT, DELETE for individual campaigns

Example
curl -X PUT 'https://api.nexxss.com/api/campaigns/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/campaigns/:id/report

Campaign Report API Route

GET - Fetch campaign metrics/report (JSON or CSV)

Example
curl -X GET 'https://api.nexxss.com/api/campaigns/{id}/report' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

cdn

2 endpoints

GET/api/cdn/assets

CDN Assets API

GET - List CDN assets

Example
curl -X GET 'https://api.nexxss.com/api/cdn/assets' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/cdn/purge

CDN Cache Purge API

POST - Purge CDN cache by URLs, tags, or all

Example
curl -X POST 'https://api.nexxss.com/api/cdn/purge' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

channels

3 endpoints

POST/api/channels/connect

POST /api/channels/connect

Unified channel-connect endpoint used by the inline onboarding wizards (P1).

Each channel has its own per-tenant credential table; this route routes

the request to the right one based on `channel`.

Body:

{ channel: "whatsapp" | "telegram" | "discord" | "sms" | "email" | "voice",

credentials: <channel-specific shape> }

Returns:

{ success: true, data: { channelId, validated } }

The `validated` flag indicates whether we successfully called the provider's

API to confirm the credentials work (e.g. Telegram getMe). For some channels

we just persist what the user pasted and validate on first use.

Example
curl -X POST 'https://api.nexxss.com/api/channels/connect' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"channel":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
ConnectSchema = z.object({
  channel: z.enum([
    "whatsapp",
    "telegram",
    "discord",
    "sms",
    "email",
    "voice",
  ]),
  credentials: z.record(z.string(), z.unknown()),
POST/api/channels/email

Email Channel API Route

Send emails through the organization's configured provider

Example
curl -X POST 'https://api.nexxss.com/api/channels/email' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"to":"string","subject":"string","body":"string","html":true,"replyTo":"string","cc":[],"bcc":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
SendEmailSchema = z.object({
      to: z.string().email("Invalid recipient email"),
      subject: z.string().min(1).max(500),
      body: z.string().min(1).max(100000),
      html: z.boolean().optional().default(false),
      replyTo: z.string().email().optional(),
      cc: z.array(z.string().email()).optional(),
      bcc: z.array(z.string().email()).optional(),
POST/api/channels/sms

SMS Channel API Route

Send SMS messages through the messaging platform via Twilio

Example
curl -X POST 'https://api.nexxss.com/api/channels/sms' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"to":"string","content":"string","mediaUrls":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
SendSMSSchema = z.object({
      to: z.string().regex(/^\+[1-9]\d{1,14}$/, "Invalid phone number format (E.164)"),
      content: z.string().min(1).max(1600),
      from: z
        .string()
        .regex(/^\+[1-9]\d{1,14}$/)
        .optional(),
      mediaUrls: z.array(z.string().url()).optional(),

cloud-agents

22 endpoints

GET/api/cloud-agents

Cloud Agents API - Main Route

GET /api/cloud-agents - Get cloud agent runs list

POST /api/cloud-agents - Create a new cloud agent run

Example
curl -X GET 'https://api.nexxss.com/api/cloud-agents' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateRunSchema = z.object({
  configId: z.string().uuid(),
  task: z.string().min(1).max(10000),
  model: z
    .enum([
      "claude-opus-4-5",
      "claude-sonnet-4",
      "gpt-4o",
      "gpt-4-turbo",
      "gemini-2.5-flash",
      "mistral-large",
    ])
    .optional(),
  priority: z.enum(["low", "normal", "high", "urgent"]).optional(),
  branch: z.string().optional(),
  // Note: baseBranch is accepted but not currently used in run creation
  // It's included for future implementation of base branch selection
  baseBranch: z.string().optional(),
POST/api/cloud-agents

Cloud Agents API - Main Route

GET /api/cloud-agents - Get cloud agent runs list

POST /api/cloud-agents - Create a new cloud agent run

Example
curl -X POST 'https://api.nexxss.com/api/cloud-agents' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"configId":"string","task":"string","priority":"value","branch":"string","baseBranch":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateRunSchema = z.object({
  configId: z.string().uuid(),
  task: z.string().min(1).max(10000),
  model: z
    .enum([
      "claude-opus-4-5",
      "claude-sonnet-4",
      "gpt-4o",
      "gpt-4-turbo",
      "gemini-2.5-flash",
      "mistral-large",
    ])
    .optional(),
  priority: z.enum(["low", "normal", "high", "urgent"]).optional(),
  branch: z.string().optional(),
  // Note: baseBranch is accepted but not currently used in run creation
  // It's included for future implementation of base branch selection
  baseBranch: z.string().optional(),
GET/api/cloud-agents/configs

Cloud Agents API - Configurations Route

GET /api/cloud-agents/configs - List configurations

POST /api/cloud-agents/configs - Create configuration

Example
curl -X GET 'https://api.nexxss.com/api/cloud-agents/configs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
TerminalConfigSchema = z.object({
  name: z.string(),
  command: z.string(),
  workingDirectory: z.string().optional(),
  env: z.record(z.string(), z.string()).optional(),
CreateConfigSchema = z.object({
  name: z.string().min(1).max(100),
  description: z.string().max(500).optional(),
  isDefault: z.boolean().optional().default(false),
  repository: z.object({
    provider: z.enum(["github", "gitlab", "bitbucket"]),
    owner: z.string(),
    name: z.string(),
    fullPath: z.string(),
    defaultBranch: z.string().optional().default("main"),
    baseBranch: z.string().optional(),
    cloneUrl: z.string().url(),
    hasWriteAccess: z.boolean().optional().default(true),
  }),
  environment: z.object({
    snapshot: z.string().optional(),
    install: z.string().optional(),
    start: z.string().optional(),
    terminals: z.array(TerminalConfigSchema).optional().default([]),
    dockerfile: z.string().optional(),
    resources: z
      .object({
        cpu: z.number().min(1).max
POST/api/cloud-agents/configs

Cloud Agents API - Configurations Route

GET /api/cloud-agents/configs - List configurations

POST /api/cloud-agents/configs - Create configuration

Example
curl -X POST 'https://api.nexxss.com/api/cloud-agents/configs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","command":"string","workingDirectory":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
TerminalConfigSchema = z.object({
  name: z.string(),
  command: z.string(),
  workingDirectory: z.string().optional(),
  env: z.record(z.string(), z.string()).optional(),
CreateConfigSchema = z.object({
  name: z.string().min(1).max(100),
  description: z.string().max(500).optional(),
  isDefault: z.boolean().optional().default(false),
  repository: z.object({
    provider: z.enum(["github", "gitlab", "bitbucket"]),
    owner: z.string(),
    name: z.string(),
    fullPath: z.string(),
    defaultBranch: z.string().optional().default("main"),
    baseBranch: z.string().optional(),
    cloneUrl: z.string().url(),
    hasWriteAccess: z.boolean().optional().default(true),
  }),
  environment: z.object({
    snapshot: z.string().optional(),
    install: z.string().optional(),
    start: z.string().optional(),
    terminals: z.array(TerminalConfigSchema).optional().default([]),
    dockerfile: z.string().optional(),
    resources: z
      .object({
        cpu: z.number().min(1).max
DELETE/api/cloud-agents/configs/:configId

Cloud Agents API - Individual Configuration Route

GET /api/cloud-agents/configs/[configId] - Get configuration

PATCH /api/cloud-agents/configs/[configId] - Update configuration

DELETE /api/cloud-agents/configs/[configId] - Delete configuration

Example
curl -X DELETE 'https://api.nexxss.com/api/cloud-agents/configs/{configId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","command":"string","workingDirectory":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
TerminalConfigSchema = z.object({
  name: z.string(),
  command: z.string(),
  workingDirectory: z.string().optional(),
  env: z.record(z.string(), z.string()).optional(),
UpdateConfigSchema = z.object({
  name: z.string().min(1).max(100).optional(),
  description: z.string().max(500).optional(),
  isDefault: z.boolean().optional(),
  repository: z
    .object({
      defaultBranch: z.string().optional(),
      baseBranch: z.string().optional(),
    })
    .optional(),
  environment: z
    .object({
      snapshot: z.string().optional(),
      install: z.string().optional(),
      start: z.string().optional(),
      terminals: z.array(TerminalConfigSchema).optional(),
      dockerfile: z.string().optional(),
      resources: z
        .object({
          cpu: z.number().min(1).max(16).optional(),
          memoryGb: z.number().min(1).max(64).optional(),
          diskGb: z.number().min(10).max(500).optional(),
          gpuType: z.enum(["none", "t4", "a100"]).optional(),
       
GET/api/cloud-agents/configs/:configId

Cloud Agents API - Individual Configuration Route

GET /api/cloud-agents/configs/[configId] - Get configuration

PATCH /api/cloud-agents/configs/[configId] - Update configuration

DELETE /api/cloud-agents/configs/[configId] - Delete configuration

Example
curl -X GET 'https://api.nexxss.com/api/cloud-agents/configs/{configId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
TerminalConfigSchema = z.object({
  name: z.string(),
  command: z.string(),
  workingDirectory: z.string().optional(),
  env: z.record(z.string(), z.string()).optional(),
UpdateConfigSchema = z.object({
  name: z.string().min(1).max(100).optional(),
  description: z.string().max(500).optional(),
  isDefault: z.boolean().optional(),
  repository: z
    .object({
      defaultBranch: z.string().optional(),
      baseBranch: z.string().optional(),
    })
    .optional(),
  environment: z
    .object({
      snapshot: z.string().optional(),
      install: z.string().optional(),
      start: z.string().optional(),
      terminals: z.array(TerminalConfigSchema).optional(),
      dockerfile: z.string().optional(),
      resources: z
        .object({
          cpu: z.number().min(1).max(16).optional(),
          memoryGb: z.number().min(1).max(64).optional(),
          diskGb: z.number().min(10).max(500).optional(),
          gpuType: z.enum(["none", "t4", "a100"]).optional(),
       
PATCH/api/cloud-agents/configs/:configId

Cloud Agents API - Individual Configuration Route

GET /api/cloud-agents/configs/[configId] - Get configuration

PATCH /api/cloud-agents/configs/[configId] - Update configuration

DELETE /api/cloud-agents/configs/[configId] - Delete configuration

Example
curl -X PATCH 'https://api.nexxss.com/api/cloud-agents/configs/{configId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","command":"string","workingDirectory":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
TerminalConfigSchema = z.object({
  name: z.string(),
  command: z.string(),
  workingDirectory: z.string().optional(),
  env: z.record(z.string(), z.string()).optional(),
UpdateConfigSchema = z.object({
  name: z.string().min(1).max(100).optional(),
  description: z.string().max(500).optional(),
  isDefault: z.boolean().optional(),
  repository: z
    .object({
      defaultBranch: z.string().optional(),
      baseBranch: z.string().optional(),
    })
    .optional(),
  environment: z
    .object({
      snapshot: z.string().optional(),
      install: z.string().optional(),
      start: z.string().optional(),
      terminals: z.array(TerminalConfigSchema).optional(),
      dockerfile: z.string().optional(),
      resources: z
        .object({
          cpu: z.number().min(1).max(16).optional(),
          memoryGb: z.number().min(1).max(64).optional(),
          diskGb: z.number().min(10).max(500).optional(),
          gpuType: z.enum(["none", "t4", "a100"]).optional(),
       
DELETE/api/cloud-agents/delete-all

Cloud Agents Delete All API Route

DELETE /api/cloud-agents/delete-all - Delete all cloud agent data for an organization

SECURITY: This is a destructive operation protected by:

- Authentication (requireAuth)

- CSRF protection (withCSRFProtection)

- Audit logging

Example
curl -X DELETE 'https://api.nexxss.com/api/cloud-agents/delete-all' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/cloud-agents/runs/:runId

Cloud Agents API - Individual Run Route

GET /api/cloud-agents/runs/[runId] - Get run details

PATCH /api/cloud-agents/runs/[runId] - Update run (cancel, send input)

DELETE /api/cloud-agents/runs/[runId] - Cancel run

Example
curl -X DELETE 'https://api.nexxss.com/api/cloud-agents/runs/{runId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"action":"value","message":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateRunSchema = z.object({
  action: z.enum(["cancel", "pause", "resume", "send_input"]),
  message: z.string().optional(),
GET/api/cloud-agents/runs/:runId

Cloud Agents API - Individual Run Route

GET /api/cloud-agents/runs/[runId] - Get run details

PATCH /api/cloud-agents/runs/[runId] - Update run (cancel, send input)

DELETE /api/cloud-agents/runs/[runId] - Cancel run

Example
curl -X GET 'https://api.nexxss.com/api/cloud-agents/runs/{runId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateRunSchema = z.object({
  action: z.enum(["cancel", "pause", "resume", "send_input"]),
  message: z.string().optional(),
PATCH/api/cloud-agents/runs/:runId

Cloud Agents API - Individual Run Route

GET /api/cloud-agents/runs/[runId] - Get run details

PATCH /api/cloud-agents/runs/[runId] - Update run (cancel, send input)

DELETE /api/cloud-agents/runs/[runId] - Cancel run

Example
curl -X PATCH 'https://api.nexxss.com/api/cloud-agents/runs/{runId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"action":"value","message":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateRunSchema = z.object({
  action: z.enum(["cancel", "pause", "resume", "send_input"]),
  message: z.string().optional(),
DELETE/api/cloud-agents/secrets

Cloud Agents API - Secrets Route

GET /api/cloud-agents/secrets - List secrets (without values)

POST /api/cloud-agents/secrets - Create or update a secret

DELETE /api/cloud-agents/secrets - Delete a secret

SECURITY: Rate limited to prevent brute-force attacks on secret management.

Example
curl -X DELETE 'https://api.nexxss.com/api/cloud-agents/secrets' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"value":"string","description":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
UpsertSecretSchema = z.object({
  key: z
    .string()
    .min(1)
    .max(100)
    .regex(/^[A-Z_][A-Z0-9_]*$/, {
      message: "Key must be uppercase with underscores (e.g., MY_SECRET_KEY)",
    }),
  value: z.string().min(1).max(10000),
  description: z.string().max(500).optional(),
DeleteSecretSchema = z.object({
  key: z.string().min(1).max(100),
GET/api/cloud-agents/secrets

Cloud Agents API - Secrets Route

GET /api/cloud-agents/secrets - List secrets (without values)

POST /api/cloud-agents/secrets - Create or update a secret

DELETE /api/cloud-agents/secrets - Delete a secret

SECURITY: Rate limited to prevent brute-force attacks on secret management.

Example
curl -X GET 'https://api.nexxss.com/api/cloud-agents/secrets' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
UpsertSecretSchema = z.object({
  key: z
    .string()
    .min(1)
    .max(100)
    .regex(/^[A-Z_][A-Z0-9_]*$/, {
      message: "Key must be uppercase with underscores (e.g., MY_SECRET_KEY)",
    }),
  value: z.string().min(1).max(10000),
  description: z.string().max(500).optional(),
DeleteSecretSchema = z.object({
  key: z.string().min(1).max(100),
POST/api/cloud-agents/secrets

Cloud Agents API - Secrets Route

GET /api/cloud-agents/secrets - List secrets (without values)

POST /api/cloud-agents/secrets - Create or update a secret

DELETE /api/cloud-agents/secrets - Delete a secret

SECURITY: Rate limited to prevent brute-force attacks on secret management.

Example
curl -X POST 'https://api.nexxss.com/api/cloud-agents/secrets' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"value":"string","description":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
UpsertSecretSchema = z.object({
  key: z
    .string()
    .min(1)
    .max(100)
    .regex(/^[A-Z_][A-Z0-9_]*$/, {
      message: "Key must be uppercase with underscores (e.g., MY_SECRET_KEY)",
    }),
  value: z.string().min(1).max(10000),
  description: z.string().max(500).optional(),
DeleteSecretSchema = z.object({
  key: z.string().min(1).max(100),
DELETE/api/cloud-agents/secrets/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/cloud-agents/secrets/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/cloud-agents/settings

Cloud Agents API - Settings Route

GET /api/cloud-agents/settings - Get workspace settings

PATCH /api/cloud-agents/settings - Update workspace settings

Example
curl -X GET 'https://api.nexxss.com/api/cloud-agents/settings' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateSettingsSchema = z.object({
  defaultModel: z
    .enum([
      "claude-opus-4-5",
      "claude-sonnet-4",
      "gpt-4o",
      "gpt-4-turbo",
      "gemini-2.5-flash",
      "mistral-large",
    ])
    .optional(),
  defaultRepository: z.string().optional(),
  baseBranch: z.string().optional(),
  autoFixCI: z.boolean().optional(),
  displayAgentSummary: z.boolean().optional(),
  displaySummaryExternally: z.boolean().optional(),
PATCH/api/cloud-agents/settings

Cloud Agents API - Settings Route

GET /api/cloud-agents/settings - Get workspace settings

PATCH /api/cloud-agents/settings - Update workspace settings

Example
curl -X PATCH 'https://api.nexxss.com/api/cloud-agents/settings' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"defaultRepository":"string","baseBranch":"string","autoFixCI":true,"displayAgentSummary":true,"displaySummaryExternally":true}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateSettingsSchema = z.object({
  defaultModel: z
    .enum([
      "claude-opus-4-5",
      "claude-sonnet-4",
      "gpt-4o",
      "gpt-4-turbo",
      "gemini-2.5-flash",
      "mistral-large",
    ])
    .optional(),
  defaultRepository: z.string().optional(),
  baseBranch: z.string().optional(),
  autoFixCI: z.boolean().optional(),
  displayAgentSummary: z.boolean().optional(),
  displaySummaryExternally: z.boolean().optional(),
DELETE/api/cloud-agents/snapshots

Cloud Agents API - Snapshots Route

GET /api/cloud-agents/snapshots - List snapshots

POST /api/cloud-agents/snapshots - Create a snapshot

DELETE /api/cloud-agents/snapshots - Delete a snapshot

Example
curl -X DELETE 'https://api.nexxss.com/api/cloud-agents/snapshots' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","description":"string","baseImage":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
CreateSnapshotSchema = z.object({
  name: z.string().min(1).max(100),
  description: z.string().max(500).optional(),
  baseImage: z.string().min(1).max(200),
DeleteSnapshotSchema = z.object({
  snapshotId: z.string().uuid(),
GET/api/cloud-agents/snapshots

Cloud Agents API - Snapshots Route

GET /api/cloud-agents/snapshots - List snapshots

POST /api/cloud-agents/snapshots - Create a snapshot

DELETE /api/cloud-agents/snapshots - Delete a snapshot

Example
curl -X GET 'https://api.nexxss.com/api/cloud-agents/snapshots' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
CreateSnapshotSchema = z.object({
  name: z.string().min(1).max(100),
  description: z.string().max(500).optional(),
  baseImage: z.string().min(1).max(200),
DeleteSnapshotSchema = z.object({
  snapshotId: z.string().uuid(),
POST/api/cloud-agents/snapshots

Cloud Agents API - Snapshots Route

GET /api/cloud-agents/snapshots - List snapshots

POST /api/cloud-agents/snapshots - Create a snapshot

DELETE /api/cloud-agents/snapshots - Delete a snapshot

Example
curl -X POST 'https://api.nexxss.com/api/cloud-agents/snapshots' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","description":"string","baseImage":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
CreateSnapshotSchema = z.object({
  name: z.string().min(1).max(100),
  description: z.string().max(500).optional(),
  baseImage: z.string().min(1).max(200),
DeleteSnapshotSchema = z.object({
  snapshotId: z.string().uuid(),
DELETE/api/cloud-agents/snapshots/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/cloud-agents/snapshots/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/cloud-agents/snapshots/:id/restore
Example
curl -X POST 'https://api.nexxss.com/api/cloud-agents/snapshots/{id}/restore' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

contact

1 endpoint

POST/api/contact

Contact Form API Route

Receives public contact form submissions and logs them.

Rate limited to prevent spam.

Example
curl -X POST 'https://api.nexxss.com/api/contact' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"firstName":"string","lastName":"string","email":"string","company":"string","subject":"string","message":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
contactSchema = z.object({
  firstName: z.string().min(1).max(100),
  lastName: z.string().min(1).max(100),
  email: z.string().email().max(255),
  company: z.string().max(200).optional(),
  subject: z.string().max(100).optional(),
  message: z.string().min(1).max(5000),

conversations

10 endpoints

GET/api/conversations

Conversations API Routes

REST endpoints for conversation management (unified inbox)

Example
curl -X GET 'https://api.nexxss.com/api/conversations' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateConversationSchema = z.object({
  customer_id: z.string().uuid(),
  customer_name: z.string().max(255).optional(),
  customer_email: z.string().email().optional(),
  channel: z.enum(["web", "whatsapp", "sms", "email", "telegram", "discord"]),
  status: z
    .enum(["active", "waiting", "resolved", "closed"])
    .optional()
    .default("active"),
  priority: z.enum(["low", "medium", "high"]).optional().default("medium"),
  tags: z.array(z.string().max(50)).optional(),
  metadata: z.record(z.string(), z.unknown()).optional(),
POST/api/conversations

Conversations API Routes

REST endpoints for conversation management (unified inbox)

Example
curl -X POST 'https://api.nexxss.com/api/conversations' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"customer_id":"string","customer_name":"string","customer_email":"string","channel":"value","priority":"value","tags":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateConversationSchema = z.object({
  customer_id: z.string().uuid(),
  customer_name: z.string().max(255).optional(),
  customer_email: z.string().email().optional(),
  channel: z.enum(["web", "whatsapp", "sms", "email", "telegram", "discord"]),
  status: z
    .enum(["active", "waiting", "resolved", "closed"])
    .optional()
    .default("active"),
  priority: z.enum(["low", "medium", "high"]).optional().default("medium"),
  tags: z.array(z.string().max(50)).optional(),
  metadata: z.record(z.string(), z.unknown()).optional(),
DELETE/api/conversations/:id

Conversation Detail API Routes

GET individual conversation, PUT to update, DELETE to close

Example
curl -X DELETE 'https://api.nexxss.com/api/conversations/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/conversations/:id

Conversation Detail API Routes

GET individual conversation, PUT to update, DELETE to close

Example
curl -X GET 'https://api.nexxss.com/api/conversations/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PUT/api/conversations/:id

Conversation Detail API Routes

GET individual conversation, PUT to update, DELETE to close

Example
curl -X PUT 'https://api.nexxss.com/api/conversations/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/conversations/:id/messages

Conversation Messages API Routes

GET messages for a conversation, POST to send a new message

Example
curl -X GET 'https://api.nexxss.com/api/conversations/{id}/messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/conversations/:id/messages

Conversation Messages API Routes

GET messages for a conversation, POST to send a new message

Example
curl -X POST 'https://api.nexxss.com/api/conversations/{id}/messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/conversations/:id/notes

Conversation internal notes.

Notes are private to the team — never sent to the customer. Stored as

messaging_messages rows with message_type='internal_note', so the existing

thread view can render them inline with a different style.

GET /api/conversations/[id]/notes → list internal notes

POST /api/conversations/[id]/notes → add an internal note (CSRF-protected)

Example
curl -X GET 'https://api.nexxss.com/api/conversations/{id}/notes' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/conversations/:id/notes

Conversation internal notes.

Notes are private to the team — never sent to the customer. Stored as

messaging_messages rows with message_type='internal_note', so the existing

thread view can render them inline with a different style.

GET /api/conversations/[id]/notes → list internal notes

POST /api/conversations/[id]/notes → add an internal note (CSRF-protected)

Example
curl -X POST 'https://api.nexxss.com/api/conversations/{id}/notes' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/conversations/:id/tags
Example
curl -X POST 'https://api.nexxss.com/api/conversations/{id}/tags' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"tag":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
AddTagSchema = z.object({
  tag: z.string().trim().min(1).max(50),

credentials

5 endpoints

GET/api/credentials

Credentials API

GET - List credentials for the authenticated user (metadata only)

POST - Store a new credential

Example
curl -X GET 'https://api.nexxss.com/api/credentials' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/credentials

Credentials API

GET - List credentials for the authenticated user (metadata only)

POST - Store a new credential

Example
curl -X POST 'https://api.nexxss.com/api/credentials' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/credentials/:provider/:service

Credential Detail API

GET - Retrieve a specific credential

DELETE - Delete a specific credential

Example
curl -X DELETE 'https://api.nexxss.com/api/credentials/{provider}/{service}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/credentials/:provider/:service

Credential Detail API

GET - Retrieve a specific credential

DELETE - Delete a specific credential

Example
curl -X GET 'https://api.nexxss.com/api/credentials/{provider}/{service}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/credentials/by-id/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/credentials/by-id/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

crm

10 endpoints

GET/api/crm/deals

CRM Deals API Routes

CRUD operations for sales deals/opportunities

Example
curl -X GET 'https://api.nexxss.com/api/crm/deals' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateDealSchema = z.object({
      customer_id: z.string().uuid(),
      pipeline_id: z.string().uuid(),
      stage_id: z.string().uuid(),
      title: z.string().min(1).max(255),
      value: z.number().min(0),
      currency: z.string().length(3).default("USD"),
      probability: z.number().min(0).max(100).optional(),
      expected_close_date: z.string().datetime().optional(),
      owner_id: z.string().uuid().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
POST/api/crm/deals

CRM Deals API Routes

CRUD operations for sales deals/opportunities

Example
curl -X POST 'https://api.nexxss.com/api/crm/deals' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"customer_id":"string","pipeline_id":"string","stage_id":"string","title":"string","value":0,"currency":"string","probability":0,"expected_close_date":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateDealSchema = z.object({
      customer_id: z.string().uuid(),
      pipeline_id: z.string().uuid(),
      stage_id: z.string().uuid(),
      title: z.string().min(1).max(255),
      value: z.number().min(0),
      currency: z.string().length(3).default("USD"),
      probability: z.number().min(0).max(100).optional(),
      expected_close_date: z.string().datetime().optional(),
      owner_id: z.string().uuid().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
DELETE/api/crm/deals/:id

Individual CRM Deal API Routes

GET, PUT, DELETE operations for a specific deal

Example
curl -X DELETE 'https://api.nexxss.com/api/crm/deals/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid deal ID format");

// =============================================
// GET /api/crm/deals/[id] - Get single deal
// =============================================

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const supabase = getSupabaseClient();
  try {
    const { id } = await params;

    const idResult = uuidSchema.safeParse(id);
    if (!idResult.success) {
      return NextResponse.json(
        { success: false, error: "Invalid deal ID format" },
        { status: 400 },
      );
    }

    const authResult = await requireAuth(request);
    if (authResult.error) {
      return authResult.error;
    }
    const { customer } = authResult;
    const { organizationId, customerId } = customer;

    con
UpdateDealSchema = z.object({
      stage_id: z.string().uuid().optional(),
      title: z.string().min(1).max(255).optional(),
      value: z.number().min(0).optional(),
      probability: z.number().min(0).max(100).optional(),
      expected_close_date: z.string().datetime().optional().nullable(),
      status: z.enum(["open", "won", "lost"]).optional(),
      owner_id: z.string().uuid().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
GET/api/crm/deals/:id

Individual CRM Deal API Routes

GET, PUT, DELETE operations for a specific deal

Example
curl -X GET 'https://api.nexxss.com/api/crm/deals/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid deal ID format");

// =============================================
// GET /api/crm/deals/[id] - Get single deal
// =============================================

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const supabase = getSupabaseClient();
  try {
    const { id } = await params;

    const idResult = uuidSchema.safeParse(id);
    if (!idResult.success) {
      return NextResponse.json(
        { success: false, error: "Invalid deal ID format" },
        { status: 400 },
      );
    }

    const authResult = await requireAuth(request);
    if (authResult.error) {
      return authResult.error;
    }
    const { customer } = authResult;
    const { organizationId, customerId } = customer;

    con
UpdateDealSchema = z.object({
      stage_id: z.string().uuid().optional(),
      title: z.string().min(1).max(255).optional(),
      value: z.number().min(0).optional(),
      probability: z.number().min(0).max(100).optional(),
      expected_close_date: z.string().datetime().optional().nullable(),
      status: z.enum(["open", "won", "lost"]).optional(),
      owner_id: z.string().uuid().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
PATCH/api/crm/deals/:id

Individual CRM Deal API Routes

GET, PUT, DELETE operations for a specific deal

Example
curl -X PATCH 'https://api.nexxss.com/api/crm/deals/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid deal ID format");

// =============================================
// GET /api/crm/deals/[id] - Get single deal
// =============================================

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const supabase = getSupabaseClient();
  try {
    const { id } = await params;

    const idResult = uuidSchema.safeParse(id);
    if (!idResult.success) {
      return NextResponse.json(
        { success: false, error: "Invalid deal ID format" },
        { status: 400 },
      );
    }

    const authResult = await requireAuth(request);
    if (authResult.error) {
      return authResult.error;
    }
    const { customer } = authResult;
    const { organizationId, customerId } = customer;

    con
UpdateDealSchema = z.object({
      stage_id: z.string().uuid().optional(),
      title: z.string().min(1).max(255).optional(),
      value: z.number().min(0).optional(),
      probability: z.number().min(0).max(100).optional(),
      expected_close_date: z.string().datetime().optional().nullable(),
      status: z.enum(["open", "won", "lost"]).optional(),
      owner_id: z.string().uuid().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
PUT/api/crm/deals/:id

Individual CRM Deal API Routes

GET, PUT, DELETE operations for a specific deal

Example
curl -X PUT 'https://api.nexxss.com/api/crm/deals/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid deal ID format");

// =============================================
// GET /api/crm/deals/[id] - Get single deal
// =============================================

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const supabase = getSupabaseClient();
  try {
    const { id } = await params;

    const idResult = uuidSchema.safeParse(id);
    if (!idResult.success) {
      return NextResponse.json(
        { success: false, error: "Invalid deal ID format" },
        { status: 400 },
      );
    }

    const authResult = await requireAuth(request);
    if (authResult.error) {
      return authResult.error;
    }
    const { customer } = authResult;
    const { organizationId, customerId } = customer;

    con
UpdateDealSchema = z.object({
      stage_id: z.string().uuid().optional(),
      title: z.string().min(1).max(255).optional(),
      value: z.number().min(0).optional(),
      probability: z.number().min(0).max(100).optional(),
      expected_close_date: z.string().datetime().optional().nullable(),
      status: z.enum(["open", "won", "lost"]).optional(),
      owner_id: z.string().uuid().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
GET/api/crm/pipelines

CRM Pipelines API Routes

List and create sales pipelines

Example
curl -X GET 'https://api.nexxss.com/api/crm/pipelines' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
StageSchema = z.object({
      name: z.string().min(1).max(100),
      order: z.number().int().min(0),
      probability: z.number().min(0).max(100),
      color: z.string().regex(/^#[0-9A-Fa-f]{6}$/),
CreatePipelineSchema = z.object({
      name: z.string().min(1).max(255),
      stages: z.array(StageSchema).min(1),
      is_default: z.boolean().optional().default(false),
POST/api/crm/pipelines

CRM Pipelines API Routes

List and create sales pipelines

Example
curl -X POST 'https://api.nexxss.com/api/crm/pipelines' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","order":0,"probability":0,"color":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
StageSchema = z.object({
      name: z.string().min(1).max(100),
      order: z.number().int().min(0),
      probability: z.number().min(0).max(100),
      color: z.string().regex(/^#[0-9A-Fa-f]{6}$/),
CreatePipelineSchema = z.object({
      name: z.string().min(1).max(255),
      stages: z.array(StageSchema).min(1),
      is_default: z.boolean().optional().default(false),
DELETE/api/crm/pipelines/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/crm/pipelines/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","order":0,"probability":0,"color":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid pipeline ID format");

const StageSchema = z.object({
  name: z.string().min(1).max(100),
  order: z.number().int().min(0),
  probability: z.number().min(0).max(100),
  color: z.string().regex(/^#[0-9A-Fa-f]{6}$/),
UpdatePipelineSchema = z.object({
  name: z.string().min(1).max(255).optional(),
  stages: z.array(StageSchema).min(1).optional(),
  is_default: z.boolean().optional(),
PUT/api/crm/pipelines/:id
Example
curl -X PUT 'https://api.nexxss.com/api/crm/pipelines/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","order":0,"probability":0,"color":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid pipeline ID format");

const StageSchema = z.object({
  name: z.string().min(1).max(100),
  order: z.number().int().min(0),
  probability: z.number().min(0).max(100),
  color: z.string().regex(/^#[0-9A-Fa-f]{6}$/),
UpdatePipelineSchema = z.object({
  name: z.string().min(1).max(255).optional(),
  stages: z.array(StageSchema).min(1).optional(),
  is_default: z.boolean().optional(),

cron

7 endpoints

GET/api/cron/agent-runs

Cron: scheduled agent runs.

Polls `nx_agent_schedules` for rows where `enabled AND next_run_at <= now`,

executes each prompt through the same tool-using agent the dashboard uses,

records the result + bumps `next_run_at` to the next match.

Capped at 25 schedules per invocation to keep a single cron tick well under

Vercel's serverless time budget. Anything still due will be picked up on

the next tick.

Example
curl -X GET 'https://api.nexxss.com/api/cron/agent-runs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/cron/onboarding-drip

Cron: daily onboarding email drip.

Sends one of three nudges depending on org age and progress:

- Day 1 (≥24h, <48h since signup): "Connect your first channel"

- Day 3 (≥72h, <96h): "Try a workflow template"

- Day 12 (≥288h, <336h): "Trial ends in 2 days"

Skips orgs that have already done the relevant action. We track which

stages have been sent in `organization_metadata.onboarding_drip_sent`.

Best-effort: failures per org don't block the others. Skipped entirely if

RESEND_API_KEY isn't configured.

Example
curl -X GET 'https://api.nexxss.com/api/cron/onboarding-drip' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/cron/redis-metrics

Cron Job: Redis Metrics Collector

Runs every 5 minutes to collect Redis metrics and forward to Better Stack

Monitored by Sentry Crons

Supports two Redis configurations:

1. Standard Redis via REDIS_URL with ioredis client (supports INFO command)

2. Upstash REST API (limited metrics via fetch, no INFO endpoint available)

Example
curl -X GET 'https://api.nexxss.com/api/cron/redis-metrics' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/cron/sentry-events-retention

Cron Job: Sentry Events Retention Cleanup

Runs daily to purge old `sentry_events` rows (PII retention enforcement)

Monitored by Sentry Crons

Example
curl -X GET 'https://api.nexxss.com/api/cron/sentry-events-retention' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/cron/social-posts

Cron Job: Social Media Post Scheduler

Runs every 15 minutes to publish scheduled social media posts

Monitored by Sentry Crons

Example
curl -X GET 'https://api.nexxss.com/api/cron/social-posts' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/cron/weekly-digest

Cron: Monday 9am UTC weekly digest.

For each org with at least one user, sends a summary email of last week:

- Inbound conversation count

- Workflow runs (succeeded / failed)

- New deals

- Failed channels needing attention

Best-effort: failures per org don't block the others. Skipped entirely if

RESEND_API_KEY isn't configured.

Example
curl -X GET 'https://api.nexxss.com/api/cron/weekly-digest' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/cron/workflows-scheduler

Cron job: workflows scheduler.

Runs every minute and fires any active workflow whose trigger_type is

`schedule` and whose cron expression matches the current minute.

Each fire executes the workflow's steps directly (we call the executor

in-process rather than the auth-protected API route, to avoid needing

to forward credentials).

Example
curl -X GET 'https://api.nexxss.com/api/cron/workflows-scheduler' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

csp-report

2 endpoints

GET/api/csp-report

CSP violation report sink.

Browsers POST violations here (set via `report-uri` in our CSP). We log them

at warn level via the shared service logger, then return 204 so the browser

doesn't retry. Rate-limited per IP to prevent log flooding.

Accepts both legacy `application/csp-report` and the newer

`application/reports+json` (Reporting API) content types.

Example
curl -X GET 'https://api.nexxss.com/api/csp-report' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/csp-report

CSP violation report sink.

Browsers POST violations here (set via `report-uri` in our CSP). We log them

at warn level via the shared service logger, then return 204 so the browser

doesn't retry. Rate-limited per IP to prevent log flooding.

Accepts both legacy `application/csp-report` and the newer

`application/reports+json` (Reporting API) content types.

Example
curl -X POST 'https://api.nexxss.com/api/csp-report' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred

csrf

1 endpoint

GET/api/csrf/token

CSRF Token API Route

Returns a CSRF token for client-side API calls.

The token is also set in a cookie for validation.

Example
curl -X GET 'https://api.nexxss.com/api/csrf/token' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "token": "..."
}

custom-fields

2 endpoints

GET/api/custom-fields

GET /api/custom-fields?entity=customer|deal — list defined fields

POST /api/custom-fields — define a new field

DELETE /api/custom-fields?id=… — remove a definition

Definitions live in organizations.metadata.custom_fields = {

customer: [{ id, key, label, type }],

deal: [{ id, key, label, type }]

}

Actual values are stored on each customer/deal row's `metadata` JSONB

column under `custom.<key>`. No migration needed for the data — just

the field definitions.

Example
curl -X GET 'https://api.nexxss.com/api/custom-fields' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/custom-fields

GET /api/custom-fields?entity=customer|deal — list defined fields

POST /api/custom-fields — define a new field

DELETE /api/custom-fields?id=… — remove a definition

Definitions live in organizations.metadata.custom_fields = {

customer: [{ id, key, label, type }],

deal: [{ id, key, label, type }]

}

Actual values are stored on each customer/deal row's `metadata` JSONB

column under `custom.<key>`. No migration needed for the data — just

the field definitions.

Example
curl -X POST 'https://api.nexxss.com/api/custom-fields' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

customer-success

3 endpoints

GET/api/customer-success/churn-risk

Customer Success Churn Risk API

GET - Get churn risk assessment for a customer

Example
curl -X GET 'https://api.nexxss.com/api/customer-success/churn-risk' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/customer-success/health

Customer Success Health Score API

GET - Get health score for a customer

Example
curl -X GET 'https://api.nexxss.com/api/customer-success/health' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/customer-success/onboarding

Customer Success Onboarding Progress API

GET - Get onboarding progress for a customer

Example
curl -X GET 'https://api.nexxss.com/api/customer-success/onboarding' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

customers

5 endpoints

GET/api/customers

Customers API Routes

REST endpoints for customer management

Example
curl -X GET 'https://api.nexxss.com/api/customers' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateCustomerSchema = z.object({
      name: z.string().optional(),
      email: z.string().email(),
      phone: z.string().optional(),
      company: z.string().optional(),
      title: z.string().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
      tags: z.array(z.string()).optional(),
POST/api/customers

Customers API Routes

REST endpoints for customer management

Example
curl -X POST 'https://api.nexxss.com/api/customers' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","email":"string","phone":"string","company":"string","title":"string","tags":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateCustomerSchema = z.object({
      name: z.string().optional(),
      email: z.string().email(),
      phone: z.string().optional(),
      company: z.string().optional(),
      title: z.string().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
      tags: z.array(z.string()).optional(),
DELETE/api/customers/:id

Individual Customer API Routes

GET, PUT, DELETE operations for a specific customer

Example
curl -X DELETE 'https://api.nexxss.com/api/customers/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid customer ID format");

// =============================================
// GET /api/customers/[id] - Get single customer
// =============================================

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const supabase = getSupabaseClient();
  try {
    const { id } = await params;

    // Validate UUID format
    const idResult = uuidSchema.safeParse(id);
    if (!idResult.success) {
      return NextResponse.json(
        { success: false, error: "Invalid customer ID format" },
        { status: 400 },
      );
    }

    // Authenticate request
    const authResult = await requireAuth(request);
    if (authResult.error) {
      return authResult.error;
    }
    const { customer: authCust
UpdateCustomerSchema = z.object({
      name: z.string().optional(),
      email: z.string().email().optional(),
      phone: z.string().optional(),
      company: z.string().optional(),
      title: z.string().optional(),
      status: z.enum(["active", "inactive", "lead", "churned"]).optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
      tags: z.array(z.string()).optional(),
GET/api/customers/:id

Individual Customer API Routes

GET, PUT, DELETE operations for a specific customer

Example
curl -X GET 'https://api.nexxss.com/api/customers/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid customer ID format");

// =============================================
// GET /api/customers/[id] - Get single customer
// =============================================

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const supabase = getSupabaseClient();
  try {
    const { id } = await params;

    // Validate UUID format
    const idResult = uuidSchema.safeParse(id);
    if (!idResult.success) {
      return NextResponse.json(
        { success: false, error: "Invalid customer ID format" },
        { status: 400 },
      );
    }

    // Authenticate request
    const authResult = await requireAuth(request);
    if (authResult.error) {
      return authResult.error;
    }
    const { customer: authCust
UpdateCustomerSchema = z.object({
      name: z.string().optional(),
      email: z.string().email().optional(),
      phone: z.string().optional(),
      company: z.string().optional(),
      title: z.string().optional(),
      status: z.enum(["active", "inactive", "lead", "churned"]).optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
      tags: z.array(z.string()).optional(),
PUT/api/customers/:id

Individual Customer API Routes

GET, PUT, DELETE operations for a specific customer

Example
curl -X PUT 'https://api.nexxss.com/api/customers/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
uuidSchema = z.string().uuid("Invalid customer ID format");

// =============================================
// GET /api/customers/[id] - Get single customer
// =============================================

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const supabase = getSupabaseClient();
  try {
    const { id } = await params;

    // Validate UUID format
    const idResult = uuidSchema.safeParse(id);
    if (!idResult.success) {
      return NextResponse.json(
        { success: false, error: "Invalid customer ID format" },
        { status: 400 },
      );
    }

    // Authenticate request
    const authResult = await requireAuth(request);
    if (authResult.error) {
      return authResult.error;
    }
    const { customer: authCust
UpdateCustomerSchema = z.object({
      name: z.string().optional(),
      email: z.string().email().optional(),
      phone: z.string().optional(),
      company: z.string().optional(),
      title: z.string().optional(),
      status: z.enum(["active", "inactive", "lead", "churned"]).optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
      tags: z.array(z.string()).optional(),

data-sync

2 endpoints

GET/api/data-sync/sources

Data Sync Sources API

GET - List registered sync sources for the current organization

POST - Register a new sync source

Persists to public.bi_data_sources, scoped by organization_id (RLS enforced).

Example
curl -X GET 'https://api.nexxss.com/api/data-sync/sources' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/data-sync/sources

Data Sync Sources API

GET - List registered sync sources for the current organization

POST - Register a new sync source

Persists to public.bi_data_sources, scoped by organization_id (RLS enforced).

Example
curl -X POST 'https://api.nexxss.com/api/data-sync/sources' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

dbos

2 endpoints

GET/api/dbos/email/inbound

DBOS Email Webhook API Route

Example: POST /api/dbos/email/inbound

DBOS durable workflows run in-process and survive crashes.

Example
curl -X GET 'https://api.nexxss.com/api/dbos/email/inbound' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
InboundEmailSchema = z.object({
  from: z.string().email("Invalid email format in 'from' field"),
  subject: z.string().min(1, "Subject is required").max(1000),
  body: z.string().max(100000).optional(),
  text: z.string().max(100000).optional(),
  html: z.string().max(500000).optional(),
  receivedAt: z.string().datetime().optional(),
  to: z.union([z.string().email(), z.array(z.string().email())]).optional(),
  cc: z.union([z.string().email(), z.array(z.string().email())]).optional(),
  replyTo: z.string().email().optional(),
  messageId: z.string().max(500).optional(),
  inReplyTo: z.string().max(500).optional(),
  attachments: z
    .array(
      z.object({
        filename: z.string().max(500),
        contentType: z.string().max(200),
        size: z
          .number()
          .max(25 * 1024 * 1024)
 
POST/api/dbos/email/inbound

DBOS Email Webhook API Route

Example: POST /api/dbos/email/inbound

DBOS durable workflows run in-process and survive crashes.

Example
curl -X POST 'https://api.nexxss.com/api/dbos/email/inbound' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"from":"string","subject":"string","body":"string","text":"string","html":"string","receivedAt":"string","replyTo":"string","messageId":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
InboundEmailSchema = z.object({
  from: z.string().email("Invalid email format in 'from' field"),
  subject: z.string().min(1, "Subject is required").max(1000),
  body: z.string().max(100000).optional(),
  text: z.string().max(100000).optional(),
  html: z.string().max(500000).optional(),
  receivedAt: z.string().datetime().optional(),
  to: z.union([z.string().email(), z.array(z.string().email())]).optional(),
  cc: z.union([z.string().email(), z.array(z.string().email())]).optional(),
  replyTo: z.string().email().optional(),
  messageId: z.string().max(500).optional(),
  inReplyTo: z.string().max(500).optional(),
  attachments: z
    .array(
      z.object({
        filename: z.string().max(500),
        contentType: z.string().max(200),
        size: z
          .number()
          .max(25 * 1024 * 1024)
 

demo

1 endpoint

POST/api/demo/login

Demo login endpoint for temporary testing

In production, this should be removed

Example
curl -X POST 'https://api.nexxss.com/api/demo/login' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

documents

15 endpoints

GET/api/documents

Documents API Routes

REST endpoints for document/file management

Example
curl -X GET 'https://api.nexxss.com/api/documents' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/documents

Documents API Routes

REST endpoints for document/file management

Example
curl -X POST 'https://api.nexxss.com/api/documents' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/documents/:id

Document Detail API Routes

GET and DELETE for individual documents

Example
curl -X DELETE 'https://api.nexxss.com/api/documents/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/documents/:id

Document Detail API Routes

GET and DELETE for individual documents

Example
curl -X GET 'https://api.nexxss.com/api/documents/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/documents/folders

Document Folders API Route

Example
curl -X GET 'https://api.nexxss.com/api/documents/folders' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/documents/folders

Document Folders API Route

Example
curl -X POST 'https://api.nexxss.com/api/documents/folders' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/documents/folders/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/documents/folders/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
PUT/api/documents/folders/:id
Example
curl -X PUT 'https://api.nexxss.com/api/documents/folders/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/documents/management

Document Management API Routes

GET - List documents for an organization

POST - Upload a document (multipart/form-data)

Example
curl -X GET 'https://api.nexxss.com/api/documents/management' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/documents/management

Document Management API Routes

GET - List documents for an organization

POST - Upload a document (multipart/form-data)

Example
curl -X POST 'https://api.nexxss.com/api/documents/management' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/documents/management/:id

Document Management Detail API Routes

GET - Get single document by ID

DELETE - Delete a document

Example
curl -X DELETE 'https://api.nexxss.com/api/documents/management/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/documents/management/:id

Document Management Detail API Routes

GET - Get single document by ID

DELETE - Delete a document

Example
curl -X GET 'https://api.nexxss.com/api/documents/management/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PUT/api/documents/management/:id

Document Management Detail API Routes

GET - Get single document by ID

DELETE - Delete a document

Example
curl -X PUT 'https://api.nexxss.com/api/documents/management/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/documents/management/:id/duplicate
Example
curl -X POST 'https://api.nexxss.com/api/documents/management/{id}/duplicate' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/documents/management/:id/version

Document Version API Routes

POST - Upload a new version of a document (multipart/form-data)

Example
curl -X POST 'https://api.nexxss.com/api/documents/management/{id}/version' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

email

7 endpoints

GET/api/email/connections

Email Connections API

GET - List email connections for the authenticated user

POST - Create a new email connection

Example
curl -X GET 'https://api.nexxss.com/api/email/connections' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/email/connections

Email Connections API

GET - List email connections for the authenticated user

POST - Create a new email connection

Example
curl -X POST 'https://api.nexxss.com/api/email/connections' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/email/connections/:id

Email Connection by ID API

DELETE - Delete an email connection

Example
curl -X DELETE 'https://api.nexxss.com/api/email/connections/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/email/connections/:id

Email Connection by ID API

DELETE - Delete an email connection

Example
curl -X GET 'https://api.nexxss.com/api/email/connections/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/email/connections/:id/rules

Email Connection Monitoring Rules API

GET - List monitoring rules for a connection

POST - Create a monitoring rule for a connection

Example
curl -X GET 'https://api.nexxss.com/api/email/connections/{id}/rules' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/email/connections/:id/rules

Email Connection Monitoring Rules API

GET - List monitoring rules for a connection

POST - Create a monitoring rule for a connection

Example
curl -X POST 'https://api.nexxss.com/api/email/connections/{id}/rules' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/email/connections/:id/sync
Example
curl -X POST 'https://api.nexxss.com/api/email/connections/{id}/sync' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

enterprise

34 endpoints

GET/api/enterprise/ai-usage

GET /api/enterprise/ai-usage

Returns the last 30 days of nx_ai_usage aggregated by model plus the

current month's spend, the tenant's budget, and a per-model breakdown.

RBAC: audit:read.

Example
curl -X GET 'https://api.nexxss.com/api/enterprise/ai-usage' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "...",
  "lookbackDays": "...",
  "totals": "...",
  "calls": "...",
  "costUsd": "..."
}
PATCH/api/enterprise/ai-usage/budget

PATCH /api/enterprise/ai-usage/budget

Updates `organizations.ai_monthly_budget` for the caller's tenant.

Body: { budgetUsd: number }. Range 0..100000 inclusive.

RBAC: tenant:admin (writing budget is an admin action).

Example
curl -X PATCH 'https://api.nexxss.com/api/enterprise/ai-usage/budget' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"budgetUsd":0}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
patchSchema = z.object({
  budgetUsd: z.number().finite().min(0).max(100_000),
GET/api/enterprise/api-keys
Example
curl -X GET 'https://api.nexxss.com/api/enterprise/api-keys' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (1)
issueSchema = z.object({
  description: z.string().min(1).max(200),
  scopes: z.array(z.enum(VALID_SCOPES)).min(1),
  expiresAt: z.string().datetime().optional(),
POST/api/enterprise/api-keys
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/api-keys' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"description":"string","scopes":[],"expiresAt":"string"}'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (1)
issueSchema = z.object({
  description: z.string().min(1).max(200),
  scopes: z.array(z.enum(VALID_SCOPES)).min(1),
  expiresAt: z.string().datetime().optional(),
DELETE/api/enterprise/api-keys/:keyId
Example
curl -X DELETE 'https://api.nexxss.com/api/enterprise/api-keys/{keyId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "data": "..."
}
POST/api/enterprise/api-keys/:keyId
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/api-keys/{keyId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "data": "..."
}
GET/api/enterprise/audit

GET /api/enterprise/audit?limit=200&since=ISO&until=ISO&action=...&verify=1

Pulls audit log rows for the tenant. Pass `verify=1` to also run a chain

verification across the tenant's full chain (slower).

RBAC: audit:read.

Example
curl -X GET 'https://api.nexxss.com/api/enterprise/audit' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string",
  "parameter": "..."
}
GET/api/enterprise/compliance/export

GET /api/enterprise/compliance/export

Generates and returns a SOC 2 evidence .xlsx workbook from the DB.

RBAC: `audit:read`.

Query params:

?since=ISO ISO timestamp lower bound (default 90 days ago)

?until=ISO ISO timestamp upper bound (default now)

?runId=UUID restrict to a single run (takes precedence over since/until)

?controlIds=a,b comma-separated SOC 2 control ids

Example
curl -X GET 'https://api.nexxss.com/api/enterprise/compliance/export' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/enterprise/compliance/run

POST /api/enterprise/compliance/run

Trigger a SOC 2 evidence collection cycle. RBAC: `audit:read`

(gated inside runCollectionCycle).

Body (optional):

{ collectorIds?: string[]; windowDays?: number }

Returns: { runId: string; counts: { pass; fail; info } }

Example
curl -X POST 'https://api.nexxss.com/api/enterprise/compliance/run' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"collectorIds":[],"windowDays":0}'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (1)
runComplianceSchema = z.object({
  collectorIds: z.array(z.string().trim().min(1)).max(100).optional(),
  windowDays: z.number().int().min(1).max(365).optional(),
GET/api/enterprise/domains
Example
curl -X GET 'https://api.nexxss.com/api/enterprise/domains' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "...",
  "meta": "..."
}
POST/api/enterprise/domains
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/domains' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "data": "...",
  "meta": "..."
}
DELETE/api/enterprise/domains/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/enterprise/domains/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true"
}
POST/api/enterprise/domains/:id/verify
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/domains/{id}/verify' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "data": "..."
}
GET/api/enterprise/gdpr
Example
curl -X GET 'https://api.nexxss.com/api/enterprise/gdpr' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true"
}
POST/api/enterprise/gdpr
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/gdpr' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true"
}
GET/api/enterprise/identity-providers
Example
curl -X GET 'https://api.nexxss.com/api/enterprise/identity-providers' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (3)
samlConfigSchema = z.object({
  entityId: z.string().min(1),
  ssoUrl: z.string().url(),
  x509Cert: z.string().min(1),
  signatureAlgorithm: z.enum(["sha256", "sha512"]).optional(),
  acsUrl: z.string().url(),
oidcConfigSchema = z.object({
  issuer: z.string().url(),
  clientId: z.string().min(1),
  clientSecretRef: z.string().min(1),
  scopes: z.array(z.string()).optional(),
  redirectUri: z.string().url(),
registerSchema = z.discriminatedUnion("type", [
  z.object({
    type: z.literal("saml"),
    displayName: z.string().min(1).max(120),
    domain: z.string().min(1).max(120).optional(),
    config: samlConfigSchema,
    attributeMapping: z.record(z.string(), z.unknown()).optional(),
    defaultRole: z.enum(VALID_ROLES).optional(),
  }),
  z.object({
    type: z.literal("oidc"),
    displayName: z.string().min(1).max(120),
    domain: z.string().min(1).max(120).optional(),
    config: oidcConfigSchema,
    attributeMapping: z.record(z.string(), z.unknown()).optional(),
    defaultRole: z.enum(VALID_ROLES).optional(),
  }),
]);

export async function GET(req: Request): Promise<Response> {
  try {
    const { ctx, credential } = await requireEnterpriseRequestAuth(req);
    if (credential) requireScope(credent
POST/api/enterprise/identity-providers
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/identity-providers' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"entityId":"string","ssoUrl":"string","x509Cert":"string","signatureAlgorithm":"value","acsUrl":"string"}'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (3)
samlConfigSchema = z.object({
  entityId: z.string().min(1),
  ssoUrl: z.string().url(),
  x509Cert: z.string().min(1),
  signatureAlgorithm: z.enum(["sha256", "sha512"]).optional(),
  acsUrl: z.string().url(),
oidcConfigSchema = z.object({
  issuer: z.string().url(),
  clientId: z.string().min(1),
  clientSecretRef: z.string().min(1),
  scopes: z.array(z.string()).optional(),
  redirectUri: z.string().url(),
registerSchema = z.discriminatedUnion("type", [
  z.object({
    type: z.literal("saml"),
    displayName: z.string().min(1).max(120),
    domain: z.string().min(1).max(120).optional(),
    config: samlConfigSchema,
    attributeMapping: z.record(z.string(), z.unknown()).optional(),
    defaultRole: z.enum(VALID_ROLES).optional(),
  }),
  z.object({
    type: z.literal("oidc"),
    displayName: z.string().min(1).max(120),
    domain: z.string().min(1).max(120).optional(),
    config: oidcConfigSchema,
    attributeMapping: z.record(z.string(), z.unknown()).optional(),
    defaultRole: z.enum(VALID_ROLES).optional(),
  }),
]);

export async function GET(req: Request): Promise<Response> {
  try {
    const { ctx, credential } = await requireEnterpriseRequestAuth(req);
    if (credential) requireScope(credent
DELETE/api/enterprise/identity-providers/:idpId
Example
curl -X DELETE 'https://api.nexxss.com/api/enterprise/identity-providers/{idpId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
PATCH/api/enterprise/identity-providers/:idpId
Example
curl -X PATCH 'https://api.nexxss.com/api/enterprise/identity-providers/{idpId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/enterprise/impersonation

/api/enterprise/impersonation

GET — list sessions (audit:read). `?active=1` filters to live sessions.

POST — start a session (super_admin via tenant:admin scope/RBAC).

DELETE — end a session (must own it). Pass `{ sessionId }` in the body.

Example
curl -X DELETE 'https://api.nexxss.com/api/enterprise/impersonation' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"targetUserId":"string","reason":"string","ttlSeconds":0}'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (2)
startSchema = z.object({
  targetUserId: z.string().uuid(),
  reason: z.string().min(1).max(500),
  ttlSeconds: z.number().int().positive().max(60 * 60 * 8).optional(),
endSchema = z.object({
  sessionId: z.string().uuid(),
GET/api/enterprise/impersonation

/api/enterprise/impersonation

GET — list sessions (audit:read). `?active=1` filters to live sessions.

POST — start a session (super_admin via tenant:admin scope/RBAC).

DELETE — end a session (must own it). Pass `{ sessionId }` in the body.

Example
curl -X GET 'https://api.nexxss.com/api/enterprise/impersonation' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (2)
startSchema = z.object({
  targetUserId: z.string().uuid(),
  reason: z.string().min(1).max(500),
  ttlSeconds: z.number().int().positive().max(60 * 60 * 8).optional(),
endSchema = z.object({
  sessionId: z.string().uuid(),
POST/api/enterprise/impersonation

/api/enterprise/impersonation

GET — list sessions (audit:read). `?active=1` filters to live sessions.

POST — start a session (super_admin via tenant:admin scope/RBAC).

DELETE — end a session (must own it). Pass `{ sessionId }` in the body.

Example
curl -X POST 'https://api.nexxss.com/api/enterprise/impersonation' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"targetUserId":"string","reason":"string","ttlSeconds":0}'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (2)
startSchema = z.object({
  targetUserId: z.string().uuid(),
  reason: z.string().min(1).max(500),
  ttlSeconds: z.number().int().positive().max(60 * 60 * 8).optional(),
endSchema = z.object({
  sessionId: z.string().uuid(),
GET/api/enterprise/impersonation/current

/api/enterprise/impersonation/current

GET — returns the active impersonation session belonging to the

requesting (session) user, or `{ data: null }` if they aren't impersonating.

Intentionally bypasses `authenticateEnterpriseRequest`'s impersonation

overlay: we need the *original* session user id (the staff member),

not the rewritten target id, so a banner can show "you are impersonating".

Returns 401 only when there is no NextAuth session. Bearer tokens are

intentionally rejected — banners are a browser-only concern.

Example
curl -X GET 'https://api.nexxss.com/api/enterprise/impersonation/current' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/enterprise/kb/documents
Example
curl -X GET 'https://api.nexxss.com/api/enterprise/kb/documents' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
POST/api/enterprise/kb/ingest
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/kb/ingest' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"title":"string","content":"string","sourceUrl":"string"}'
Response
{
  "success": "true",
  "error": "string",
  "details": "..."
}
Zod schemas (1)
ingestSchema = z.object({
  title: z.string().min(1).max(500),
  content: z.string().min(1).max(2_000_000),
  sourceUrl: z.string().url().max(2048).optional(),
POST/api/enterprise/kb/query
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/kb/query' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"query":"string","topK":0}'
Response
{
  "success": "true",
  "error": "string",
  "details": "..."
}
Zod schemas (1)
querySchema = z.object({
  query: z.string().min(1).max(4000),
  topK: z.number().int().min(1).max(20).optional(),
GET/api/enterprise/memberships

GET /api/enterprise/memberships

Returns the tenant's memberships list. Joins the users table so the admin

UI can show email / display name alongside each membership.

RBAC: memberships:read. (Contains user email PII; permission-gated.)

Example
curl -X GET 'https://api.nexxss.com/api/enterprise/memberships' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
DELETE/api/enterprise/memberships/:membershipId
Example
curl -X DELETE 'https://api.nexxss.com/api/enterprise/memberships/{membershipId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"role":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
patchSchema = z.object({
  role: z.enum(VALID_ROLES as [Role, ...Role[]]).optional(),
PATCH/api/enterprise/memberships/:membershipId
Example
curl -X PATCH 'https://api.nexxss.com/api/enterprise/memberships/{membershipId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"role":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
patchSchema = z.object({
  role: z.enum(VALID_ROLES as [Role, ...Role[]]).optional(),
GET/api/enterprise/tenant

GET /api/enterprise/tenant

Returns the caller's tenant snapshot: id, name, plan, retention, and the

caller's membership row (role + accepted_at). Used by the admin UI shell.

Example
curl -X GET 'https://api.nexxss.com/api/enterprise/tenant' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/enterprise/webhooks
Example
curl -X GET 'https://api.nexxss.com/api/enterprise/webhooks' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (1)
registerSchema = z.object({
  url: z.string().url(),
  description: z.string().max(500).optional(),
  eventTypes: z.array(z.string().min(1)).min(1),
POST/api/enterprise/webhooks
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/webhooks' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"url":"string","description":"string","eventTypes":[]}'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (1)
registerSchema = z.object({
  url: z.string().url(),
  description: z.string().max(500).optional(),
  eventTypes: z.array(z.string().min(1)).min(1),
POST/api/enterprise/webhooks/:endpointId
Example
curl -X POST 'https://api.nexxss.com/api/enterprise/webhooks/{endpointId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"action":"value","reason":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
actionSchema = z.object({
  action: z.enum(["rotate", "disable"]),
  reason: z.string().max(500).optional(),
POST/api/enterprise/webhooks/inbound/:endpointId

POST /api/enterprise/webhooks/inbound/:endpointId

Example inbound webhook receiver. Demonstrates the verifySignature flow

receivers of NEXXSS-signed webhooks would implement on their side.

Real customer-built receivers would live in the customer's own service;

this route is here to document the contract end-to-end.

Verifies:

- `x-nexxss-signature` HMAC-SHA256

- `x-nexxss-delivery-ts` is within 5 minutes

Then upserts the event id into a dedup table so retries are idempotent.

Example
curl -X POST 'https://api.nexxss.com/api/enterprise/webhooks/inbound/{endpointId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string",
  "code": "..."
}

exports

1 endpoint

GET/api/exports

GET /api/exports?type=customers|conversations|deals|workflows&format=csv|json

Synchronous data export — streams the org's data as a CSV or JSON file.

Works for orgs with < ~10k rows; larger exports should be moved to a

background job (S3 + email-link) when needed.

Example
curl -X GET 'https://api.nexxss.com/api/exports' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

facebook

4 endpoints

GET/api/facebook/deauthorize
Example
curl -X GET 'https://api.nexxss.com/api/facebook/deauthorize' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "error": "string"
}
POST/api/facebook/deauthorize
Example
curl -X POST 'https://api.nexxss.com/api/facebook/deauthorize' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "error": "string"
}
GET/api/facebook/delete

Meta data-deletion callback alias.

Keeps Facebook App Dashboard callback URL stable at /api/facebook/delete

while reusing the canonical implementation in /api/webhooks/data-deletion.

Example
curl -X GET 'https://api.nexxss.com/api/facebook/delete' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/facebook/delete

Meta data-deletion callback alias.

Keeps Facebook App Dashboard callback URL stable at /api/facebook/delete

while reusing the canonical implementation in /api/webhooks/data-deletion.

Example
curl -X POST 'https://api.nexxss.com/api/facebook/delete' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred

health

11 endpoints

GET/api/health

Health check endpoint with three modes:

- simple (?simple=true) Load-balancer friendly. No auth, NO dependency

checks. Always HTTP 200 + `{ status: "ok" }`.

- full (default) Runs all dependency checks and returns

`{ status, timestamp, services }` (HTTP 200 when

healthy, 503 otherwise). The `services` map

(HealthResult per service) is PUBLIC — it drives

the public /status page — but error strings are

redacted for unauthenticated callers. A detailed

`checks[]` array (raw errors) is added only for

authenticated callers.

- verbose (?verbose=true) Authenticated only. Adds `allChecks` (every

service, including skipped) and a sanitized

`system` health object (no raw runtime metrics).

Example
curl -X GET 'https://api.nexxss.com/api/health' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "status": "..."
}
GET/api/health/connections

GET /api/health/connections

Returns the health of every connection a customer has wired up — channel

tokens (FB pages, IG, WhatsApp, Telegram, Discord), webhook subscription

states, and recent webhook delivery failures from `webhook_event_log`.

Used by /dashboard/health so customers can self-diagnose when their IG

token expires or their FB page is disconnected.

Example
curl -X GET 'https://api.nexxss.com/api/health/connections' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/health/db

Probes the Supabase admin DB with a trivial `select 1`.

Example
curl -X GET 'https://api.nexxss.com/api/health/db' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/health/dbos

Reports whether the in-process DBOS workflow engine has been initialized.

Example
curl -X GET 'https://api.nexxss.com/api/health/dbos' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/health/openai

Unauthenticated GET to openai /v1/models; a 401 still proves the service is up.

Example
curl -X GET 'https://api.nexxss.com/api/health/openai' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/health/redis

PING against the Redis client; reports `redis_not_configured` if absent.

Example
curl -X GET 'https://api.nexxss.com/api/health/redis' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/health/resend

Unauthenticated Resend /health probe.

Example
curl -X GET 'https://api.nexxss.com/api/health/resend' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/health/sentry

Hits the Sentry public API root; a 200 means the service is up.

Example
curl -X GET 'https://api.nexxss.com/api/health/sentry' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/health/stripe

Calls Stripe customers.list({limit:1}) as a bounded liveness probe.

Example
curl -X GET 'https://api.nexxss.com/api/health/stripe' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/health/supabase

Pings the Supabase auth endpoint with an intentionally invalid token.

Example
curl -X GET 'https://api.nexxss.com/api/health/supabase' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/health/supabase-storage

Lists storage buckets to confirm the Supabase Storage API is reachable.

Example
curl -X GET 'https://api.nexxss.com/api/health/supabase-storage' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred

invoices

6 endpoints

GET/api/invoices

Invoices API Routes

GET - List invoices (placeholder - requires DB backing)

POST - Create a new invoice

Example
curl -X GET 'https://api.nexxss.com/api/invoices' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/invoices

Invoices API Routes

GET - List invoices (placeholder - requires DB backing)

POST - Create a new invoice

Example
curl -X POST 'https://api.nexxss.com/api/invoices' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/invoices/:id

Invoice Item API Routes

GET - Get invoice by ID

PATCH - Update invoice status (mark_paid / void)

DELETE - Void an invoice (soft delete by setting status='void')

Example
curl -X DELETE 'https://api.nexxss.com/api/invoices/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/invoices/:id

Invoice Item API Routes

GET - Get invoice by ID

PATCH - Update invoice status (mark_paid / void)

DELETE - Void an invoice (soft delete by setting status='void')

Example
curl -X GET 'https://api.nexxss.com/api/invoices/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PATCH/api/invoices/:id

Invoice Item API Routes

GET - Get invoice by ID

PATCH - Update invoice status (mark_paid / void)

DELETE - Void an invoice (soft delete by setting status='void')

Example
curl -X PATCH 'https://api.nexxss.com/api/invoices/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/invoices/tax

Invoice Tax Calculation API

GET - Calculate tax for a given subtotal, region, and country

Example
curl -X GET 'https://api.nexxss.com/api/invoices/tax' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

knowledge-base

12 endpoints

GET/api/knowledge-base

Knowledge Base API Routes

GET — List KB items (paginated, filtered)

POST — Upload document (multipart/form-data)

Example
curl -X GET 'https://api.nexxss.com/api/knowledge-base' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/knowledge-base

Knowledge Base API Routes

GET — List KB items (paginated, filtered)

POST — Upload document (multipart/form-data)

Example
curl -X POST 'https://api.nexxss.com/api/knowledge-base' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/knowledge-base/:id

Knowledge Base Item API

GET — Get single item by ID

PATCH — Update item

DELETE — Soft delete item

Example
curl -X DELETE 'https://api.nexxss.com/api/knowledge-base/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"title":"string","content":"string","summary":"string","tags":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
updateSchema = z.object({
  title: z.string().min(1).max(500).optional(),
  content: z.string().min(1).max(100000).optional(),
  summary: z.string().max(1000).optional(),
  tags: z.array(z.string()).max(20).optional(),
  metadata: z.record(z.string(), z.unknown()).optional(),
GET/api/knowledge-base/:id

Knowledge Base Item API

GET — Get single item by ID

PATCH — Update item

DELETE — Soft delete item

Example
curl -X GET 'https://api.nexxss.com/api/knowledge-base/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
updateSchema = z.object({
  title: z.string().min(1).max(500).optional(),
  content: z.string().min(1).max(100000).optional(),
  summary: z.string().max(1000).optional(),
  tags: z.array(z.string()).max(20).optional(),
  metadata: z.record(z.string(), z.unknown()).optional(),
PATCH/api/knowledge-base/:id

Knowledge Base Item API

GET — Get single item by ID

PATCH — Update item

DELETE — Soft delete item

Example
curl -X PATCH 'https://api.nexxss.com/api/knowledge-base/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"title":"string","content":"string","summary":"string","tags":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
updateSchema = z.object({
  title: z.string().min(1).max(500).optional(),
  content: z.string().min(1).max(100000).optional(),
  summary: z.string().max(1000).optional(),
  tags: z.array(z.string()).max(20).optional(),
  metadata: z.record(z.string(), z.unknown()).optional(),
GET/api/knowledge-base/crawl-configs

Knowledge Base Crawl Configs API

GET — List crawl configs

POST — Create/update crawl config

Example
curl -X GET 'https://api.nexxss.com/api/knowledge-base/crawl-configs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
crawlConfigSchema = z.object({
  base_url: z.httpUrl(),
  max_pages: z.number().int().min(1).max(1000).optional(),
  max_depth: z.number().int().min(1).max(10).optional(),
  include_patterns: z.array(z.string()).optional(),
  exclude_patterns: z.array(z.string()).optional(),
  crawl_frequency: z.enum(["daily", "weekly", "monthly", "manual"]).optional(),
POST/api/knowledge-base/crawl-configs

Knowledge Base Crawl Configs API

GET — List crawl configs

POST — Create/update crawl config

Example
curl -X POST 'https://api.nexxss.com/api/knowledge-base/crawl-configs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"max_pages":0,"max_depth":0,"include_patterns":[],"exclude_patterns":[],"crawl_frequency":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
crawlConfigSchema = z.object({
  base_url: z.httpUrl(),
  max_pages: z.number().int().min(1).max(1000).optional(),
  max_depth: z.number().int().min(1).max(10).optional(),
  include_patterns: z.array(z.string()).optional(),
  exclude_patterns: z.array(z.string()).optional(),
  crawl_frequency: z.enum(["daily", "weekly", "monthly", "manual"]).optional(),
DELETE/api/knowledge-base/crawl-configs/:id

Knowledge Base Crawl Config Item API

DELETE — Delete a crawl config

Example
curl -X DELETE 'https://api.nexxss.com/api/knowledge-base/crawl-configs/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/knowledge-base/crawl-configs/:id/start

Knowledge Base Crawl Start API

POST — Start a crawl job for a config

Example
curl -X POST 'https://api.nexxss.com/api/knowledge-base/crawl-configs/{id}/start' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/knowledge-base/manual

Knowledge Base Manual Entry API

POST — Create a manual text entry

Example
curl -X POST 'https://api.nexxss.com/api/knowledge-base/manual' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"title":"string","content":"string","summary":"string","tags":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
manualEntrySchema = z.object({
  title: z.string().min(1).max(500),
  content: z.string().min(1).max(100000),
  summary: z.string().max(1000).optional(),
  tags: z.array(z.string()).max(20).optional(),
GET/api/knowledge-base/stats

Knowledge Base Stats API

GET — Organization KB statistics

Example
curl -X GET 'https://api.nexxss.com/api/knowledge-base/stats' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

logs

1 endpoint

POST/api/logs/error

Error Logging API Endpoint

Receives client-side errors and logs them for monitoring.

Called by lib/errorLogger.ts for centralized error tracking.

SECURITY: Rate limited to prevent log injection attacks and storage abuse.

Example
curl -X POST 'https://api.nexxss.com/api/logs/error' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"message":"string","stack":"string","severity":"value"}'
Response
{
  "error": "string"
}
Zod schemas (1)
errorLogSchema = z.object({
  message: z.string().min(1).max(10000),
  stack: z.string().max(50000).optional(),
  context: z.record(z.string(), z.unknown()).optional(),
  severity: z.enum(["low", "medium", "high", "critical"]).optional().default("medium"),

macros

3 endpoints

DELETE/api/macros

GET /api/macros — list saved canned responses for the org

POST /api/macros — create one

Stored in organizations.metadata.macros = [{ id, slug, label, body }] so

we don't need a migration. Org-scoped, all teammates see the same list.

Example
curl -X DELETE 'https://api.nexxss.com/api/macros' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/macros

GET /api/macros — list saved canned responses for the org

POST /api/macros — create one

Stored in organizations.metadata.macros = [{ id, slug, label, body }] so

we don't need a migration. Org-scoped, all teammates see the same list.

Example
curl -X GET 'https://api.nexxss.com/api/macros' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/macros

GET /api/macros — list saved canned responses for the org

POST /api/macros — create one

Stored in organizations.metadata.macros = [{ id, slug, label, body }] so

we don't need a migration. Org-scoped, all teammates see the same list.

Example
curl -X POST 'https://api.nexxss.com/api/macros' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

mfa

6 endpoints

DELETE/api/mfa

MFA API Routes

Endpoints for managing Multi-Factor Authentication (TOTP).

GET /api/mfa - Get MFA status for current user

POST /api/mfa - Initialize MFA setup (returns secret and QR code URI)

DELETE /api/mfa - Disable MFA (requires password verification)

Example
curl -X DELETE 'https://api.nexxss.com/api/mfa' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"token":"string"}'
Response
{
  "success": "true",
  "data": "...",
  "enabled": "...",
  "enabledAt": "...",
  "backupCodesRemaining": "..."
}
Zod schemas (1)
DisableMFASchema = z.object({
  // Require current MFA token to disable
  token: z.string().min(6).max(20),
GET/api/mfa

MFA API Routes

Endpoints for managing Multi-Factor Authentication (TOTP).

GET /api/mfa - Get MFA status for current user

POST /api/mfa - Initialize MFA setup (returns secret and QR code URI)

DELETE /api/mfa - Disable MFA (requires password verification)

Example
curl -X GET 'https://api.nexxss.com/api/mfa' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "...",
  "enabled": "...",
  "enabledAt": "...",
  "backupCodesRemaining": "..."
}
Zod schemas (1)
DisableMFASchema = z.object({
  // Require current MFA token to disable
  token: z.string().min(6).max(20),
POST/api/mfa

MFA API Routes

Endpoints for managing Multi-Factor Authentication (TOTP).

GET /api/mfa - Get MFA status for current user

POST /api/mfa - Initialize MFA setup (returns secret and QR code URI)

DELETE /api/mfa - Disable MFA (requires password verification)

Example
curl -X POST 'https://api.nexxss.com/api/mfa' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"token":"string"}'
Response
{
  "success": "true",
  "data": "...",
  "enabled": "...",
  "enabledAt": "...",
  "backupCodesRemaining": "..."
}
Zod schemas (1)
DisableMFASchema = z.object({
  // Require current MFA token to disable
  token: z.string().min(6).max(20),
POST/api/mfa/backup-codes

MFA Backup Codes API Routes

POST /api/mfa/backup-codes - Regenerate backup codes (requires MFA verification)

Example
curl -X POST 'https://api.nexxss.com/api/mfa/backup-codes' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"token":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
RegenerateBackupCodesSchema = z.object({
  // Require current MFA token to regenerate backup codes
  // FIX: max(9) to accommodate XXXX-XXXX format (9 chars with hyphen)
  token: z.string().min(6).max(9),
POST/api/mfa/setup
Example
curl -X POST 'https://api.nexxss.com/api/mfa/setup' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
POST/api/mfa/verify

MFA Verification API Routes

POST /api/mfa/verify - Verify MFA token (for setup completion or login)

Example
curl -X POST 'https://api.nexxss.com/api/mfa/verify' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"purpose":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
VerifyMFASchema = z.object({
  token: z
    .string()
    .min(6)
    .max(20)
    .regex(/^[\dA-Za-z-]+$/, "Invalid token format"),
  // Purpose: 'setup' to complete MFA setup, 'login' to verify during login
  purpose: z.enum(["setup", "login"]).default("login"),

notifications

1 endpoint

GET/api/notifications

GET /api/notifications

Lightweight aggregation for the in-app notification bell. Returns:

- Unanswered (open) inbound conversation count

- Failed workflow runs in the last 24 hours

- Channel connections that may need attention (webhook_subscribed=false)

- Trial days remaining (if any)

Example
curl -X GET 'https://api.nexxss.com/api/notifications' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

onboarding

4 endpoints

POST/api/onboarding

Onboarding API Route

Saves user onboarding preferences after account creation.

Accepts the exact field names the wizard at /app/onboarding/page.tsx sends:

{ organizationName, industry, companySize, channels, teamEmails, website?, goals? }

Writes top-level columns on `organizations` (added in migration

20260502000001_onboarding_columns.sql) and stashes pending team invites in

settings.pending_team_invites for the invitation worker to pick up.

On successful completion, also kicks off best-effort post-onboarding work:

- industry-specific knowledge base starter pack (P7)

- background website crawl, if a website is known (P6)

Both are fire-and-forget so onboarding never blocks on slow IO.

Example
curl -X POST 'https://api.nexxss.com/api/onboarding' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"organizationName":"string","industry":"string","companySize":"string","channels":[],"teamEmails":[],"website":"string","goals":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
onboardingSchema = z.object({
  organizationName: z.string().min(1).max(200),
  industry: z.string().max(100).optional().default(""),
  companySize: z.string().max(20).optional().default(""),
  channels: z.array(z.string()).max(10).optional().default([]),
  teamEmails: z.array(z.string().email()).max(50).optional().default([]),
  website: z.string().max(500).optional(),
  goals: z.array(z.string()).max(10).optional().default([]),
POST/api/onboarding/bootstrap

POST /api/onboarding/bootstrap

First-dashboard-load bootstrap endpoint.

Performs idempotent demo-data seeding (P2). The dashboard layout calls this

once on mount; the helper below is guarded by the `demo_seeded` flag so

subsequent loads are no-ops.

Returns the seed result, but the dashboard doesn't typically render

anything from it — the demo conversation simply appears in the inbox after

the dashboard's own data fetch.

Example
curl -X POST 'https://api.nexxss.com/api/onboarding/bootstrap' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/onboarding/state

GET /api/onboarding/state — current wizard state for the auth'd user.

PATCH /api/onboarding/state — merge wizard state into users.metadata.onboarding.

The 4-step onboarding wizard at <OnboardingWizard /> uses this to:

1. Resume on the right step on reload.

2. Auto-detect "channel connected" by counting rows across

facebook_pages / telegram_bots / discord_bots / whatsapp_connections.

3. Auto-detect "workflow created" by counting rows in workflows.

4. Persist per-step completion and `dismissed` so the wizard stops

appearing once the user finishes (or explicitly closes it).

State shape stored in users.metadata.onboarding:

{

step: number, // 0..3

dismissed: boolean, // user closed the wizard

completed: string[], // step keys the user explicitly marked done

completedAt: string|null, // ISO timestamp when step 4 was reached

}

The GET response also rolls up live "done" booleans per step so the wizard

doesn't have to make additional round-trips.

Example
curl -X GET 'https://api.nexxss.com/api/onboarding/state' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string",
  "context": "..."
}
Zod schemas (1)
patchSchema = z.object({
  step: z.number().int().min(0).max(STEP_KEYS.length).optional(),
  dismissed: z.boolean().optional(),
  completed: z.array(z.enum(STEP_KEYS)).optional(),
PATCH/api/onboarding/state

GET /api/onboarding/state — current wizard state for the auth'd user.

PATCH /api/onboarding/state — merge wizard state into users.metadata.onboarding.

The 4-step onboarding wizard at <OnboardingWizard /> uses this to:

1. Resume on the right step on reload.

2. Auto-detect "channel connected" by counting rows across

facebook_pages / telegram_bots / discord_bots / whatsapp_connections.

3. Auto-detect "workflow created" by counting rows in workflows.

4. Persist per-step completion and `dismissed` so the wizard stops

appearing once the user finishes (or explicitly closes it).

State shape stored in users.metadata.onboarding:

{

step: number, // 0..3

dismissed: boolean, // user closed the wizard

completed: string[], // step keys the user explicitly marked done

completedAt: string|null, // ISO timestamp when step 4 was reached

}

The GET response also rolls up live "done" booleans per step so the wizard

doesn't have to make additional round-trips.

Example
curl -X PATCH 'https://api.nexxss.com/api/onboarding/state' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"step":0,"dismissed":true,"completed":[]}'
Response
{
  "success": "true",
  "error": "string",
  "context": "..."
}
Zod schemas (1)
patchSchema = z.object({
  step: z.number().int().min(0).max(STEP_KEYS.length).optional(),
  dismissed: z.boolean().optional(),
  completed: z.array(z.enum(STEP_KEYS)).optional(),

platform-admin

3 endpoints

GET/api/platform-admin/denied

GET /api/platform-admin/denied

Returns the last 50 cross-tenant audit_log rows with outcome=denied.

super_admin gated.

Example
curl -X GET 'https://api.nexxss.com/api/platform-admin/denied' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
GET/api/platform-admin/mrr

GET /api/platform-admin/mrr

Sums active Stripe subscriptions' price.unit_amount across all customers

to produce an instantaneous MRR figure. Tagged `stale: true` if Stripe

is not configured or the call failed.

NOTE: This treats every active subscription's unit_amount as monthly USD.

Currency normalization and recurring-interval scaling (annual → /12) are

applied below but FX is not — non-USD subs are reported in source currency

with a `stale=true` flag if encountered.

Example
curl -X GET 'https://api.nexxss.com/api/platform-admin/mrr' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "...",
  "mrrUsd": "...",
  "activeSubscriptions": "...",
  "currency": "...",
  "stale": "...",
  "reason": "..."
}
GET/api/platform-admin/overview

GET /api/platform-admin/overview

Returns top metrics + tenants table for the platform staff dashboard.

Gated on `super_admin` membership (any tenant).

Example
curl -X GET 'https://api.nexxss.com/api/platform-admin/overview' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "...",
  "metrics": "...",
  "totalTenants": "...",
  "totalUsers": "...",
  "mau": "...",
  "activeImpersonations": "..."
}

power-tools

4 endpoints

GET/api/power-tools/forms

Power Tools Forms API Routes

REST endpoints for form builder and management

Example
curl -X GET 'https://api.nexxss.com/api/power-tools/forms' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
FormFieldSchema = z.object({
  type: z.enum([
    "text",
    "email",
    "phone",
    "number",
    "textarea",
    "select",
    "checkbox",
    "radio",
    "date",
    "time",
    "file",
    "hidden",
  ]),
  label: z.string().min(1, "Field label is required").max(200),
  name: z.string().min(1).max(100).optional(),
  placeholder: z.string().max(500).optional(),
  required: z.boolean().optional().default(false),
  options: z.array(z.string()).optional(),
  validation: z
    .object({
      min: z.number().optional(),
      max: z.number().optional(),
      pattern: z.string().optional(),
      message: z.string().optional(),
    })
    .optional(),
  defaultValue: z.union([z.string(), z.number(), z.boolean()]).optional(),
CreateFormSchema = z.object({
  name: z.string().min(1, "Form name is required").max(200),
  description: z.string().max(1000).optional(),
  slug: z
    .string()
    .min(1, "Form slug is required")
    .max(100)
    .regex(/^[a-z0-9-]+$/, "Slug must contain only lowercase letters, numbers, and hyphens"),
  fields: z.array(FormFieldSchema).min(1, "At least one form field is required"),
POST/api/power-tools/forms

Power Tools Forms API Routes

REST endpoints for form builder and management

Example
curl -X POST 'https://api.nexxss.com/api/power-tools/forms' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"type":"value","label":"string","name":"string","placeholder":"string","required":true,"options":[],"min":0,"max":0}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (2)
FormFieldSchema = z.object({
  type: z.enum([
    "text",
    "email",
    "phone",
    "number",
    "textarea",
    "select",
    "checkbox",
    "radio",
    "date",
    "time",
    "file",
    "hidden",
  ]),
  label: z.string().min(1, "Field label is required").max(200),
  name: z.string().min(1).max(100).optional(),
  placeholder: z.string().max(500).optional(),
  required: z.boolean().optional().default(false),
  options: z.array(z.string()).optional(),
  validation: z
    .object({
      min: z.number().optional(),
      max: z.number().optional(),
      pattern: z.string().optional(),
      message: z.string().optional(),
    })
    .optional(),
  defaultValue: z.union([z.string(), z.number(), z.boolean()]).optional(),
CreateFormSchema = z.object({
  name: z.string().min(1, "Form name is required").max(200),
  description: z.string().max(1000).optional(),
  slug: z
    .string()
    .min(1, "Form slug is required")
    .max(100)
    .regex(/^[a-z0-9-]+$/, "Slug must contain only lowercase letters, numbers, and hyphens"),
  fields: z.array(FormFieldSchema).min(1, "At least one form field is required"),
DELETE/api/power-tools/forms/:id
Example
curl -X DELETE 'https://api.nexxss.com/api/power-tools/forms/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","description":"string","fields":[],"status":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateFormSchema = z.object({
  name: z.string().min(1).max(200).optional(),
  description: z.string().max(1000).optional().nullable(),
  slug: z
    .string()
    .min(1)
    .max(100)
    .regex(/^[a-z0-9-]+$/)
    .optional(),
  fields: z.array(z.record(z.string(), z.unknown())).optional(),
  status: z.string().max(50).optional(),
PUT/api/power-tools/forms/:id
Example
curl -X PUT 'https://api.nexxss.com/api/power-tools/forms/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","description":"string","fields":[],"status":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateFormSchema = z.object({
  name: z.string().min(1).max(200).optional(),
  description: z.string().max(1000).optional().nullable(),
  slug: z
    .string()
    .min(1)
    .max(100)
    .regex(/^[a-z0-9-]+$/)
    .optional(),
  fields: z.array(z.record(z.string(), z.unknown())).optional(),
  status: z.string().max(50).optional(),

reports

6 endpoints

GET/api/reports

Reports API Routes

CRUD for tenant report definitions backing the dashboard Reports page.

GET /api/reports - list the org's reports

POST /api/reports - create a report

The `reports` table is created by

supabase/migrations/20260607000003_create_reports_table.sql. It is not in the

generated Supabase types yet, so we widen the client with DynamicTableFallback.

Example
curl -X GET 'https://api.nexxss.com/api/reports' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/reports

Reports API Routes

CRUD for tenant report definitions backing the dashboard Reports page.

GET /api/reports - list the org's reports

POST /api/reports - create a report

The `reports` table is created by

supabase/migrations/20260607000003_create_reports_table.sql. It is not in the

generated Supabase types yet, so we widen the client with DynamicTableFallback.

Example
curl -X POST 'https://api.nexxss.com/api/reports' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/reports/:id

Single Report API Routes

GET /api/reports/[id] - fetch one report (org-scoped)

PATCH /api/reports/[id] - update fields / toggle status / duplicate

DELETE /api/reports/[id] - delete a report

PATCH supports three modes via the body:

{ ...fields } -> partial update

{ action: "toggle" } -> flip status active <-> paused

{ action: "duplicate" } -> create a copy (status draft) and return it

Example
curl -X DELETE 'https://api.nexxss.com/api/reports/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"action":"value","name":"string","description":"string","schedule":"value","status":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateReportSchema = z.object({
  action: z.enum(["toggle", "duplicate"]).optional(),
  name: z.string().min(1).max(255).optional(),
  description: z.string().max(2000).optional(),
  type: z
    .enum(["engagement", "revenue", "customers", "campaigns", "custom"])
    .optional(),
  schedule: z.enum(["daily", "weekly", "monthly", "manual"]).optional(),
  status: z.enum(["active", "paused", "draft"]).optional(),
  config: z.record(z.string(), z.unknown()).optional(),
GET/api/reports/:id

Single Report API Routes

GET /api/reports/[id] - fetch one report (org-scoped)

PATCH /api/reports/[id] - update fields / toggle status / duplicate

DELETE /api/reports/[id] - delete a report

PATCH supports three modes via the body:

{ ...fields } -> partial update

{ action: "toggle" } -> flip status active <-> paused

{ action: "duplicate" } -> create a copy (status draft) and return it

Example
curl -X GET 'https://api.nexxss.com/api/reports/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateReportSchema = z.object({
  action: z.enum(["toggle", "duplicate"]).optional(),
  name: z.string().min(1).max(255).optional(),
  description: z.string().max(2000).optional(),
  type: z
    .enum(["engagement", "revenue", "customers", "campaigns", "custom"])
    .optional(),
  schedule: z.enum(["daily", "weekly", "monthly", "manual"]).optional(),
  status: z.enum(["active", "paused", "draft"]).optional(),
  config: z.record(z.string(), z.unknown()).optional(),
PATCH/api/reports/:id

Single Report API Routes

GET /api/reports/[id] - fetch one report (org-scoped)

PATCH /api/reports/[id] - update fields / toggle status / duplicate

DELETE /api/reports/[id] - delete a report

PATCH supports three modes via the body:

{ ...fields } -> partial update

{ action: "toggle" } -> flip status active <-> paused

{ action: "duplicate" } -> create a copy (status draft) and return it

Example
curl -X PATCH 'https://api.nexxss.com/api/reports/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"action":"value","name":"string","description":"string","schedule":"value","status":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateReportSchema = z.object({
  action: z.enum(["toggle", "duplicate"]).optional(),
  name: z.string().min(1).max(255).optional(),
  description: z.string().max(2000).optional(),
  type: z
    .enum(["engagement", "revenue", "customers", "campaigns", "custom"])
    .optional(),
  schedule: z.enum(["daily", "weekly", "monthly", "manual"]).optional(),
  status: z.enum(["active", "paused", "draft"]).optional(),
  config: z.record(z.string(), z.unknown()).optional(),
POST/api/reports/:id/run

POST /api/reports/[id]/run

Records a run of a report: stamps last_run_at = now() and (if the report was

a draft) promotes it to active. Returns a pragmatic summary built from real

org data counts. A full report-generation engine is out of scope — this gives

the UI a real "last run" timestamp plus a sensible result payload.

Example
curl -X POST 'https://api.nexxss.com/api/reports/{id}/run' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
IdSchema = z.string().uuid();

interface ReportRow {
  id: string;
  type: string;
  status: string;
  name: string;
}

/**
 * Best-effort count of a table scoped to the org. Returns 0 on any error so a
 * missing/empty table never fails the run.
 */
async function safeCount(
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  sb: any,
  table: string,
  orgId: string,
): Promise<number> {
  try {
    const { count, error } = await sb
      .from(table)
      .select("id", { count: "exact", head: true })
      .eq("organization_id", orgId);
    if (error) return 0;
    return count ?? 0;
  } catch {
    return 0;
  }
}

/**
 * `messages` has no `organization_id` column — it is scoped to an org only via
 * its parent `conversations` row. Count through that relationship so the metric
 * 

settings

13 endpoints

DELETE/api/settings/account/delete

POST /api/settings/account/delete — schedule org deletion (7-day grace)

DELETE /api/settings/account/delete — cancel a pending deletion

Sets organizations.metadata.delete_pending_at and a separate cron picks

up orgs whose grace window has elapsed and hard-deletes them. We don't

delete immediately — that's a foot-gun and GDPR explicitly allows a

grace period before erasure.

Example
curl -X DELETE 'https://api.nexxss.com/api/settings/account/delete' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/settings/account/delete

POST /api/settings/account/delete — schedule org deletion (7-day grace)

DELETE /api/settings/account/delete — cancel a pending deletion

Sets organizations.metadata.delete_pending_at and a separate cron picks

up orgs whose grace window has elapsed and hard-deletes them. We don't

delete immediately — that's a foot-gun and GDPR explicitly allows a

grace period before erasure.

Example
curl -X POST 'https://api.nexxss.com/api/settings/account/delete' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/settings/api-keys

GET /api/settings/api-keys → list keys for the org (no secrets)

POST /api/settings/api-keys → mint a new key (raw key shown ONCE)

Example
curl -X GET 'https://api.nexxss.com/api/settings/api-keys' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/settings/api-keys

GET /api/settings/api-keys → list keys for the org (no secrets)

POST /api/settings/api-keys → mint a new key (raw key shown ONCE)

Example
curl -X POST 'https://api.nexxss.com/api/settings/api-keys' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/settings/api-keys/:id

DELETE /api/settings/api-keys/[id] — revoke (deactivate) a key.

Soft-revokes by setting is_active=false so we keep the audit trail.

Example
curl -X DELETE 'https://api.nexxss.com/api/settings/api-keys/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/settings/audit

GET /api/settings/audit?limit=200&since=ISO

Returns recent audit log entries for the current organization.

Example
curl -X GET 'https://api.nexxss.com/api/settings/audit' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/settings/integrations

Integrations API Route

Example
curl -X GET 'https://api.nexxss.com/api/settings/integrations' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/settings/notifications

Notification Preferences API Routes

Example
curl -X GET 'https://api.nexxss.com/api/settings/notifications' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PUT/api/settings/notifications

Notification Preferences API Routes

Example
curl -X PUT 'https://api.nexxss.com/api/settings/notifications' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/settings/organization

Organization Settings API Routes

Example
curl -X GET 'https://api.nexxss.com/api/settings/organization' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PUT/api/settings/organization

Organization Settings API Routes

Example
curl -X PUT 'https://api.nexxss.com/api/settings/organization' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/settings/profile

User Profile Settings API Routes

Example
curl -X GET 'https://api.nexxss.com/api/settings/profile' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PUT/api/settings/profile

User Profile Settings API Routes

Example
curl -X PUT 'https://api.nexxss.com/api/settings/profile' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

social

5 endpoints

GET/api/social/comments

GET /api/social/comments?status=open|replied|hidden|deleted|spam

Lists comments received via FB / IG webhook for the current organization.

Powers the moderation queue in social-hub.

Example
curl -X GET 'https://api.nexxss.com/api/social/comments' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/social/pages

GET /api/social/pages

Lists Facebook Pages (and any linked Instagram Business accounts) connected

to the current organization. Used by the social-hub admin UI.

Example
curl -X GET 'https://api.nexxss.com/api/social/pages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/social/post

POST /api/social/post

Publish a Facebook Page or Instagram Business post.

Body:

{ platform: "facebook" | "instagram",

pageId: string, // page_id from facebook_pages

content?: string, // caption / message

imageUrl?: string, // public URL of the image (required for IG)

scheduledAt?: string } // ISO timestamp for scheduled posting (FB only)

Persists a row in social_outbound_posts with status `posting` then flips to

`posted` or `failed` after the Graph API round-trip. Scheduled posts go to

status `scheduled` and are picked up by the existing cron job.

Example
curl -X POST 'https://api.nexxss.com/api/social/post' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/social/reply-comment

POST /api/social/reply-comment

Reply to a comment on a Facebook or Instagram post (or — once we wire the

adapters — TikTok / YouTube / Twitter). Updates social_comments with

status='replied' and replied_at on success.

Body:

{ commentId: string, // social_comments.id (our DB id)

message: string,

hideOriginal?: boolean, // optional: hide the comment after reply (FB only)

deleteOriginal?: boolean } // optional: delete the comment after reply

Example
curl -X POST 'https://api.nexxss.com/api/social/reply-comment' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/social/send-dm

POST /api/social/send-dm

Send a Facebook Messenger or Instagram Direct message.

Body:

{ platform: "facebook" | "instagram",

pageId: string, // page_id from facebook_pages

recipientId: string, // PSID for FB, IG-scoped id for IG

text: string,

conversationId?: string } // optional, to attach the outbound msg

Example
curl -X POST 'https://api.nexxss.com/api/social/send-dm' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

social-media

3 endpoints

GET/api/social-media/posts

Social Media Posts API Routes

REST endpoints for social media post management

Example
curl -X GET 'https://api.nexxss.com/api/social-media/posts' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
createPostSchema = z.object({
      accountIds: z.array(z.string().uuid()).min(1),
      content: z.string().min(1),
      mediaUrls: z.array(z.string().url()).optional(),
      scheduledAt: z.string().datetime().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
POST/api/social-media/posts

Social Media Posts API Routes

REST endpoints for social media post management

Example
curl -X POST 'https://api.nexxss.com/api/social-media/posts' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"accountIds":[],"content":"string","mediaUrls":[],"scheduledAt":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
createPostSchema = z.object({
      accountIds: z.array(z.string().uuid()).min(1),
      content: z.string().min(1),
      mediaUrls: z.array(z.string().url()).optional(),
      scheduledAt: z.string().datetime().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
PATCH/api/social-media/posts/:id

Single Social Media Post API Route

PATCH /api/social-media/posts/[id] - update an existing post (org-scoped)

Backs the social hub composer's "edit" flow. Only mutable columns of a single

post row are updatable here (content, media, schedule, status); the owning

account is fixed at creation time.

Example
curl -X PATCH 'https://api.nexxss.com/api/social-media/posts/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"content":"string","mediaUrls":[],"scheduledAt":"string","status":"value"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
IdSchema = z.string().uuid();

// Unknown keys (e.g. the composer's `platforms`/`hashtags`) are stripped by
// default — only the columns below are applied.
const UpdatePostSchema = z.object({
  content: z.string().min(1).max(63206).optional(),
  mediaUrls: z.array(z.string().url()).optional(),
  // `null` explicitly clears a previously stored schedule.
  scheduledAt: z.string().nullable().optional(),
  status: z.enum(["draft", "scheduled", "published", "failed"]).optional(),

status

1 endpoint

GET/api/status

GET /api/status

Public status endpoint. Pings each subsystem (Supabase / Redis / AI gateway)

and returns ok / degraded / down. No auth — used by /status and external

monitors.

Example
curl -X GET 'https://api.nexxss.com/api/status' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "...",
  "checkedAt": "..."
}

storage

6 endpoints

POST/api/storage
Example
curl -X POST 'https://api.nexxss.com/api/storage' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
GET/api/storage/files

Storage Files API Routes

GET - List user's files (metadata for first 50)

POST - Upload a file (multipart/form-data)

Example
curl -X GET 'https://api.nexxss.com/api/storage/files' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/storage/files

Storage Files API Routes

GET - List user's files (metadata for first 50)

POST - Upload a file (multipart/form-data)

Example
curl -X POST 'https://api.nexxss.com/api/storage/files' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/storage/files/:id

Storage File Detail API Routes

GET - Get file metadata and signed download URL

DELETE - Delete a file

Example
curl -X DELETE 'https://api.nexxss.com/api/storage/files/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/storage/files/:id

Storage File Detail API Routes

GET - Get file metadata and signed download URL

DELETE - Delete a file

Example
curl -X GET 'https://api.nexxss.com/api/storage/files/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/storage/quota

Storage Quota API Route

GET - Get storage quota for the authenticated user

Example
curl -X GET 'https://api.nexxss.com/api/storage/quota' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

stripe

3 endpoints

DELETE/api/stripe/checkout

Stripe Checkout API Route

Endpoint for creating and managing Stripe checkout sessions

Example
curl -X DELETE 'https://api.nexxss.com/api/stripe/checkout' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"ui_mode":"value","redirect_on_completion":"value","line_items":[],"currency":"string","product_data":{},"name":"string","description":"string","images":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
createCheckoutSessionSchema = z.object({
  ui_mode: z.enum(["embedded", "hosted"]).optional(),
  redirect_on_completion: z.enum(["always", "if_required", "never"]).optional(),
  line_items: z.array(
    z
      .object({
        price_data: z
          .object({
            currency: z.string(),
            product_data: z.object({
              name: z.string(),
              description: z.string().optional(),
              images: z.array(z.string()).optional(),
            }),
            unit_amount: z.number(),
            recurring: z
              .object({
                interval: z.enum(["day", "week", "month", "year"]),
                interval_count: z.number().optional(),
              })
              .optional(),
          })
          .optional(),
        price: z.string().optional(),
        quantity:
GET/api/stripe/checkout

Stripe Checkout API Route

Endpoint for creating and managing Stripe checkout sessions

Example
curl -X GET 'https://api.nexxss.com/api/stripe/checkout' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
createCheckoutSessionSchema = z.object({
  ui_mode: z.enum(["embedded", "hosted"]).optional(),
  redirect_on_completion: z.enum(["always", "if_required", "never"]).optional(),
  line_items: z.array(
    z
      .object({
        price_data: z
          .object({
            currency: z.string(),
            product_data: z.object({
              name: z.string(),
              description: z.string().optional(),
              images: z.array(z.string()).optional(),
            }),
            unit_amount: z.number(),
            recurring: z
              .object({
                interval: z.enum(["day", "week", "month", "year"]),
                interval_count: z.number().optional(),
              })
              .optional(),
          })
          .optional(),
        price: z.string().optional(),
        quantity:
POST/api/stripe/checkout

Stripe Checkout API Route

Endpoint for creating and managing Stripe checkout sessions

Example
curl -X POST 'https://api.nexxss.com/api/stripe/checkout' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"ui_mode":"value","redirect_on_completion":"value","line_items":[],"currency":"string","product_data":{},"name":"string","description":"string","images":[]}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
createCheckoutSessionSchema = z.object({
  ui_mode: z.enum(["embedded", "hosted"]).optional(),
  redirect_on_completion: z.enum(["always", "if_required", "never"]).optional(),
  line_items: z.array(
    z
      .object({
        price_data: z
          .object({
            currency: z.string(),
            product_data: z.object({
              name: z.string(),
              description: z.string().optional(),
              images: z.array(z.string()).optional(),
            }),
            unit_amount: z.number(),
            recurring: z
              .object({
                interval: z.enum(["day", "week", "month", "year"]),
                interval_count: z.number().optional(),
              })
              .optional(),
          })
          .optional(),
        price: z.string().optional(),
        quantity:

subscriptions

3 endpoints

POST/api/subscriptions/change

Subscription Change API

POST — Preview/process a subscription plan change

Example
curl -X POST 'https://api.nexxss.com/api/subscriptions/change' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/subscriptions/current

Current Subscription API

GET — Get the current subscription for the authenticated organization

Example
curl -X GET 'https://api.nexxss.com/api/subscriptions/current' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/subscriptions/plans

Subscription Plans API

GET — List all available subscription plans (public)

Example
curl -X GET 'https://api.nexxss.com/api/subscriptions/plans' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}

team

4 endpoints

GET/api/team/members

GET /api/team/members — list users in the current org

POST /api/team/members — invite a new teammate (creates the user row,

sends a magic-link email if SMTP is configured)

Example
curl -X GET 'https://api.nexxss.com/api/team/members' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/team/members

GET /api/team/members — list users in the current org

POST /api/team/members — invite a new teammate (creates the user row,

sends a magic-link email if SMTP is configured)

Example
curl -X POST 'https://api.nexxss.com/api/team/members' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/team/members/:id

PATCH /api/team/members/[id] — change a teammate's role

DELETE /api/team/members/[id] — remove a teammate from the organization

Only callers with the `users:write` permission can mutate. Removing the

last owner is blocked.

Example
curl -X DELETE 'https://api.nexxss.com/api/team/members/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
PATCH/api/team/members/:id

PATCH /api/team/members/[id] — change a teammate's role

DELETE /api/team/members/[id] — remove a teammate from the organization

Only callers with the `users:write` permission can mutate. Removing the

last owner is blocked.

Example
curl -X PATCH 'https://api.nexxss.com/api/team/members/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

v1

5 endpoints

GET/api/v1/conversations

Public REST API — conversations

GET /api/v1/conversations?status=open&limit=50

Auth: `Authorization: Bearer nx_<prefix>_<secret>`

Example
curl -X GET 'https://api.nexxss.com/api/v1/conversations' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/v1/customers

Public REST API — customers

GET /api/v1/customers?limit=100 → list customers

POST /api/v1/customers → create a customer

Auth: `Authorization: Bearer nx_<prefix>_<secret>`

Example
curl -X GET 'https://api.nexxss.com/api/v1/customers' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/v1/customers

Public REST API — customers

GET /api/v1/customers?limit=100 → list customers

POST /api/v1/customers → create a customer

Auth: `Authorization: Bearer nx_<prefix>_<secret>`

Example
curl -X POST 'https://api.nexxss.com/api/v1/customers' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/v1/openapi.json

GET /api/v1/openapi.json

OpenAPI 3.1 spec for the public REST API. Used by the Swagger viewer at

/docs/api and by external tools (Postman, code generators).

Example
curl -X GET 'https://api.nexxss.com/api/v1/openapi.json' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
GET/api/v1/workflows

Public REST API — workflows

GET /api/v1/workflows?limit=50

Auth: `Authorization: Bearer nx_<prefix>_<secret>`

Example
curl -X GET 'https://api.nexxss.com/api/v1/workflows' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}

voice

6 endpoints

GET/api/voice/calls

Voice Calls API Routes

List and initiate voice calls

Example
curl -X GET 'https://api.nexxss.com/api/voice/calls' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
InitiateCallSchema = z.object({
      to_number: z.string().regex(/^\+[1-9]\d{1,14}$/, "Invalid phone number format (E.164)"),
      from_number: z
        .string()
        .regex(/^\+[1-9]\d{1,14}$/)
        .optional(),
      customer_id: z.string().uuid().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
POST/api/voice/calls

Voice Calls API Routes

List and initiate voice calls

Example
curl -X POST 'https://api.nexxss.com/api/voice/calls' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"to_number":"string","customer_id":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
InitiateCallSchema = z.object({
      to_number: z.string().regex(/^\+[1-9]\d{1,14}$/, "Invalid phone number format (E.164)"),
      from_number: z
        .string()
        .regex(/^\+[1-9]\d{1,14}$/)
        .optional(),
      customer_id: z.string().uuid().optional(),
      metadata: z.record(z.string(), z.unknown()).optional(),
POST/api/voice/recording
Example
curl -X POST 'https://api.nexxss.com/api/voice/recording' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/voice/status
Example
curl -X POST 'https://api.nexxss.com/api/voice/status' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/voice/twiml/:organizationId
Example
curl -X GET 'https://api.nexxss.com/api/voice/twiml/{organizationId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/voice/twiml/:organizationId
Example
curl -X POST 'https://api.nexxss.com/api/voice/twiml/{organizationId}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred

webhooks

35 endpoints

GET/api/webhooks/analytics
Example
curl -X GET 'https://api.nexxss.com/api/webhooks/analytics' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/webhooks/calendar/google

Google Calendar Webhook Handler

Handles push notifications from Google Calendar API.

Google sends notifications when calendar events change.

Setup:

1. Create a watch channel via Google Calendar API

2. Point notification URL to this endpoint

3. Google sends POST with channel headers (no body for sync messages)

Routes:

POST /api/webhooks/calendar/google

Security:

- Validates channel token from headers

- Rate limited to 500 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/calendar/google' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
POST/api/webhooks/crm/events

CRM Events Webhook Handler

Handles incoming events from CRM systems (HubSpot, Salesforce, Pipedrive, etc.)

Normalizes events and integrates with the Smart Memory Hub.

Routes:

POST /api/webhooks/crm/events

OPTIONS - CORS preflight

Security:

- HMAC signature or API key authentication

- Rate limited to 500 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/crm/events' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
POST/api/webhooks/customer-success/events

Customer Success Events Webhook Handler

Handles lifecycle events for customer success tracking:

- Onboarding milestones

- Feature adoption events

- Usage threshold alerts

- Health score changes

- Churn risk signals

- NPS/CSAT survey responses

Routes:

POST /api/webhooks/customer-success/events

OPTIONS - CORS preflight

Security:

- API key or HMAC signature authentication

- Rate limited to 400 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/customer-success/events' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
GET/api/webhooks/data-deletion

Meta Data-Deletion Callback.

Meta's app-review compliance requirement: when a Facebook user revokes our

app's access or requests deletion, Meta sends a `signed_request` POST to

this endpoint. The signed_request is a JWT-like format:

<base64url(hmac-sha256(payload, app_secret))>.<base64url(payload)>

We MUST:

1. Verify the signature using FACEBOOK_APP_SECRET (timing-safe).

2. Extract the `user_id` (FB-scoped) from the payload.

3. Insert a row in data_deletion_requests so an admin/cron can complete

the deletion within 30 days.

4. Respond with JSON containing a `url` for the confirmation status page

and a `confirmation_code` (must be unique, ≤ 36 chars) per Meta spec.

Reference:

https://developers.facebook.com/docs/development/create-an-app/app-dashboard/data-deletion-callback

Example
curl -X GET 'https://api.nexxss.com/api/webhooks/data-deletion' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "error": "string"
}
POST/api/webhooks/data-deletion

Meta Data-Deletion Callback.

Meta's app-review compliance requirement: when a Facebook user revokes our

app's access or requests deletion, Meta sends a `signed_request` POST to

this endpoint. The signed_request is a JWT-like format:

<base64url(hmac-sha256(payload, app_secret))>.<base64url(payload)>

We MUST:

1. Verify the signature using FACEBOOK_APP_SECRET (timing-safe).

2. Extract the `user_id` (FB-scoped) from the payload.

3. Insert a row in data_deletion_requests so an admin/cron can complete

the deletion within 30 days.

4. Respond with JSON containing a `url` for the confirmation status page

and a `confirmation_code` (must be unique, ≤ 36 chars) per Meta spec.

Reference:

https://developers.facebook.com/docs/development/create-an-app/app-dashboard/data-deletion-callback

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/data-deletion' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "error": "string"
}
POST/api/webhooks/discord

Discord Interactions Webhook Handler

Handles incoming interactions from Discord via the Interactions Endpoint URL.

Discord sends interactions (slash commands, components, modals) via HTTP POST

instead of the Gateway when configured as an Interactions Endpoint.

Setup:

1. Set the Interactions Endpoint URL in Discord Developer Portal:

https://discord.com/developers/applications/<APP_ID>/information

→ Interactions Endpoint URL: <YOUR_DOMAIN>/api/webhooks/discord

2. Discord will send a PING to verify the endpoint. This handler responds

correctly to the verification challenge.

Security:

- Validates Ed25519 signatures using the Discord application public key

- Rate limited to 200 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/discord' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "error": "string"
}
POST/api/webhooks/email/events/:provider

Email Events Webhook Handler (Multi-Provider)

Handles email delivery events (bounces, complaints, opens, clicks, etc.)

from SendGrid, Postmark, and Mailgun.

Routes:

POST /api/webhooks/email/events/sendgrid

POST /api/webhooks/email/events/postmark

POST /api/webhooks/email/events/mailgun

OPTIONS - CORS preflight

Security:

- Provider-specific signature verification

- Rate limited to 1000 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/email/events/{provider}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
POST/api/webhooks/email/inbound/:provider

Email Inbound Webhook Handler (Multi-Provider)

Dynamic route handling inbound email parsing from SendGrid, Postmark, and Mailgun.

Each provider sends a different payload format; this handler normalizes them.

Routes:

POST /api/webhooks/email/inbound/sendgrid

POST /api/webhooks/email/inbound/postmark

POST /api/webhooks/email/inbound/mailgun

OPTIONS - CORS preflight

Security:

- Provider-specific signature verification

- Rate limited to 500 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/email/inbound/{provider}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
GET/api/webhooks/endpoints

Webhook Endpoints API

GET - List webhook endpoints for the authenticated organization

POST - Create a new webhook endpoint

Example
curl -X GET 'https://api.nexxss.com/api/webhooks/endpoints' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateWebhookSchema = z.object({
  url: z.string().url("Invalid URL format"),
  events: z
    .array(z.string())
    .min(1, "At least one event type is required")
    .refine(
      (events) => events.every((e) => VALID_EVENT_TYPES.has(e)),
      "Invalid event type(s)",
    ),
  description: z.string().max(500).optional(),
POST/api/webhooks/endpoints

Webhook Endpoints API

GET - List webhook endpoints for the authenticated organization

POST - Create a new webhook endpoint

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/endpoints' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"url":"string","description":"string"}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
CreateWebhookSchema = z.object({
  url: z.string().url("Invalid URL format"),
  events: z
    .array(z.string())
    .min(1, "At least one event type is required")
    .refine(
      (events) => events.every((e) => VALID_EVENT_TYPES.has(e)),
      "Invalid event type(s)",
    ),
  description: z.string().max(500).optional(),
DELETE/api/webhooks/endpoints/:id

Webhook Endpoint by ID API

GET - Get a single webhook endpoint

PATCH - Update a webhook endpoint

DELETE - Delete a webhook endpoint

Example
curl -X DELETE 'https://api.nexxss.com/api/webhooks/endpoints/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/webhooks/endpoints/:id

Webhook Endpoint by ID API

GET - Get a single webhook endpoint

PATCH - Update a webhook endpoint

DELETE - Delete a webhook endpoint

Example
curl -X GET 'https://api.nexxss.com/api/webhooks/endpoints/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PATCH/api/webhooks/endpoints/:id

Webhook Endpoint by ID API

GET - Get a single webhook endpoint

PATCH - Update a webhook endpoint

DELETE - Delete a webhook endpoint

Example
curl -X PATCH 'https://api.nexxss.com/api/webhooks/endpoints/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/webhooks/endpoints/:id/test

Webhook Endpoint Test API

POST - Send a test event to a webhook endpoint

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/endpoints/{id}/test' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/webhooks/events
Example
curl -X GET 'https://api.nexxss.com/api/webhooks/events' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/webhooks/facebook

Facebook + Instagram unified webhook receiver.

GET → Meta verification challenge (hub.mode=subscribe).

POST → message and feed events. Handles:

- Page Messenger DMs (object=page)

- Instagram Direct DMs (object=instagram)

- Page comment changes (object=page, field=feed)

- Instagram comment changes (object=instagram, field=comments)

Each event is verified with X-Hub-Signature-256 against FACEBOOK_APP_SECRET,

then routed to the right per-tenant handler. Inbound DMs become rows in

messaging_messages; inbound comments become rows in social_comments.

Example
curl -X GET 'https://api.nexxss.com/api/webhooks/facebook' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/webhooks/facebook

Facebook + Instagram unified webhook receiver.

GET → Meta verification challenge (hub.mode=subscribe).

POST → message and feed events. Handles:

- Page Messenger DMs (object=page)

- Instagram Direct DMs (object=instagram)

- Page comment changes (object=page, field=feed)

- Instagram comment changes (object=instagram, field=comments)

Each event is verified with X-Hub-Signature-256 against FACEBOOK_APP_SECRET,

then routed to the right per-tenant handler. Inbound DMs become rows in

messaging_messages; inbound comments become rows in social_comments.

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/facebook' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
POST/api/webhooks/forms

Form Submissions Webhook Handler

Handles incoming form submissions from external form providers

and custom forms. Supports lead scoring and routing.

Routes:

POST /api/webhooks/forms

OPTIONS - CORS preflight

Security:

- Dual auth: HMAC signature OR API key

- Rate limited to 200 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/forms' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
GET/api/webhooks/meta/ads

Meta Marketing API webhook receiver — "Create & manage ads" use case.

GET → Meta verification challenge (hub.mode=subscribe).

POST → ad-account / campaign / adset / ad / async-request events.

Subscribed object: `application` (selected in the Meta App Dashboard under

Use cases → Create & manage ads → Webhooks → Select product: Application).

Common subscribed fields:

- ad_account — settings, spend cap, status changes

- adcampaign_status — campaign lifecycle changes

- adset_status — ad set lifecycle changes

- ad_status — ad lifecycle changes

- async_request_completed

- async_session_completed

- adimage

Signature is verified with X-Hub-Signature-256 against FACEBOOK_APP_SECRET.

The Page/IG webhook lives separately at /app/api/webhooks/facebook because

the payload shapes and tenant-resolution paths are different.

Tenant resolution: Marketing API webhooks identify themselves by ad-account

id buried inside `change.value`. Multi-tenant routing requires a lookup

table (e.g. `meta_ad_accounts: ad_account_id → organization_id`); until

that exists, events are logged and routed to the org named by

META_DEFAULT_ORGANIZATION_ID (single-tenant fallback). Returning 200 even

when the tenant is unknown is intentional — Meta retries 5xx aggressively.

Example
curl -X GET 'https://api.nexxss.com/api/webhooks/meta/ads' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/webhooks/meta/ads

Meta Marketing API webhook receiver — "Create & manage ads" use case.

GET → Meta verification challenge (hub.mode=subscribe).

POST → ad-account / campaign / adset / ad / async-request events.

Subscribed object: `application` (selected in the Meta App Dashboard under

Use cases → Create & manage ads → Webhooks → Select product: Application).

Common subscribed fields:

- ad_account — settings, spend cap, status changes

- adcampaign_status — campaign lifecycle changes

- adset_status — ad set lifecycle changes

- ad_status — ad lifecycle changes

- async_request_completed

- async_session_completed

- adimage

Signature is verified with X-Hub-Signature-256 against FACEBOOK_APP_SECRET.

The Page/IG webhook lives separately at /app/api/webhooks/facebook because

the payload shapes and tenant-resolution paths are different.

Tenant resolution: Marketing API webhooks identify themselves by ad-account

id buried inside `change.value`. Multi-tenant routing requires a lookup

table (e.g. `meta_ad_accounts: ad_account_id → organization_id`); until

that exists, events are logged and routed to the org named by

META_DEFAULT_ORGANIZATION_ID (single-tenant fallback). Returning 200 even

when the tenant is unknown is intentional — Meta retries 5xx aggressively.

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/meta/ads' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
POST/api/webhooks/payments/:provider

Payment Webhook Handler

Handles Stripe/PayPal/Square/Braintree webhooks with signature verification.

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/payments/{provider}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/webhooks/registry

Webhook Registry Handler

Centralized webhook endpoint registry with health monitoring.

Lists all webhook endpoints and provides health check capabilities.

Routes:

GET /api/webhooks/registry - List all registered endpoints

POST /api/webhooks/registry - Run health checks on endpoints

OPTIONS - CORS preflight

Security:

- Requires internal auth (INTERNAL_AUTH_SECRET or CRON_SECRET)

- Rate limited to 50 req/min per IP

Example
curl -X GET 'https://api.nexxss.com/api/webhooks/registry' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
// response shape not inferred
POST/api/webhooks/registry

Webhook Registry Handler

Centralized webhook endpoint registry with health monitoring.

Lists all webhook endpoints and provides health check capabilities.

Routes:

GET /api/webhooks/registry - List all registered endpoints

POST /api/webhooks/registry - Run health checks on endpoints

OPTIONS - CORS preflight

Security:

- Requires internal auth (INTERNAL_AUTH_SECRET or CRON_SECRET)

- Rate limited to 50 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/registry' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
GET/api/webhooks/social/:platform

Social Media Webhook Handler (Multi-Platform)

Handles incoming webhooks from social media platforms:

- Facebook/Instagram (Meta Graph API)

- Twitter/X (Account Activity API)

Routes:

GET /api/webhooks/social/facebook - Hub challenge verification

GET /api/webhooks/social/twitter - CRC challenge verification

POST /api/webhooks/social/facebook - Facebook/Instagram events

POST /api/webhooks/social/instagram - Instagram events (alias for facebook)

POST /api/webhooks/social/twitter - Twitter events

Security:

- Platform-specific signature verification

- Rate limited to 500 req/min per IP

Example
curl -X GET 'https://api.nexxss.com/api/webhooks/social/{platform}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "error": "string"
}
POST/api/webhooks/social/:platform

Social Media Webhook Handler (Multi-Platform)

Handles incoming webhooks from social media platforms:

- Facebook/Instagram (Meta Graph API)

- Twitter/X (Account Activity API)

Routes:

GET /api/webhooks/social/facebook - Hub challenge verification

GET /api/webhooks/social/twitter - CRC challenge verification

POST /api/webhooks/social/facebook - Facebook/Instagram events

POST /api/webhooks/social/instagram - Instagram events (alias for facebook)

POST /api/webhooks/social/twitter - Twitter events

Security:

- Platform-specific signature verification

- Rate limited to 500 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/social/{platform}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "error": "string"
}
POST/api/webhooks/stripe

Stripe Webhook Handler

Dedicated endpoint for Stripe webhook events.

Handles subscription lifecycle, invoice, and checkout events.

Configure this URL in Stripe Dashboard:

https://your-domain.com/api/webhooks/stripe

Required env: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/stripe' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "error": "string"
}
POST/api/webhooks/telegram

Telegram Webhook Handler

Handles incoming webhooks from Telegram Bot API

- POST: Incoming messages, commands, and callback queries

Setup:

Set the webhook URL in Telegram via:

https://api.telegram.org/bot<TOKEN>/setWebhook?url=<YOUR_DOMAIN>/api/webhooks/telegram?token=<TOKEN_HASH>

Security:

- Validates the `token` query parameter against a hash of the bot token

- Rate limited to 200 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/telegram' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "error": "string"
}
POST/api/webhooks/telnyx/recording

Telnyx Call Recording Webhook Handler

Handles incoming webhooks from Telnyx for call recording events

- POST: Processes call.recording.saved events

Flow:

1. Verify Telnyx signature

2. Store webhook event for observability

3. Check for duplicate events (Redis deduplication)

4. Store recording metadata in call_recordings table

5. Return 200 OK to acknowledge receipt

@see https://developers.telnyx.com/docs/v2/call-control/recording
Example
curl -X POST 'https://api.nexxss.com/api/webhooks/telnyx/recording' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/webhooks/twilio

Twilio Webhook Handler

Handles incoming webhooks from Twilio

- POST: Incoming SMS/MMS messages and voice callbacks

Supports:

- SMS/MMS incoming messages

- Voice call status callbacks

- Recording callbacks

Security:

- Validates X-Twilio-Signature header using AUTH_TOKEN

- Rate limited to 200 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/twilio' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "error": "string"
}
POST/api/webhooks/twilio/sms

Twilio SMS Webhook Handler

Handles inbound SMS messages and delivery status callbacks from Twilio.

Returns TwiML responses for inbound messages.

Endpoints:

POST /api/webhooks/twilio/sms - Receive inbound SMS or delivery status

Security:

- Validates Twilio request signature (HMAC-SHA1)

- Rate limited to 300 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/twilio/sms' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
POST/api/webhooks/twilio/voice

Twilio Voice Webhook Handler

Handles inbound/outbound voice calls, recordings, and transcriptions.

Returns TwiML responses for call flow control.

Endpoints:

POST /api/webhooks/twilio/voice - Incoming calls, status, recordings

Security:

- Validates Twilio request signature (HMAC-SHA1)

- Rate limited to 200 req/min per IP

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/twilio/voice' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
// response shape not inferred
GET/api/webhooks/whatsapp

WhatsApp Webhook Handler

Handles incoming webhooks from WhatsApp Business API (Cloud API)

- GET: Webhook verification (challenge-response)

- POST: Incoming messages and status updates

Example
curl -X GET 'https://api.nexxss.com/api/webhooks/whatsapp' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "error": "string"
}
POST/api/webhooks/whatsapp

WhatsApp Webhook Handler

Handles incoming webhooks from WhatsApp Business API (Cloud API)

- GET: Webhook verification (challenge-response)

- POST: Incoming messages and status updates

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/whatsapp' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "error": "string"
}
POST/api/webhooks/workflow/:id

Public webhook trigger endpoint.

POST /api/webhooks/workflow/[id]?secret=<workflow-secret>

Lets external services fire a workflow. The workflow must:

- have trigger_type = "webhook"

- have status = "active"

- have a webhook secret (auto-generated on first save)

The full request body is exposed to step templating as `{{trigger.<key>}}`.

No CSRF protection or org auth — the secret IS the auth. Rate limiting is

applied via the same path-based limiter the rest of the API uses (per IP +

per workflow).

Example
curl -X POST 'https://api.nexxss.com/api/webhooks/workflow/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

widget

9 endpoints

GET/api/widget/analytics

Widget Analytics API Route

Returns analytics for the organization's widget

Example
curl -X GET 'https://api.nexxss.com/api/widget/analytics' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/widget/config

Widget Config API Route (Authenticated)

Get and update widget configuration for the current organization

Example
curl -X GET 'https://api.nexxss.com/api/widget/config' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateWidgetSchema = z.object({
      name: z.string().min(1).max(255).optional(),
      domain: z.string().url().optional(),
      theme: z
        .object({
          primaryColor: z
            .string()
            .regex(/^#[0-9A-Fa-f]{6}$/)
            .optional(),
          position: z.enum(["bottom-right", "bottom-left"]).optional(),
          showLauncher: z.boolean().optional(),
          launcherIcon: z.string().optional(),
        })
        .optional(),
      behavior: z
        .object({
          greeting: z.string().max(500).optional(),
          offlineMessage: z.string().max(500).optional(),
          collectEmail: z.boolean().optional(),
          showTypingIndicator: z.boolean().optional(),
        })
        .optional(),
      ai: z
        .object({
          enabled: z.boolean().optional
POST/api/widget/config

Widget Config API Route (Authenticated)

Get and update widget configuration for the current organization

Example
curl -X POST 'https://api.nexxss.com/api/widget/config' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","domain":"string","position":"value","showLauncher":true,"launcherIcon":"string","greeting":"string","offlineMessage":"string","collectEmail":true}'
Response
{
  "success": "true",
  "error": "string"
}
Zod schemas (1)
UpdateWidgetSchema = z.object({
      name: z.string().min(1).max(255).optional(),
      domain: z.string().url().optional(),
      theme: z
        .object({
          primaryColor: z
            .string()
            .regex(/^#[0-9A-Fa-f]{6}$/)
            .optional(),
          position: z.enum(["bottom-right", "bottom-left"]).optional(),
          showLauncher: z.boolean().optional(),
          launcherIcon: z.string().optional(),
        })
        .optional(),
      behavior: z
        .object({
          greeting: z.string().max(500).optional(),
          offlineMessage: z.string().max(500).optional(),
          collectEmail: z.boolean().optional(),
          showTypingIndicator: z.boolean().optional(),
        })
        .optional(),
      ai: z
        .object({
          enabled: z.boolean().optional
GET/api/widget/config/:key

Public Widget Configuration API

Public endpoint for loading widget configuration by embed key.

No authentication required - used by embedded widget script.

Example
curl -X GET 'https://api.nexxss.com/api/widget/config/{key}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
GET/api/widget/embed

Widget Embed Script API Route

Returns the embed script for the organization's widget

Example
curl -X GET 'https://api.nexxss.com/api/widget/embed' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/widget/rotate-key

Widget Key Rotation API Route

POST - Generate a new widget key for the organization

Example
curl -X POST 'https://api.nexxss.com/api/widget/rotate-key' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/widget/sessions

Widget Chat Sessions API

Public endpoint for creating chat sessions.

Used by embedded widget to initiate conversations.

Example
curl -X POST 'https://api.nexxss.com/api/widget/sessions' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"widgetKey":"string","visitorId":"string","pageUrl":"string","pageTitle":"string","referrer":"string","userAgent":"string","timezone":"string","language":"string"}'
Response
{
  "error": "string",
  "details": "..."
}
Zod schemas (1)
createSessionSchema = z.object({
  widgetKey: z.string().min(10),
  visitorId: z.string().optional(),
  metadata: z
    .object({
      pageUrl: z.string().url().optional(),
      pageTitle: z.string().max(500).optional(),
      referrer: z.string().max(500).optional(),
      userAgent: z.string().max(500).optional(),
      timezone: z.string().max(50).optional(),
      language: z.string().max(10).optional(),
    })
    .optional(),
GET/api/widget/sessions/:sessionId/messages

Widget Chat Messages API

Public endpoints for sending and receiving messages in a chat session.

Used by embedded widget for real-time conversation.

SECURITY: Rate limiting is applied to prevent abuse from public endpoints.

Example
curl -X GET 'https://api.nexxss.com/api/widget/sessions/{sessionId}/messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (1)
sendMessageSchema = z.object({
  content: z.string().min(1).max(4000),
  type: z.enum(["text", "file", "image"]).optional().default("text"),
POST/api/widget/sessions/:sessionId/messages

Widget Chat Messages API

Public endpoints for sending and receiving messages in a chat session.

Used by embedded widget for real-time conversation.

SECURITY: Rate limiting is applied to prevent abuse from public endpoints.

Example
curl -X POST 'https://api.nexxss.com/api/widget/sessions/{sessionId}/messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"content":"string","type":"value"}'
Response
{
  "success": "true",
  "data": "..."
}
Zod schemas (1)
sendMessageSchema = z.object({
  content: z.string().min(1).max(4000),
  type: z.enum(["text", "file", "image"]).optional().default("text"),

widgets

5 endpoints

GET/api/widgets

Widget Management API

Admin endpoints for managing chatbot widgets.

Requires authentication and organization context.

Example
curl -X GET 'https://api.nexxss.com/api/widgets' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/widgets

Widget Management API

Admin endpoints for managing chatbot widgets.

Requires authentication and organization context.

Example
curl -X POST 'https://api.nexxss.com/api/widgets' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/widgets/:id

Individual Widget API

Endpoints for managing a specific widget.

Requires authentication and organization context.

Example
curl -X DELETE 'https://api.nexxss.com/api/widgets/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/widgets/:id

Individual Widget API

Endpoints for managing a specific widget.

Requires authentication and organization context.

Example
curl -X GET 'https://api.nexxss.com/api/widgets/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PATCH/api/widgets/:id

Individual Widget API

Endpoints for managing a specific widget.

Requires authentication and organization context.

Example
curl -X PATCH 'https://api.nexxss.com/api/widgets/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}

workflows

12 endpoints

GET/api/workflows

Workflow Automation API

GET - List workflows for the organization

POST - Create a new workflow

Example
curl -X GET 'https://api.nexxss.com/api/workflows' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/workflows

Workflow Automation API

GET - List workflows for the organization

POST - Create a new workflow

Example
curl -X POST 'https://api.nexxss.com/api/workflows' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
DELETE/api/workflows/:id

Workflow Automation API - Single Workflow

GET - Get a single workflow by ID

PATCH - Update a workflow

DELETE - Delete a workflow

Example
curl -X DELETE 'https://api.nexxss.com/api/workflows/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/workflows/:id

Workflow Automation API - Single Workflow

GET - Get a single workflow by ID

PATCH - Update a workflow

DELETE - Delete a workflow

Example
curl -X GET 'https://api.nexxss.com/api/workflows/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
PATCH/api/workflows/:id

Workflow Automation API - Single Workflow

GET - Get a single workflow by ID

PATCH - Update a workflow

DELETE - Delete a workflow

Example
curl -X PATCH 'https://api.nexxss.com/api/workflows/{id}' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/workflows/:id/analytics

GET /api/workflows/[id]/analytics?range=7d|30d|all

Aggregates `workflow_runs` for the given workflow into:

- total runs

- success rate (succeeded / total)

- average duration (ms)

- top failed step types

- p95 duration (ms)

- daily run counts (for sparkline)

Used by the workflow detail dialog and a future analytics page.

Example
curl -X GET 'https://api.nexxss.com/api/workflows/{id}/analytics' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/workflows/:id/duplicate

POST /api/workflows/[id]/duplicate

Clones an existing workflow as a new draft. The duplicate keeps the same

trigger, steps, edges, and visual layout, but is renamed "<original> (copy)"

and is created with status="draft" so the user can review before activating.

If the original is webhook-triggered, a fresh secret is generated for the

clone so the two workflows don't share an auth secret.

Example
curl -X POST 'https://api.nexxss.com/api/workflows/{id}/duplicate' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/workflows/:id/execute

Workflow Execution API

POST /api/workflows/[id]/execute

Runs a saved workflow now. Returns the per-step log with success/error for

each step. For long-running workflows (>~30s) consider switching to a

background queue (DBOS workflow), but the synchronous path is fine for

90% of typical use.

Example
curl -X POST 'https://api.nexxss.com/api/workflows/{id}/execute' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/workflows/:id/rotate-secret

POST /api/workflows/[id]/rotate-secret

Rotates the webhook secret on a webhook-triggered workflow. Use after a

suspected leak. Returns the new URL so the user can update external

integrations.

Example
curl -X POST 'https://api.nexxss.com/api/workflows/{id}/rotate-secret' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/workflows/:id/runs

GET /api/workflows/[id]/runs

Returns recent execution runs for a workflow, including the per-step log

(status, error, branch taken). Powers the runs viewer panel that lets users

debug their own automations.

Example
curl -X GET 'https://api.nexxss.com/api/workflows/{id}/runs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
GET/api/workflows/templates

GET /api/workflows/templates

Lists rows from the public `workflow_templates` catalogue. Optional

?category= query param performs a case-insensitive equality filter on

the category column ("All" is treated as no filter). Results are sorted

popularity-desc so the most-cloned templates surface first.

The endpoint deliberately does NOT require auth — the marketplace UI

is browsable pre-login, and RLS on the table grants anon SELECT.

Example
curl -X GET 'https://api.nexxss.com/api/workflows/templates' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
Response
{
  "success": "true",
  "error": "string"
}
POST/api/workflows/templates/:slug/clone

POST /api/workflows/templates/[slug]/clone

Clones the named workflow template into the caller's organization as a

draft workflow. Returns the new workflow id so the client can navigate

straight to /dashboard/workflows/[id] (or the builder) on success.

Mirrors the auth/permission/org-access pattern used by every other

workflow mutation route in this codebase.

Example
curl -X POST 'https://api.nexxss.com/api/workflows/templates/{slug}/clone' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "success": "true",
  "error": "string"
}