REST API

API Documentation

Integrate ClientPortal into your own tools and workflows. All endpoints return JSON.

Authentication

Include your JWT token in the Authorization header for all protected endpoints:

Authorization: Bearer YOUR_JWT_TOKEN

Get your token by calling POST /api/auth/login. Tokens expire after 30 days.

Base URL

https://clientportal.app

All API requests are HTTPS. HTTP requests are redirected to HTTPS.

Authentication
POST/api/auth/register

Create a new agency account

Request body
{ name, email, password, agencyName }
Response
{ token, user, agency }
POST/api/auth/login

Get a JWT token

Request body
{ email, password }
Response
{ token, user, agency }
GET/api/auth/me🔒 auth required

Get current user + agency

Response
{ user, agency }
POST/api/auth/logout🔒 auth required

Clear session cookie

Clients
GET/api/clients🔒 auth required

List all clients for the agency

Response
[{ id, name, email, company, token, _count }]
POST/api/clients🔒 auth required

Create a client (sends welcome email)

Request body
{ name, email, company? }
Response
{ id, name, email, company, token }
Projects
GET/api/projects🔒 auth required

List projects (filter by ?clientId)

POST/api/projects🔒 auth required

Create a project

Request body
{ name, description?, clientId }
GET/api/projects/:id🔒 auth required

Get project by ID

PATCH/api/projects/:id🔒 auth required

Update project name, description, or status

DELETE/api/projects/:id🔒 auth required

Delete a project

POST/api/projects/:id/complete🔒 auth required

Mark complete + notify client

Request body
{ message? }
Files
GET/api/files?projectId=🔒 auth required

List files for a project

POST/api/files🔒 auth required

Upload a file (multipart/form-data)

Request body
FormData: { file, projectId, notify? }
PATCH/api/files/:id/approve

Mark file as approved

Invoices
GET/api/invoices🔒 auth required

List all invoices

POST/api/invoices🔒 auth required

Create invoice + Stripe payment link

Request body
{ amount, currency, dueDate, clientId, sendEmail? }
GET/api/invoices/:id/pdf🔒 auth required

Get printable HTML invoice

AI & Updates
POST/api/ai🔒 auth required

Generate AI project update (GPT-4o-mini)

Request body
{ projectId }
Response
{ id, content, aiGenerated: true }
Client Portal
GET/api/portal?token=

Get all portal data for a client token

GET/api/portal/messages?token=&projectId=

Get project messages

POST/api/portal/messages

Send message as client

Request body
{ content, projectId, token }
POST/api/portal/sign/:fileId

Sign a document

Request body
{ token, signatureData, clientName?, clientEmail? }
Webhooks / Zapier
GET/api/zapier🔒 auth required

List registered webhooks

POST/api/zapier🔒 auth required

Register a webhook endpoint

Request body
{ url, events: string[] }
DELETE/api/zapier?id=🔒 auth required

Deactivate a webhook

Rate Limits

Free
100 req/min
Starter
500 req/min
Pro
2000 req/min

Rate limit headers are included in every response: X-RateLimit-Remaining, X-RateLimit-Reset