API Reference¶
The CloviCRM API lets you integrate CloviCRM into your own applications and automations.
All endpoints are served over HTTPS from https://clovicrm.clovitek.com.
Authentication¶
Authenticate every request with a Bearer token in the Authorization header. Generate a
token from your account settings on the CloviCRM dashboard.
Keep your token secret
Treat your API token like a password. Send it only over HTTPS and never commit it to source control — load it from an environment variable instead.
Responses & errors¶
All responses are JSON. Successful calls return 2xx; client errors return 4xx with a
JSON body describing the problem. Common status codes:
| Status | Meaning |
|---|---|
200 |
Success |
400 |
Bad request — check your parameters |
401 |
Missing or invalid token |
404 |
Resource not found |
429 |
Rate limit exceeded — slow down and retry |
500 |
Server error — retry or contact support |
CloviCRM API Reference¶
Status: Live backend at
http://127.0.0.1:8978(pm2clovicrm).
Source:/root/clovicrm/server.js
Public domain:clovicrm.clovitek.com
Authentication¶
All /api/* routes (except the public widget routes and /health) are protected by requireAuth middleware.
Two accepted credential types:
| Method | Cookie/Header | Notes |
|---|---|---|
| Platform SSO | cl_session cookie |
Shared CloviTek AI JWT minted by clovitek-sso at port 8991 |
| Standalone session | crm_token cookie or Authorization: Bearer <token> |
Issued by /api/auth/login or /api/auth/register |
Both are signed with JWT_SECRET from /root/.api_keys/master.env. Token lifetime is 30 days for standalone sessions. A 401 Unauthorized is returned when neither credential is present or valid.
Note: There is no separate developer/public API key system yet. All routes are application-layer routes consumed by the CloviCRM frontend and trusted internal integrations. A public REST API (Bearer API key) is planned.
Route Sections¶
- Auth Routes
- Contacts
- Companies
- Deals & Pipeline
- Tasks (CRM Reminders)
- Projects & Project Management
- AI Layer
- Public Widget API (no auth)
- Health
Auth Routes¶
POST /api/auth/register¶
Creates a new standalone CloviCRM account. Issues a crm_token cookie on success.
Auth: None required
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
email |
string | yes | Must be a valid email |
password |
string | yes | Minimum 8 characters |
name |
string | no | Display name |
Example:
curl -s -c cookies.txt -X POST https://clovicrm.clovitek.com/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"secret123","name":"Your Name"}'
400 invalid email or short password; 409 email already registered.
POST /api/auth/login¶
Signs in a standalone account. Issues a crm_token cookie.
Auth: None required
Body (JSON):
| Field | Type | Required |
|---|---|---|
email |
string | yes |
password |
string | yes |
Example:
curl -s -c cookies.txt -X POST https://clovicrm.clovitek.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"secret123"}'
401 invalid credentials.
POST /api/auth/logout¶
Clears the crm_token cookie.
Auth: None required
Parameters: None
Response:
Contacts¶
Contact kind values: investor | client | lead | partner
GET /api/contacts¶
Returns all contacts, optionally filtered.
Auth: cl_session or crm_token / Bearer
Query params:
| Param | Type | Notes |
|---|---|---|
kind |
string | Filter by investor, client, lead, or partner |
source |
string | Filter by custom.source tag (platform capture source) |
Example:
Response:{
"success": true,
"data": [
{
"id": 1, "name": "Jane Smith", "company": "Acme Inc", "email": "jane@acme.com",
"kind": "investor", "title": "GP", "owner": "you@example.com",
"stage": "intro", "status": "active", "tags": [], "custom": {},
"lastContact": "2026-06-10", "isDemo": false, "avatar": "JS"
}
]
}
400 invalid kind value.
POST /api/contacts¶
Creates a new contact.
Auth: cl_session or crm_token / Bearer
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | |
kind |
string | no | Default: lead |
email |
string | no | |
company |
string | no | |
title |
string | no | |
owner |
string | no | Defaults to authenticated user's email |
stage |
string | no | |
status |
string | no | Default: active |
tags |
string[] | no | |
custom |
object | no | Arbitrary key-value metadata |
Example:
curl -s -b cookies.txt -X POST https://clovicrm.clovitek.com/api/contacts \
-H "Content-Type: application/json" \
-d '{"name":"Bob Lee","kind":"lead","email":"bob@example.com","company":"StartupCo"}'
400 name is required.
POST /api/contacts/upsert¶
Idempotent upsert by (kind, email). If a matching record exists, it is updated (with shallow custom merge). If a client kind is submitted and a lead with the same email exists, that lead is promoted to client instead of creating a duplicate.
Auth: cl_session or crm_token / Bearer
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
email |
string | yes | Lookup key |
name |
string | yes | |
kind |
string | no | Default: lead |
source |
string | no | Stored in custom.source for per-platform views |
company, title, owner, stage, status |
string | no | |
custom |
object | no | Shallowly merged with existing custom |
is_demo |
boolean | no |
Response:
-created: true — new record inserted-
promoted: true — lead promoted to client
Errors: 400 email or name missing.
PATCH /api/contacts/:id¶
Updates one or more fields of an existing contact.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Body (JSON) — any subset of:
name, email, company, title, owner, stage, status, kind, tags (array), custom (object)
Example:
curl -s -b cookies.txt -X PATCH https://clovicrm.clovitek.com/api/contacts/42 \
-H "Content-Type: application/json" \
-d '{"stage":"qualified","status":"active"}'
400 no fields provided; 404 contact not found.
DELETE /api/contacts/:id¶
Deletes a contact.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Response:
GET /api/contacts/export¶
Downloads contacts as a CSV file.
Auth: cl_session or crm_token / Bearer
Query params:
| Param | Type | Notes |
|---|---|---|
kind |
string | Optional filter |
Response: Content-Type: text/csv download
Columns: id, name, email, company, kind, title, owner, stage, status, tags (pipe-delimited), lastContact
Errors: 400 invalid kind value.
POST /api/contacts/import¶
Imports contacts from a CSV. Deduplicates by (kind, email) via upsert. Rows without email are always inserted.
Auth: cl_session or crm_token / Bearer
Content-Type: text/csv (body = raw CSV) or application/json with { "csv": "..." }
CSV columns (case-insensitive): name (required), email, company, kind, title, owner, stage, status, tags (pipe or semicolon separated)
Example:
curl -s -b cookies.txt -X POST https://clovicrm.clovitek.com/api/contacts/import \
-H "Content-Type: text/csv" \
--data-binary @contacts.csv
400 no CSV provided, missing header row, or no name column.
GET /api/contacts/:id/activities¶
Returns the activity log for a contact (most recent first, up to 200 entries).
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Response:
{
"success": true,
"data": [
{ "id": 1, "actor": "you@example.com", "type": "note", "payload": { "note": "Called them." }, "at": "2026-06-10T12:00:00Z" }
]
}
POST /api/contacts/:id/activities¶
Appends an activity entry to a contact's log and refreshes last_contact_at.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
type |
string | yes | e.g. call, email, meeting, note |
actor |
string | no | Defaults to authenticated user's email |
payload |
object | no | Arbitrary metadata |
Response (201):
Errors:400 type missing; 404 contact not found.
POST /api/contacts/:id/notes¶
Convenience shortcut — writes a type:'note' activity and refreshes last_contact_at.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Body (JSON):
| Field | Type | Required |
|---|---|---|
note or text |
string | yes |
Response (201):
Errors:400 note text missing; 404 contact not found.
GET /api/sources¶
Returns distinct custom.source values with counts. Powers the per-platform source filter dropdown.
Auth: cl_session or crm_token / Bearer
Response:
{
"success": true,
"data": [
{ "source": "manuscriptsmith", "n": 14 },
{ "source": "clovilegal", "n": 3 }
]
}
Companies¶
GET /api/companies¶
Returns all companies with their contact counts.
Auth: cl_session or crm_token / Bearer
Response:
{
"success": true,
"data": [
{ "id": 1, "name": "Acme Inc", "domain": "acme.com", "industry": "SaaS", "custom": {}, "contact_count": 3, "isDemo": false, "created_at": "..." }
]
}
POST /api/companies¶
Creates a new company record.
Auth: cl_session or crm_token / Bearer
Body (JSON):
| Field | Type | Required |
|---|---|---|
name |
string | yes |
domain |
string | no |
industry |
string | no |
custom |
object | no |
Response (201):
Errors:400 name required.
PATCH /api/companies/:id¶
Updates a company.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Body (JSON) — any subset of: name, domain, industry, custom
Response:
Errors:400 no fields; 404 not found.
DELETE /api/companies/:id¶
Deletes a company.
Auth: cl_session or crm_token / Bearer
Response:
GET /api/companies/:id/contacts¶
Returns all contacts linked to a company.
Auth: cl_session or crm_token / Bearer
Response:
POST /api/companies/:id/link-contact¶
Links a contact to a company and syncs the denormalized company label on the contact row.
Auth: cl_session or crm_token / Bearer
Path params: id (company integer)
Body (JSON):
| Field | Type | Required |
|---|---|---|
contact_id |
integer | yes |
Response:
Errors:400 contact_id required; 404 company or contact not found.
Deals & Pipeline¶
GET /api/pipeline¶
Returns the full kanban pipeline: stages with their nested deals.
Auth: cl_session or crm_token / Bearer
Query params:
| Param | Type | Notes |
|---|---|---|
view |
string | raise (investor pipeline) or operate (client pipeline); omit for all stages |
Response:
{
"success": true,
"data": {
"stages": [
{
"id": "intro", "label": "Intro", "color": "#3b82f6",
"deals": [
{ "id": 1, "title": "Series A", "value": 500000, "contact": "Jane Smith", "contact_id": 7, "probability": 30, "days": 12 }
]
}
]
}
}
POST /api/pipeline-stages¶
Idempotent upsert of a pipeline stage by id. Used by provisioning scripts to seed product-specific stages (e.g. manuscriptsmith-trial).
Auth: cl_session or crm_token / Bearer
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
id |
string | yes | Unique stage identifier |
label |
string | yes | Display label |
color |
string | no | Hex color, default #64748b |
sort_order |
integer | no | Default 0 |
Response (201):
{ "success": true, "data": { "id": "manuscriptsmith-trial", "label": "Trial", "color": "#64748b", "sort_order": 0 } }
400 id or label missing.
POST /api/deals¶
Creates a new deal and logs a deal_created activity.
Auth: cl_session or crm_token / Bearer
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
title |
string | yes | |
stage |
string | no | Pipeline stage id |
value |
number | no | Default 0 |
probability |
number | no | 0-100, default 0 |
contact_id |
integer | no |
Response (201):
{ "success": true, "data": { "id": 9, "title": "Series A", "stage": "intro", "value": 500000, "...": "..." } }
400 title required.
PATCH /api/deals/:id¶
Updates a deal (including moving it between pipeline stages). A stage_change activity is logged on stage updates.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Body (JSON) — any subset of: title, stage, value, probability, contact_id
Response:
Errors:400 no fields; 404 not found.
GET /api/stats¶
Returns high-level CRM counts for the dashboard.
Auth: cl_session or crm_token / Bearer
Response:
revenue = sum of values for deals with stage = 'closed'
- deals = count of deals NOT in stage closed
- open_tasks = count of type='task' activities where done is false
GET /api/chart/revenue¶
Returns a 30-day revenue chart dataset. This is deterministic seed data; it does not reflect live customer revenue.
Auth: cl_session or crm_token / Bearer
Response:
{
"success": true,
"data": {
"labels": ["May 13", "May 14", "..."],
"values": [1200, 800, "..."]
}
}
Tasks (CRM Reminders)¶
These are CRM reminder/follow-up tasks stored in the tasks table. They are distinct from project management tasks (see /api/pm-tasks and /api/projects/:id/tasks).
GET /api/tasks¶
Returns CRM reminder tasks with optional filters.
Auth: cl_session or crm_token / Bearer
Query params:
| Param | Type | Notes |
|---|---|---|
done |
true or false |
Filter by completion state |
contact_id |
integer | Filter by linked contact |
due |
string | overdue (past + not done), today, or upcoming (future) |
Response:
{
"success": true,
"data": [
{ "id": 1, "title": "Follow up with Jane", "contact_id": 7, "deal_id": null, "due_at": "2026-06-20T09:00:00Z", "done": false, "owner": "you@example.com", "contact_name": "Jane Smith", "created_at": "..." }
]
}
POST /api/tasks¶
Creates a CRM reminder task. Logs a task activity on the linked contact if contact_id is provided.
Auth: cl_session or crm_token / Bearer
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
title |
string | yes | |
contact_id |
integer | no | |
deal_id |
integer | no | |
due_at |
ISO datetime | no | |
done |
boolean | no | Default false |
owner |
string | no | Defaults to authenticated user's email |
Response (201):
Errors:400 title required.
PATCH /api/tasks/:id¶
Updates a CRM reminder task.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Body (JSON) — any subset of: title, due_at, done, owner, contact_id, deal_id
Response:
Errors:400 no fields; 404 not found.
DELETE /api/tasks/:id¶
Deletes a CRM reminder task.
Auth: cl_session or crm_token / Bearer
Response:
Projects & Project Management¶
CloviCRM includes a full project/task management layer (CloviProject). Database tables are pm_-prefixed to avoid collision with CRM reminder tasks.
GET /api/projects¶
Lists all projects with task counts.
Auth: cl_session or crm_token / Bearer
Response:
{
"success": true,
"data": [
{ "id": 1, "title": "Website Redesign", "description": "", "client_contact_id": 7, "client_name": "Jane Smith", "status": "active", "start_date": null, "deadline": "2026-08-01", "color": "#3d6ae0", "isDemo": false, "created_at": "...", "task_count": 5 }
]
}
POST /api/projects¶
Creates a new project.
Auth: cl_session or crm_token / Bearer
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
title |
string | yes | |
description |
string | no | |
client_contact_id |
integer | no | Links to a CRM contact |
status |
string | no | Default: active |
start_date |
date | no | |
deadline |
date | no | |
color |
string | no | Hex, default #3d6ae0 |
Response (201):
Errors:400 title required.
GET /api/projects/:id¶
Returns a full project board payload: project metadata + kanban statuses + milestones + all tasks (with assignees).
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Response:
{
"success": true,
"data": {
"project": { "id": 1, "title": "Website Redesign", "...": "..." },
"statuses": [ { "id": 1, "label": "To Do", "color": "#64748b", "sort_order": 0, "is_done": false, "project_id": null } ],
"milestones": [ { "id": 1, "project_id": 1, "title": "Beta Launch", "due_date": "2026-07-01", "sort_order": 0 } ],
"tasks": [ { "id": 10, "project_id": 1, "title": "Set up hosting", "status_id": 1, "priority": "medium", "assignees": [{"ref":"you@example.com","name":"You"}], "...": "..." } ]
}
}
404 project not found.
PATCH /api/projects/:id¶
Updates a project.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Body (JSON) — any subset of: title, description, client_contact_id, status, start_date, deadline, color
Response:
Errors:400 no fields; 404 not found.
DELETE /api/projects/:id¶
Deletes a project.
Auth: cl_session or crm_token / Bearer
Response:
GET /api/projects/:id/tasks¶
Lists all project management tasks for a project (with assignees).
Auth: cl_session or crm_token / Bearer
Response:
{ "success": true, "data": [ { "id": 10, "title": "Set up hosting", "assignees": [], "...": "..." } ] }
POST /api/projects/:id/tasks¶
Creates a task inside a project.
Auth: cl_session or crm_token / Bearer
Path params: id (project integer)
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
title |
string | yes | |
description |
string | no | |
status_id |
integer | no | Links to a pm_task_statuses row (kanban column) |
priority |
string | no | Default: medium |
milestone_id |
integer | no | |
deadline |
date | no | |
sort_order |
integer | no | Default: 0 |
context |
string | no | e.g. deal, contact |
context_id |
integer | no | ID of linked context object |
assignees |
array | no | [{ref, name}] or ["email@..."] |
Response (201):
Errors:400 title required; 404 project not found.
PATCH /api/pm-tasks/:id¶
Updates a project management task. This is also the kanban drag endpoint — update status_id and sort_order to move a card between columns. Replaces the full assignee set if assignees is provided.
Auth: cl_session or crm_token / Bearer
Path params: id (pm_task integer)
Body (JSON) — any subset of: title, description, status_id, priority, milestone_id, deadline, sort_order, context, context_id, assignees
Response:
Errors:404 task not found.
DELETE /api/pm-tasks/:id¶
Deletes a project management task.
Auth: cl_session or crm_token / Bearer
Response:
GET /api/task-statuses¶
Returns kanban column definitions. Org-level columns always included; pass project_id to also include project-specific columns.
Auth: cl_session or crm_token / Bearer
Query params:
| Param | Type | Notes |
|---|---|---|
project_id |
integer | If provided, returns org-level + project-specific columns |
Response:
{
"success": true,
"data": [ { "id": 1, "label": "To Do", "color": "#64748b", "sort_order": 0, "is_done": false, "project_id": null } ]
}
POST /api/task-statuses¶
Creates a new kanban column (task status).
Auth: cl_session or crm_token / Bearer
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
label |
string | yes | |
project_id |
integer | no | null = org-level column |
color |
string | no | Hex, default #64748b |
sort_order |
integer | no | Default 0 |
is_done |
boolean | no | Tasks in this column are treated as done |
Response (201):
Errors:400 label required.
GET /api/projects/:id/milestones¶
Lists milestones for a project.
Auth: cl_session or crm_token / Bearer
Response:
{ "success": true, "data": [ { "id": 1, "project_id": 1, "title": "Beta Launch", "due_date": "2026-07-01", "sort_order": 0 } ] }
POST /api/projects/:id/milestones¶
Creates a milestone for a project.
Auth: cl_session or crm_token / Bearer
Path params: id (project integer)
Body (JSON):
| Field | Type | Required |
|---|---|---|
title |
string | yes |
due_date |
date | no |
sort_order |
integer | no |
Response (201):
Errors:400 title required; 404 project not found.
PATCH /api/milestones/:id¶
Updates a milestone.
Auth: cl_session or crm_token / Bearer
Path params: id (integer)
Body (JSON) — any subset of: title, due_date, sort_order
Response:
Errors:400 no fields; 404 not found.
DELETE /api/milestones/:id¶
Deletes a milestone.
Auth: cl_session or crm_token / Bearer
Response:
AI Layer¶
Routes that call the crm_llm.py bridge (guarded llm_cascade). All AI routes require auth. They return 502 if the AI backend is unavailable rather than failing silently.
POST /api/ai/score-deal/:id¶
Scores a deal's close likelihood (0-100) using the AI layer and logs the result as an ai_score activity. Does not modify any deal columns.
Auth: cl_session or crm_token / Bearer
Path params: id (deal integer)
Body: None required
Response:
{
"success": true,
"deal_id": 9,
"score": 72,
"reasoning": "Deal is well-advanced with a warm contact in a buying role.",
"next_action": "Send the final proposal by Friday.",
"engine": "claude-3-haiku",
"fell_back": false
}
404 deal not found; 502 AI unavailable or unparseable output.
POST /api/ai/draft-email/:contactId¶
Drafts a personalized B2B email for a contact and logs an ai_email_draft activity.
Auth: cl_session or crm_token / Bearer
Path params: contactId (integer)
Body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
intent |
string | no | Default: "a friendly follow-up" |
Example:
curl -s -b cookies.txt -X POST https://clovicrm.clovitek.com/api/ai/draft-email/42 \
-H "Content-Type: application/json" \
-d '{"intent":"introduce our new pricing plan"}'
{
"success": true,
"contact_id": 42,
"subject": "Quick thought on your next step",
"body": "Hi Bob,\n\nI wanted to reach out about...",
"engine": "claude-3-haiku",
"fell_back": false
}
404 contact not found; 502 AI unavailable.
GET /api/ai/status¶
Probes whether the AI layer (crm_llm.py / llm_cascade) is reachable.
Auth: cl_session or crm_token / Bearer
Response:
Public Widget API (no auth)¶
These endpoints have cors({ origin: '*' }) and require no authentication. They expose read-only pipeline summary data with no contact PII.
GET /api/widget/public/pipeline¶
Returns a public summary of the deal pipeline (stage labels, deal counts, aggregate values only).
Auth: None
Response:
{
"success": true,
"data": {
"stages": [
{ "id": "intro", "label": "Intro", "color": "#3b82f6", "count": 3, "value": 150000 }
],
"total_deals": 12,
"total_value": 875000
}
}
GET /widget/¶
Renders an embeddable HTML iframe widget displaying the pipeline. No authentication required.
Auth: None (CORS open)
Query params:
| Param | Type | Notes |
|---|---|---|
mode |
string | badge (default) — single-line stat pill; card — per-stage list; panel — horizontal bar chart |
theme |
string | dark (default) or light |
Example embed:
<iframe src="https://clovicrm.clovitek.com/widget/?mode=card&theme=dark" width="300" height="200" frameborder="0"></iframe>
text/html rendered widget.
Health¶
GET /health¶
DB-aware health probe. Returns 503 if the PostgreSQL database is unreachable.
Auth: None
Response (200):
Route Index¶
| Method | Path | Auth | Category |
|---|---|---|---|
| POST | /api/auth/register |
none | Auth |
| POST | /api/auth/login |
none | Auth |
| POST | /api/auth/logout |
none | Auth |
| GET | /api/contacts |
required | Contacts |
| POST | /api/contacts |
required | Contacts |
| POST | /api/contacts/upsert |
required | Contacts |
| GET | /api/contacts/export |
required | Contacts |
| POST | /api/contacts/import |
required | Contacts |
| PATCH | /api/contacts/:id |
required | Contacts |
| DELETE | /api/contacts/:id |
required | Contacts |
| GET | /api/contacts/:id/activities |
required | Contacts |
| POST | /api/contacts/:id/activities |
required | Contacts |
| POST | /api/contacts/:id/notes |
required | Contacts |
| GET | /api/sources |
required | Contacts |
| GET | /api/companies |
required | Companies |
| POST | /api/companies |
required | Companies |
| PATCH | /api/companies/:id |
required | Companies |
| DELETE | /api/companies/:id |
required | Companies |
| GET | /api/companies/:id/contacts |
required | Companies |
| POST | /api/companies/:id/link-contact |
required | Companies |
| GET | /api/pipeline |
required | Deals |
| POST | /api/pipeline-stages |
required | Deals |
| POST | /api/deals |
required | Deals |
| PATCH | /api/deals/:id |
required | Deals |
| GET | /api/stats |
required | Deals |
| GET | /api/chart/revenue |
required | Deals |
| GET | /api/tasks |
required | Tasks |
| POST | /api/tasks |
required | Tasks |
| PATCH | /api/tasks/:id |
required | Tasks |
| DELETE | /api/tasks/:id |
required | Tasks |
| GET | /api/projects |
required | Projects |
| POST | /api/projects |
required | Projects |
| GET | /api/projects/:id |
required | Projects |
| PATCH | /api/projects/:id |
required | Projects |
| DELETE | /api/projects/:id |
required | Projects |
| GET | /api/projects/:id/tasks |
required | Projects |
| POST | /api/projects/:id/tasks |
required | Projects |
| PATCH | /api/pm-tasks/:id |
required | Projects |
| DELETE | /api/pm-tasks/:id |
required | Projects |
| GET | /api/task-statuses |
required | Projects |
| POST | /api/task-statuses |
required | Projects |
| GET | /api/projects/:id/milestones |
required | Projects |
| POST | /api/projects/:id/milestones |
required | Projects |
| PATCH | /api/milestones/:id |
required | Projects |
| DELETE | /api/milestones/:id |
required | Projects |
| POST | /api/ai/score-deal/:id |
required | AI |
| POST | /api/ai/draft-email/:contactId |
required | AI |
| GET | /api/ai/status |
required | AI |
| GET | /api/widget/public/pipeline |
none | Widget |
| GET | /widget/ |
none | Widget |
| GET | /health |
none | Health |