---
title: HelloCRM Public API
description: Integrator API for messages, contacts, companies, products, deals, and quotes.
version: 1.0.0
base_url: https://api.hellocrm.ai
docs_url: https://developers.hellocrm.ai
openapi: https://developers.hellocrm.ai/openapi.json
postman: https://developers.hellocrm.ai/hello-crm.postman_collection.json
---

# HelloCRM Public API

> **For humans:** [Interactive API reference](https://developers.hellocrm.ai/) · [Code samples](https://developers.hellocrm.ai/testing.html) · [Postman](https://developers.hellocrm.ai/postman.html)  
> **For AI / crawlers:** This file is the canonical Markdown description of the HelloCRM integrator API.

## Table of contents

- [Overview](#overview)
- [Authentication](#authentication)
- [Base URL and headers](#base-url-and-headers)
- [Idempotency](#idempotency)
- [Response envelope](#response-envelope)
- [Machine-readable formats](#machine-readable-formats)
- [Endpoints](#endpoints)
  - [Conversations](#conversations)
  - [Send Live Chat](#send-live-chat)
  - [Send Email](#send-email)
  - [Send SMS](#send-sms)
  - [Send WhatsApp](#send-whatsapp)
  - [Bulk Email](#bulk-email)
  - [Bulk SMS](#bulk-sms)
  - [Bulk WhatsApp](#bulk-whatsapp)
  - [Templates](#templates)
  - [Contacts](#contacts)
  - [Companies](#companies)
  - [Products](#products)
  - [Deals](#deals)
  - [Quotes](#quotes)

## Overview

HelloCRM **documented public API** for integrators: conversations, messaging (live chat, email, SMS, WhatsApp, bulk), templates, contacts, companies, products, deals, and quotes.



**Messaging — two modes (both supported):** **In conversation** — pass `conversationId` (from Conversations APIs or your CRM). **Standalone** — omit `conversationId`; pass `to` (phone or email) or `contactId` and the API finds or creates the contact and conversation. `providerId` = provider id or sending phone/email on file.



**Authentication:** `x-api-key` (team API key) or `Authorization: Bearer <jwt>` on protected routes.



**Standard success envelope** (target contract; some handlers may omit fields):

`{"success":true,"message":"string","data":{},"meta":{}}`



**Idempotency:** Send `Idempotency-Key` on creates and sensitive sends when you retry.



**Bulk outbound:** `POST /api/messages/sendBulkNewMessages` — comma-separated `to`, `channel` one of `email`, `sms`, `whatsapp` (see Bulk Email / Bulk SMS / Bulk WhatsApp folders).



Regenerated by `hellocrm-backend/scripts/generate-postman-collection.mjs` (documented routes only).

HelloCRM exposes a **documented public REST API** for integrators. Covered resources:

- **Messages** — chat, email, SMS, WhatsApp (single send and bulk campaigns)
- **Contacts** — create, update, upsert, delete
- **Companies** — create, update, delete
- **Products** — create, update, delete
- **Deals** — create, update, delete
- **Quotes** — create from a deal, update, delete

## Authentication

Send your team API key on every request:

```http
x-api-key: YOUR_TEAM_API_KEY
```

Some routes also accept:

```http
Authorization: Bearer YOUR_JWT
```

Missing or invalid credentials return **401**.

## Base URL and headers

| Item | Value |
|------|--------|
| Production base URL | `https://api.hellocrm.ai` |
| Content-Type (requests with body) | `application/json` |
| Accept | `application/json` |

Example:

```bash
curl -sS -X GET "https://api.hellocrm.ai/api/contacts" \
  -H "Accept: application/json" \
  -H "x-api-key: YOUR_TEAM_API_KEY"
```

## Idempotency

On **creates** and **message sends**, send a unique header when retries must be safe:

```http
Idempotency-Key: 01HZY8QX3K9V2B4C6D8E0F2G4H6J8K0L
```

Use a new key per logical operation (ULID, UUID, etc.).

## Response envelope

Target success shape (some handlers may omit fields):

```json
{
  "success": true,
  "message": "string",
  "data": {},
  "meta": {}
}
```

Errors use appropriate HTTP status codes with a JSON body when applicable.

## Machine-readable formats

| Format | URL |
|--------|-----|
| OpenAPI 3.0 | [https://developers.hellocrm.ai/openapi.json](https://developers.hellocrm.ai/openapi.json) |
| Postman Collection v2.1 | [https://developers.hellocrm.ai/hello-crm.postman_collection.json](https://developers.hellocrm.ai/hello-crm.postman_collection.json) |
| This Markdown file | [https://developers.hellocrm.ai/API.md](https://developers.hellocrm.ai/API.md) |
| LLMs index | [https://developers.hellocrm.ai/llms.txt](https://developers.hellocrm.ai/llms.txt) |

Regenerate Postman, OpenAPI, and this file from the repo:

```bash
cd hellocrm-backend && npm run postman:generate
```

## Endpoints

## Conversations

Obtain or create a `conversationId` for **in-conversation** messaging.

**Three options:** (1) `POST /api/conversations/getConversationByPhoneAndEmail` — find or create contact + conversation from phone/email. (2) `POST /api/contacts/create-new-conversation` — create contact (if needed) and conversation in one request. (3) `POST /api/conversations` — create conversation when you already have a `contactId`.

**Optional:** you can skip these and send standalone messages with `to` / `recipientId` — the send APIs auto-resolve contact and conversation.

### Resolve conversation by phone or email (find or create)

**POST** `/api/conversations/getConversationByPhoneAndEmail`

Full URL: `https://api.hellocrm.ai/api/conversations/getConversationByPhoneAndEmail`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Resolve conversation by phone or email (find or create)

Returns `{ data: { _id: conversationId, contactId: { ... } } }`. Creates contact/conversation if missing.

Use the returned `data._id` as `conversationId` when you need it. You can skip this call if you send messages with `to` (phone/email) instead.

**Request body fields**

Find or create contact and conversation by email and/or phone.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | string | No | Contact email (optional if `phone` provided). |
| `phone` | string | No | Contact phone in E.164 format (optional if `email` provided). |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/conversations/getConversationByPhoneAndEmail \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "email": "john.doe@example.com",
    "phone": "+1234567890"
  }'
```

**200**

Conversation and contact found or created

```json
{
  "success": true,
  "message": "Found",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "contactId": {
      "_id": "64f91a7d28ae948d8e9e8432",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "phoneNumber": "+1234567890"
    },
    "createdAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Create contact and conversation

**POST** `/api/contacts/create-new-conversation`

Full URL: `https://api.hellocrm.ai/api/contacts/create-new-conversation`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Create contact and conversation

Creates contact if missing, then creates conversation. Returns `data._id` as `conversationId`. Reuses existing contact/conversation when phone or email matches.

One call when you do not have a `contactId` yet. Returns populated conversation; use `data._id` as `conversationId`.

**Request body fields**

Create contact when missing, then create conversation. At least one of `email` or `phone` recommended.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `firstName` | string | Yes | Contact first name. |
| `lastName` | string | Yes | Contact last name. |
| `email` | string | No | Contact email. |
| `phone` | string | No | Contact phone (E.164). |
| `lifecycleStage` | string | No | e.g. Lead, Customer. Defaults to Lead when omitted. |
| `groupId` | string | No | Optional contact group id. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/contacts/create-new-conversation \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1234567890",
    "lifecycleStage": "Lead",
    "groupId": "64f91a7d28ae948d8e9e8435"
  }'
```

**200**

Contact and conversation found or created

```json
{
  "success": true,
  "message": "Found",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "contactId": {
      "_id": "64f91a7d28ae948d8e9e8432",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "phoneNumber": "+1234567890"
    },
    "createdAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Create conversation (by contactId)

**POST** `/api/conversations`

Full URL: `https://api.hellocrm.ai/api/conversations`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Create conversation (by contactId)

`POST /api/conversations` — requires an existing `contactId`. Returns `201` with new conversation or `200` if one already exists for that contact.

Use when the contact already exists. Same team-scoped uniqueness: one conversation per contact.

**Request body fields**

Create a conversation for an existing contact (one per contact per team).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `contactId` | string | Yes | Existing contact id. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/conversations \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "contactId": "64f91a7d28ae948d8e9e8430"
  }'
```

**200**

Conversation already exists

```json
{
  "success": true,
  "message": "Conversation already exist.",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "contactId": {
      "_id": "64f91a7d28ae948d8e9e8432",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "phoneNumber": "+1234567890"
    },
    "createdAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**201**

Conversation created

```json
{
  "success": true,
  "message": "Conversation created successfully.",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "contactId": {
      "_id": "64f91a7d28ae948d8e9e8432",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "phoneNumber": "+1234567890"
    },
    "createdAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Get conversation by id

**GET** `/api/conversations/{conversationId}`

Full URL: `https://api.hellocrm.ai/api/conversations/{conversationId}`

**Parameters**

- Path `conversationId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Get conversation by id

Fetch a single conversation with populated contact.

**cURL**

```bash
curl -X GET https://api.hellocrm.ai/api/conversations/CONVERSATION_ID_HERE \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Conversation found

```json
{
  "success": true,
  "message": "Conversation Found.",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "contactId": {
      "_id": "64f91a7d28ae948d8e9e8432",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "phoneNumber": "+1234567890"
    },
    "createdAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### List conversations for a contact

**GET** `/api/conversations/getAllConversationsOfContact/{contactId}`

Full URL: `https://api.hellocrm.ai/api/conversations/getAllConversationsOfContact/{contactId}`

**Parameters**

- Path `contactId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### List conversations for a contact

All conversations linked to a contact id.

**cURL**

```bash
curl -X GET https://api.hellocrm.ai/api/conversations/getAllConversationsOfContact/CONTACT_ID_HERE \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Conversations listed

```json
{
  "success": true,
  "message": "Conversations found.",
  "data": [
    {
      "_id": "64f91a7d28ae948d8e9e8430",
      "teamId": "64f91a7d28ae948d8e9e8400",
      "contactId": {
        "_id": "64f91a7d28ae948d8e9e8432",
        "name": "John Doe",
        "email": "john.doe@example.com",
        "phoneNumber": "+1234567890"
      },
      "createdAt": "2025-01-15T10:00:00.000Z"
    }
  ]
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### List messages in a conversation

**GET** `/api/messages/{conversationId}`

Full URL: `https://api.hellocrm.ai/api/messages/{conversationId}`

**Parameters**

- Path `conversationId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### List messages in a conversation

Paginated message history for a conversation (`?page=1&limit=10`, optional `channel`).

**cURL**

```bash
curl -X GET "https://api.hellocrm.ai/api/messages/CONVERSATION_ID_HERE?page=1&limit=10" \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Messages grouped by date

```json
{
  "success": true,
  "message": "Messages Found.",
  "data": [
    {
      "date": "2025-01-15",
      "messages": [
        {
          "_id": "64e90fa89e24f248d9a36e5b",
          "channel": "sms",
          "direction": "outgoing",
          "content": "Hello Jane, your appointment is scheduled.",
          "status": "sent",
          "conversationId": "64e93841f54d7026b53bb6a1",
          "contactId": "64e93829d0911c7392069abc",
          "createdAt": "2025-01-15T10:05:00.000Z"
        }
      ]
    }
  ],
  "pagination": {
    "total": 1,
    "currentPage": 1,
    "totalPages": 1,
    "hasMore": false
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Send Live Chat

Send live chat on channel `chat`. **Two ways to target the recipient:** (1) **In conversation** — pass `conversationId` (and optionally `contactId`). (2) **Standalone** — omit `conversationId`; pass `contactId` or `to` (phone). (`recipientId` is accepted as an alias for `contactId`.)

### Send a live chat message

**POST** `/api/messages/sendLiveMessage`

Full URL: `https://api.hellocrm.ai/api/messages/sendLiveMessage`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Send a live chat message

Supports **in-conversation** (`conversationId`) or **standalone** (`contactId` or `to`). `channel` must be `chat`. Attachment `mediaType`: image, video, audio, file, or empty string.

**In conversation:** `conversationId` (+ optional `contactId`). **Standalone:** `contactId` or `to` (phone). `recipientId` works as an alias for `contactId`. `channel` must be `chat`.

**Request body fields**

**Targeting (pick one mode):** In conversation — `conversationId` (optional `contactId`). Standalone — `to` (phone) or `contactId`. **Also accepted:** `recipientId` (same value as `contactId`, legacy alias). **Always send:** `channel: chat`, `content`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `conversationId` | string | No | In-conversation mode. |
| `contactId` | string | No | HelloCRM contact id (who receives the message). |
| `to` | string | No | Standalone mode — recipient phone (E.164). |
| `content` | string | Yes | Message text. Merge fields supported. |
| `channel` | enum (`chat`) | Yes | Must be `chat`. |
| `mediaUrl` | string | No | Top-level media URL (optional). |
| `mediaType` | string | No | Top-level media type (optional). |
| `source` | string | No | e.g. `widget`, `web`. |
| `attachments` | array | No | Optional file attachments. |

**cURL — In conversation**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendLiveMessage \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "conversationId": "64f91a7d28ae948d8e9e8430",
    "contactId": "64f91a7d28ae948d8e9e8432",
    "content": "Hello, {{contact.name}}! Please find the attached file.",
    "channel": "chat",
    "mediaUrl": null,
    "mediaType": null,
    "source": "widget",
    "attachments": []
  }'
```

**cURL — Standalone (no conversationId)**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendLiveMessage \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "to": "+15551234567",
    "content": "Hello! Thanks for reaching out via chat.",
    "channel": "chat",
    "mediaUrl": null,
    "mediaType": null,
    "source": "widget",
    "attachments": []
  }'
```

**200**

Message sent successfully

```json
{
  "success": true,
  "message": "Message sent successfully",
  "data": {
    "_id": "64e90fa89e24f248d9a36e5b",
    "channel": "chat",
    "direction": "outgoing",
    "content": "Hello Jane, your appointment is scheduled.",
    "status": "sent",
    "conversationId": "64e93841f54d7026b53bb6a1",
    "contactId": "64e93829d0911c7392069abc",
    "createdAt": "2025-01-15T10:05:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Send Email

Send email on channel `email`. **In conversation:** `conversationId` + `recipientIds`. **Standalone:** omit `conversationId`; use `to` (email) and/or `recipientIds`. `providerId` = provider id or provider email.

### Send an email message

**POST** `/api/messages/sendEmailMessage`

Full URL: `https://api.hellocrm.ai/api/messages/sendEmailMessage`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Send an email message

**In conversation** or **standalone** — see folder description. `providerId` = provider id or provider email.

**In conversation:** `conversationId` + `recipientIds`. **Standalone:** `to` (email) and/or `recipientIds` without `conversationId`.

**Request body fields**

**Targeting:** In conversation — `conversationId` + `recipientIds`. Standalone — `to` (email) and/or `recipientIds` without `conversationId`. **Required:** `channel`, `subject`, `content`, `providerId`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `conversationId` | string | No | In-conversation mode. |
| `recipientIds` | array | No | Contact ids to receive the email. |
| `to` | string | No | Standalone — recipient email address. |
| `channel` | enum (`email`) | Yes | Must be `email`. |
| `subject` | string | Yes | Email subject line. |
| `content` | string | Yes | HTML email body. |
| `mediaUrl` | string | No | Optional. |
| `mediaType` | string | No | Optional. |
| `source` | string | No | e.g. `web`, `HelloCRM`. |
| `providerId` | string | Yes | Provider id or provider email. |
| `attachments` | array | No |  |
| `replyToMessageId` | string | No | Reply threading — HelloCRM message id. |
| `quotedMessageId` | string | No | External Message-Id for threading. |
| `threadId` | string | No | Provider thread id (e.g. Gmail). |

**cURL — In conversation**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendEmailMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "conversationId": "64d82f8f90b04f2b9c343b7a",
    "recipientIds": ["64c1e942d0911c73920693bd"],
    "channel": "email",
    "subject": "Test Email Subject",
    "content": "<p>Hello {{contact.firstName}}, this is a test email.</p>",
    "mediaUrl": "",
    "mediaType": "",
    "source": "web",
    "providerId": "64db8124cb0a330f257cb0c2",
    "attachments": [],
    "replyToMessageId": "64e90fa89e24f248d9a36e5b",
    "quotedMessageId": "<quoted-msg-id@example.com>",
    "threadId": "<thread-id-from-gmail>"
  }'
```

**cURL — Standalone (no conversationId)**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendEmailMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "jane.doe@example.com",
    "channel": "email",
    "subject": "Hello from HelloCRM",
    "content": "<p>Hi Jane, this email was sent without a prior conversation id.</p>",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "attachments": []
  }'
```

**200**

Messages sent successfully

```json
{
  "success": true,
  "message": "Messages sent successfully",
  "data": {
    "_id": "64e90fa89e24f248d9a36e5b",
    "channel": "email",
    "direction": "outgoing",
    "content": "Hello Jane, your appointment is scheduled.",
    "status": "sent",
    "conversationId": "64e93841f54d7026b53bb6a1",
    "contactId": "64e93829d0911c7392069abc",
    "createdAt": "2025-01-15T10:05:00.000Z",
    "subject": "Test Email Subject"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Send SMS

Send SMS via `POST /api/messages/sendMessage` (`channel: "sms"`). **In conversation:** `conversationId` (+ optional `contactId`). **Standalone:** `to` (phone) — contact/conversation created if needed. `providerId` = provider id or sending number.

### Send an SMS message / Send a WhatsApp message

**POST** `/api/messages/sendMessage`

Full URL: `https://api.hellocrm.ai/api/messages/sendMessage`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Send an SMS message

**Standalone example** in body; see docs for **in-conversation** variant with `conversationId`. `channel` must be `sms`.

**In conversation:** `conversationId` (+ optional `contactId`). **Standalone:** `to` (phone) — contact/conversation auto-resolved. `providerId` = provider id or sending number.

**Request body fields**

**Targeting:** `conversationId` **or** `to` (phone) **or** `contactId`. (`recipientId` is accepted as an alias for `contactId`.) **Required:** `channel`, `content`, `providerId`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `conversationId` | string | No | In-conversation mode. |
| `contactId` | string | No | HelloCRM contact id (who receives the SMS). |
| `to` | string | No | Standalone — recipient E.164 phone. |
| `channel` | enum (`sms`) | Yes | Must be `sms`. |
| `content` | string | Yes | SMS body text. |
| `mediaUrl` | string | No | Optional MMS media URL. |
| `mediaType` | string | No | Optional media type. |
| `source` | string | No | Source label. |
| `providerId` | string | Yes | Provider id or sending phone number. |

**cURL — In conversation**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "conversationId": "64f91a7d28ae948d8e9e8430",
    "contactId": "64f91a7d28ae948d8e9e8432",
    "channel": "sms",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "+15559876543"
  }'
```

**cURL — Standalone (no conversationId)**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567",
    "channel": "sms",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "+15559876543"
  }'
```

**200 — Send an SMS message**

Message sent successfully

```json
{
  "success": true,
  "message": "Message sent successfully",
  "data": {
    "_id": "64e90fa89e24f248d9a36e5b",
    "channel": "sms",
    "direction": "outgoing",
    "content": "Hello Jane, your appointment is scheduled.",
    "status": "sent",
    "conversationId": "64e93841f54d7026b53bb6a1",
    "contactId": "64e93829d0911c7392069abc",
    "createdAt": "2025-01-15T10:05:00.000Z"
  }
}
```

**400 — Send an SMS message**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Send an SMS message**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Send an SMS message**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Send an SMS message**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Send a WhatsApp message

**Standalone example** in body; see docs for **in-conversation** variant. Template fields optional when using approved templates.

Same targeting as SMS. Template fields optional when using approved WhatsApp templates.

**Request body fields**

Same targeting rules as SMS. Template fields required for template/marketing sends.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `conversationId` | string | No | In-conversation mode. |
| `contactId` | string | No | HelloCRM contact id (who receives the message). |
| `to` | string | No | Standalone — recipient E.164 phone. |
| `channel` | enum (`whatsapp`) | Yes | Must be `whatsapp`. |
| `content` | string | Yes | Message body or template fallback text. |
| `mediaUrl` | string | No | Optional. |
| `mediaType` | string | No | Optional. |
| `source` | string | No | Source label. |
| `providerId` | string | Yes | Provider id or WhatsApp sending number. |
| `templateId` | string | No | HelloCRM WhatsApp template id. |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |

**cURL — In conversation**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "conversationId": "64f91a7d28ae948d8e9e8430",
    "contactId": "64f91a7d28ae948d8e9e8432",
    "channel": "whatsapp",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "+15559876543",
    "templateId": "646b8124cb0a330f257cb010",
    "headerParameters": [{ "type": "text", "text": "Hey" }],
    "bodyParameters": [{ "type": "text", "text": "Hey body" }]
  }'
```

**cURL — Standalone (no conversationId)**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567",
    "channel": "whatsapp",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "+15559876543",
    "templateId": "646b8124cb0a330f257cb010",
    "headerParameters": [{ "type": "text", "text": "Hey" }],
    "bodyParameters": [{ "type": "text", "text": "Hey body" }]
  }'
```

**200 — Send a WhatsApp message**

Message sent successfully

```json
{
  "success": true,
  "message": "Message sent successfully",
  "data": {
    "_id": "64e90fa89e24f248d9a36e5b",
    "channel": "whatsapp",
    "direction": "outgoing",
    "content": "Hello Jane, your appointment is scheduled.",
    "status": "sent",
    "conversationId": "64e93841f54d7026b53bb6a1",
    "contactId": "64e93829d0911c7392069abc",
    "createdAt": "2025-01-15T10:05:00.000Z"
  }
}
```

**400 — Send a WhatsApp message**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Send a WhatsApp message**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Send a WhatsApp message**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Send a WhatsApp message**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Send WhatsApp

Send WhatsApp via `POST /api/messages/sendMessage` (`channel: "whatsapp"`). Same targeting as SMS: **in conversation** (`conversationId`) or **standalone** (`to`). Template fields for approved templates.

### Send an SMS message / Send a WhatsApp message

**POST** `/api/messages/sendMessage`

Full URL: `https://api.hellocrm.ai/api/messages/sendMessage`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Send an SMS message

**Standalone example** in body; see docs for **in-conversation** variant with `conversationId`. `channel` must be `sms`.

**In conversation:** `conversationId` (+ optional `contactId`). **Standalone:** `to` (phone) — contact/conversation auto-resolved. `providerId` = provider id or sending number.

**Request body fields**

**Targeting:** `conversationId` **or** `to` (phone) **or** `contactId`. (`recipientId` is accepted as an alias for `contactId`.) **Required:** `channel`, `content`, `providerId`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `conversationId` | string | No | In-conversation mode. |
| `contactId` | string | No | HelloCRM contact id (who receives the SMS). |
| `to` | string | No | Standalone — recipient E.164 phone. |
| `channel` | enum (`sms`) | Yes | Must be `sms`. |
| `content` | string | Yes | SMS body text. |
| `mediaUrl` | string | No | Optional MMS media URL. |
| `mediaType` | string | No | Optional media type. |
| `source` | string | No | Source label. |
| `providerId` | string | Yes | Provider id or sending phone number. |

**cURL — In conversation**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "conversationId": "64f91a7d28ae948d8e9e8430",
    "contactId": "64f91a7d28ae948d8e9e8432",
    "channel": "sms",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "+15559876543"
  }'
```

**cURL — Standalone (no conversationId)**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567",
    "channel": "sms",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "+15559876543"
  }'
```

**200 — Send an SMS message**

Message sent successfully

```json
{
  "success": true,
  "message": "Message sent successfully",
  "data": {
    "_id": "64e90fa89e24f248d9a36e5b",
    "channel": "sms",
    "direction": "outgoing",
    "content": "Hello Jane, your appointment is scheduled.",
    "status": "sent",
    "conversationId": "64e93841f54d7026b53bb6a1",
    "contactId": "64e93829d0911c7392069abc",
    "createdAt": "2025-01-15T10:05:00.000Z"
  }
}
```

**400 — Send an SMS message**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Send an SMS message**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Send an SMS message**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Send an SMS message**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Send a WhatsApp message

**Standalone example** in body; see docs for **in-conversation** variant. Template fields optional when using approved templates.

Same targeting as SMS. Template fields optional when using approved WhatsApp templates.

**Request body fields**

Same targeting rules as SMS. Template fields required for template/marketing sends.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `conversationId` | string | No | In-conversation mode. |
| `contactId` | string | No | HelloCRM contact id (who receives the message). |
| `to` | string | No | Standalone — recipient E.164 phone. |
| `channel` | enum (`whatsapp`) | Yes | Must be `whatsapp`. |
| `content` | string | Yes | Message body or template fallback text. |
| `mediaUrl` | string | No | Optional. |
| `mediaType` | string | No | Optional. |
| `source` | string | No | Source label. |
| `providerId` | string | Yes | Provider id or WhatsApp sending number. |
| `templateId` | string | No | HelloCRM WhatsApp template id. |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |

**cURL — In conversation**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "conversationId": "64f91a7d28ae948d8e9e8430",
    "contactId": "64f91a7d28ae948d8e9e8432",
    "channel": "whatsapp",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "+15559876543",
    "templateId": "646b8124cb0a330f257cb010",
    "headerParameters": [{ "type": "text", "text": "Hey" }],
    "bodyParameters": [{ "type": "text", "text": "Hey body" }]
  }'
```

**cURL — Standalone (no conversationId)**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendMessage \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567",
    "channel": "whatsapp",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "+15559876543",
    "templateId": "646b8124cb0a330f257cb010",
    "headerParameters": [{ "type": "text", "text": "Hey" }],
    "bodyParameters": [{ "type": "text", "text": "Hey body" }]
  }'
```

**200 — Send a WhatsApp message**

Message sent successfully

```json
{
  "success": true,
  "message": "Message sent successfully",
  "data": {
    "_id": "64e90fa89e24f248d9a36e5b",
    "channel": "whatsapp",
    "direction": "outgoing",
    "content": "Hello Jane, your appointment is scheduled.",
    "status": "sent",
    "conversationId": "64e93841f54d7026b53bb6a1",
    "contactId": "64e93829d0911c7392069abc",
    "createdAt": "2025-01-15T10:05:00.000Z"
  }
}
```

**400 — Send a WhatsApp message**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Send a WhatsApp message**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Send a WhatsApp message**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Send a WhatsApp message**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Bulk Email

Bulk email campaign. Endpoint: `POST /api/messages/sendBulkNewMessages` with `channel: "email"` and comma-separated emails in `to`.

### Bulk send email / Bulk send SMS / Bulk send WhatsApp

**POST** `/api/messages/sendBulkNewMessages`

Full URL: `https://api.hellocrm.ai/api/messages/sendBulkNewMessages`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Bulk send email

Queues a bulk email campaign. `to` is comma-separated emails; requires `providerId`.

**Request body fields**

Queue a bulk email campaign to comma-separated addresses in `to`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`email`) | Yes | Must be `email`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `subject` | string | Yes | Email subject for all recipients. |
| `preheader` | string | No | Optional inbox preheader. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "alice@example.com,bob@example.com",
    "channel": "email",
    "subject": "Bulk campaign subject",
    "preheader": "",
    "content": "<p>Hello {{contact.firstName}}, this is a bulk email.</p>",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send email**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send email**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send email**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send email**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send email**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Bulk send SMS

Queues bulk SMS. `to` is comma-separated phone numbers; `channel` must be `sms`.

**Request body fields**

Queue bulk SMS to comma-separated E.164 numbers in `to`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`sms`) | Yes | Must be `sms`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567,+15559876543",
    "channel": "sms",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send SMS**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send SMS**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send SMS**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send SMS**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send SMS**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Bulk send WhatsApp

Queues bulk WhatsApp. Same endpoint as bulk SMS; set `channel` to `whatsapp`.

**Request body fields**

Queue bulk WhatsApp. Use `templateId` and parameter arrays for template messages.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`whatsapp`) | Yes | Must be `whatsapp`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567,+15559876543",
    "channel": "whatsapp",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "templateId": "646b8124cb0a330f257cb010",
    "headerParameters": [{ "type": "text", "text": "Hey" }],
    "bodyParameters": [{ "type": "text", "text": "Hey body" }],
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send WhatsApp**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send WhatsApp**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send WhatsApp**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send WhatsApp**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send WhatsApp**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Bulk SMS

Bulk SMS campaign. Endpoint: `POST /api/messages/sendBulkNewMessages` with `channel: "sms"` and comma-separated phone numbers in `to`.

### Bulk send email / Bulk send SMS / Bulk send WhatsApp

**POST** `/api/messages/sendBulkNewMessages`

Full URL: `https://api.hellocrm.ai/api/messages/sendBulkNewMessages`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Bulk send email

Queues a bulk email campaign. `to` is comma-separated emails; requires `providerId`.

**Request body fields**

Queue a bulk email campaign to comma-separated addresses in `to`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`email`) | Yes | Must be `email`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `subject` | string | Yes | Email subject for all recipients. |
| `preheader` | string | No | Optional inbox preheader. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "alice@example.com,bob@example.com",
    "channel": "email",
    "subject": "Bulk campaign subject",
    "preheader": "",
    "content": "<p>Hello {{contact.firstName}}, this is a bulk email.</p>",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send email**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send email**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send email**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send email**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send email**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Bulk send SMS

Queues bulk SMS. `to` is comma-separated phone numbers; `channel` must be `sms`.

**Request body fields**

Queue bulk SMS to comma-separated E.164 numbers in `to`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`sms`) | Yes | Must be `sms`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567,+15559876543",
    "channel": "sms",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send SMS**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send SMS**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send SMS**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send SMS**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send SMS**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Bulk send WhatsApp

Queues bulk WhatsApp. Same endpoint as bulk SMS; set `channel` to `whatsapp`.

**Request body fields**

Queue bulk WhatsApp. Use `templateId` and parameter arrays for template messages.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`whatsapp`) | Yes | Must be `whatsapp`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567,+15559876543",
    "channel": "whatsapp",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "templateId": "646b8124cb0a330f257cb010",
    "headerParameters": [{ "type": "text", "text": "Hey" }],
    "bodyParameters": [{ "type": "text", "text": "Hey body" }],
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send WhatsApp**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send WhatsApp**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send WhatsApp**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send WhatsApp**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send WhatsApp**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Bulk WhatsApp

Bulk WhatsApp campaign. Endpoint: `POST /api/messages/sendBulkNewMessages` with `channel: "whatsapp"` and comma-separated phone numbers in `to`.

### Bulk send email / Bulk send SMS / Bulk send WhatsApp

**POST** `/api/messages/sendBulkNewMessages`

Full URL: `https://api.hellocrm.ai/api/messages/sendBulkNewMessages`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Bulk send email

Queues a bulk email campaign. `to` is comma-separated emails; requires `providerId`.

**Request body fields**

Queue a bulk email campaign to comma-separated addresses in `to`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`email`) | Yes | Must be `email`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `subject` | string | Yes | Email subject for all recipients. |
| `preheader` | string | No | Optional inbox preheader. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "alice@example.com,bob@example.com",
    "channel": "email",
    "subject": "Bulk campaign subject",
    "preheader": "",
    "content": "<p>Hello {{contact.firstName}}, this is a bulk email.</p>",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send email**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send email**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send email**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send email**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send email**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Bulk send SMS

Queues bulk SMS. `to` is comma-separated phone numbers; `channel` must be `sms`.

**Request body fields**

Queue bulk SMS to comma-separated E.164 numbers in `to`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`sms`) | Yes | Must be `sms`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567,+15559876543",
    "channel": "sms",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send SMS**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send SMS**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send SMS**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send SMS**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send SMS**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Bulk send WhatsApp

Queues bulk WhatsApp. Same endpoint as bulk SMS; set `channel` to `whatsapp`.

**Request body fields**

Queue bulk WhatsApp. Use `templateId` and parameter arrays for template messages.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | Yes | Comma-separated recipients (emails or E.164 phones depending on `channel`). |
| `channel` | enum (`whatsapp`) | Yes | Must be `whatsapp`. |
| `content` | string | Yes | Message body. Supports merge fields like `{{contact.firstName}}`. |
| `mediaUrl` | string | No | Optional media URL. |
| `mediaType` | string | No | Optional media type when `mediaUrl` is set. |
| `source` | string | No | Source label for reporting, e.g. `HelloCRM`. |
| `providerId` | string | Yes | Sending provider id, phone number, or email (must match channel). |
| `attachments` | array | No | Optional attachments. |
| `scheduleType` | enum (`now`, `scheduled`) | No | `now` sends immediately; `scheduled` uses `scheduleTime`. |
| `scheduleTime` | object | No | Used when `scheduleType` is `scheduled`. |
| `templateId` | string | No | HelloCRM template id (WhatsApp / some SMS flows). |
| `headerParameters` | array | No | WhatsApp template parameter objects (Meta format). |
| `bodyParameters` | array | No | WhatsApp template parameter objects (Meta format). |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/messages/sendBulkNewMessages \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567,+15559876543",
    "channel": "whatsapp",
    "content": "Hello {{contact.firstName}}, your appointment is scheduled.",
    "mediaUrl": "",
    "mediaType": "",
    "source": "HelloCRM",
    "providerId": "64db8124cb0a330f257cb0c2",
    "templateId": "646b8124cb0a330f257cb010",
    "headerParameters": [{ "type": "text", "text": "Hey" }],
    "bodyParameters": [{ "type": "text", "text": "Hey body" }],
    "attachments": [],
    "scheduleType": "now",
    "scheduleTime": { "date": "", "time": "" }
  }'
```

**200 — Bulk send WhatsApp**

Bulk send queued

```json
{
  "success": true,
  "message": "Send successfully"
}
```

**400 — Bulk send WhatsApp**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Bulk send WhatsApp**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Bulk send WhatsApp**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Bulk send WhatsApp**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Templates

CRUD for message templates. **Create** endpoints are split by channel (SMS, email, WhatsApp). WhatsApp create/update often uses `multipart/form-data` when a header media `file` is required; SMS and email use JSON.

### List templates

**GET** `/api/templates`

Full URL: `https://api.hellocrm.ai/api/templates`

**Parameters**

- Query `page` (required) — Page number
- Query `limit` (required) — Page size
- Query `types` (required) — Filter: sms, email, whatsapp (repeat or array per server)
- Query `statuses` (required) — Filter: pending, approved, rejected

**Headers**

- `Accept`: e.g. `application/json`

#### List templates

Paginated list. Agents see only their templates; admins see team templates.

Query `types` and `statuses` filter results. Agents see only their templates.

**cURL**

```bash
curl -X GET "https://api.hellocrm.ai/api/templates?page=1&limit=20&types=sms&statuses=approved" \
  -H "Accept: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Paginated template list

```json
{
  "success": true,
  "message": "Found.",
  "data": [
    {
      "_id": "646b8124cb0a330f257cb010",
      "templateType": "sms",
      "name": "Appointment reminder",
      "uniqueName": "appointment_reminder_sms",
      "content": "Hello {{contact.firstName}}, your appointment is on {{appointment.date}}.",
      "status": "approved",
      "category": "UTILITY",
      "language": "en"
    }
  ],
  "pagination": {
    "totalResults": 1,
    "totalPages": 1,
    "currentPage": 1,
    "limit": 20,
    "hasMore": false
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Get template by id

**GET** `/api/templates/{templateId}`

Full URL: `https://api.hellocrm.ai/api/templates/{templateId}`

**Parameters**

- Path `templateId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Get template by id

Fetch one template by id.

**cURL**

```bash
curl -X GET https://api.hellocrm.ai/api/templates/646b8124cb0a330f257cb010 \
  -H "Accept: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Single template

```json
{
  "success": true,
  "message": "Template retrieved successfully",
  "data": {
    "_id": "646b8124cb0a330f257cb010",
    "templateType": "sms",
    "name": "Appointment reminder",
    "uniqueName": "appointment_reminder_sms",
    "content": "Hello {{contact.firstName}}, your appointment is on {{appointment.date}}.",
    "status": "approved"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Create SMS template / Create email template / Create WhatsApp template

**POST** `/api/templates`

Full URL: `https://api.hellocrm.ai/api/templates`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Create SMS template

`templateType` must be `sms`. Returns `data._id` — use as `templateId` when sending messages.

Use `data._id` from the response as `templateId` in message send APIs.

**Request body fields**

`POST /api/templates` with `templateType: sms`. Response `data._id` is the template id for send APIs.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `templateType` | enum (`sms`) | Yes | Must be `sms`. |
| `name` | string | Yes | Display name in HelloCRM. |
| `uniqueName` | string | Yes | Unique slug / DLT id. |
| `content` | string | Yes | SMS body with merge fields. |
| `category` | string | No | Optional category label. |
| `language` | string | No | BCP-47 code, e.g. `en`. |
| `provider` | string | Yes | SMS provider id. |
| `variables` | array | No | Merge field keys referenced in content. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/templates \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "templateType": "sms",
    "name": "Appointment reminder",
    "uniqueName": "appointment_reminder_sms",
    "content": "Hello {{contact.firstName}}, your appointment is on {{appointment.date}}.",
    "category": "UTILITY",
    "language": "en",
    "provider": "64db8124cb0a330f257cb0c2",
    "variables": ["contact.firstName", "appointment.date"]
  }'
```

**201 — Create SMS template**

SMS template created

```json
{
  "success": true,
  "message": "Template created.",
  "data": {
    "_id": "646b8124cb0a330f257cb010",
    "templateType": "sms",
    "name": "Appointment reminder",
    "status": "approved"
  }
}
```

**400 — Create SMS template**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Create SMS template**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Create SMS template**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Create SMS template**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Create email template

`templateType` must be `email`. Include `subject` and HTML `content`.

Use `data._id` as `templateId` when referencing this template in sends.

**Request body fields**

`POST /api/templates` with `templateType: email`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `templateType` | enum (`email`) | Yes | Must be `email`. |
| `name` | string | Yes | Display name in HelloCRM. |
| `uniqueName` | string | Yes | Unique slug. |
| `subject` | string | Yes | Email subject line. |
| `content` | string | Yes | HTML email body. |
| `preheader` | string | No | Inbox preheader (optional). |
| `language` | string | No | BCP-47 code, e.g. `en`. |
| `provider` | string | Yes | Email provider id. |
| `variables` | array | No | Merge field keys referenced in subject/body. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/templates \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "templateType": "email",
    "name": "Welcome email",
    "uniqueName": "welcome_email",
    "subject": "Welcome to {{company.name}}",
    "content": "<p>Hello {{contact.firstName}}, welcome aboard.</p>",
    "language": "en",
    "provider": "64db8124cb0a330f257cb0c2",
    "variables": ["contact.firstName", "company.name"],
    "preheader": "We are glad you are here"
  }'
```

**201 — Create email template**

Email template created

```json
{
  "success": true,
  "message": "Template created.",
  "data": {
    "_id": "646b8124cb0a330f257cb011",
    "templateType": "email",
    "name": "Welcome email",
    "subject": "Welcome to Acme",
    "status": "approved"
  }
}
```

**400 — Create email template**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Create email template**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Create email template**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Create email template**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```

#### Create WhatsApp template

`templateType` must be `whatsapp`. Submitted to Meta for approval. For image/video/document headers, send `multipart/form-data` with a `file` field (see schema notes).

For image/video/document headers, use `multipart/form-data` with field `file` plus the same text fields. Status is often `pending` until Meta approves.

**Request body fields**

`POST /api/templates` with `templateType: whatsapp`. JSON shown below; use `multipart/form-data` when uploading header media (`file`). Status is usually `pending` until Meta approves.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `templateType` | enum (`whatsapp`) | Yes | Must be `whatsapp`. |
| `name` | string | Yes | Display name in HelloCRM. |
| `uniqueName` | string | Yes | Meta template name (snake_case). |
| `content` | string | Yes | Template body with {{1}} style placeholders. |
| `category` | enum (`UTILITY`, `MARKETING`, `AUTHENTICATION`) | Yes | Meta template category. |
| `language` | string | Yes | BCP-47 code, e.g. `en`. |
| `provider` | string | Yes | WhatsApp provider id. |
| `variables` | array | No | Body variable placeholders. |
| `bodyVariableSampleValues` | array | No | Sample values for Meta review. |
| `headerVariables` | array | No | Header placeholders when header is text. |
| `headerVariableSampleValues` | array | No |  |
| `isHeader` | boolean | No | Whether template includes a header. |
| `headerType` | enum (`text`, `image`, `video`, `document`) | No | Header format; non-text headers need `file` upload. |
| `headerText` | string | No | Header text when `headerType` is `text`. |
| `footer` | string | No | Optional footer line. |
| `templateButtons` | array | No | Quick reply, URL, or phone buttons (JSON string in multipart). |
| `file` | string | No | Multipart only — header media file. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/templates \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "templateType": "whatsapp",
    "name": "Appointment reminder",
    "uniqueName": "appointment_reminder_wa",
    "content": "Hello {{1}}, your appointment is on {{2}}.",
    "category": "UTILITY",
    "language": "en",
    "provider": "64db8124cb0a330f257cb0c2",
    "variables": ["{{1}}", "{{2}}"],
    "bodyVariableSampleValues": ["Jane", "May 20"],
    "isHeader": false,
    "footer": "Reply STOP to opt out"
  }'
```

**201 — Create WhatsApp template**

WhatsApp template submitted

```json
{
  "success": true,
  "message": "Template created.",
  "data": {
    "_id": "646b8124cb0a330f257cb012",
    "templateType": "whatsapp",
    "name": "Appointment reminder",
    "status": "pending"
  }
}
```

**400 — Create WhatsApp template**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401 — Create WhatsApp template**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404 — Create WhatsApp template**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500 — Create WhatsApp template**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Update template

**PUT** `/api/templates/{templateId}`

Full URL: `https://api.hellocrm.ai/api/templates/{templateId}`

**Parameters**

- Path `templateId` (required) — (Required)

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Update template

Updates template by id. WhatsApp templates sync to Meta when edited.

WhatsApp templates sync to Meta on update.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `templateType` | enum (`sms`, `email`, `whatsapp`) | Yes |  |
| `name` | string | No |  |
| `content` | string | No |  |
| `category` | string | No |  |
| `language` | string | No |  |
| `variables` | array | No |  |

**cURL**

```bash
curl -X PUT https://api.hellocrm.ai/api/templates/646b8124cb0a330f257cb010 \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "templateType": "sms",
    "name": "Appointment reminder (updated)",
    "content": "Hi {{contact.firstName}}, reminder: appointment on {{appointment.date}}.",
    "category": "UTILITY",
    "language": "en",
    "variables": ["contact.firstName", "appointment.date"]
  }'
```

**200**

Template updated

```json
{
  "success": true,
  "message": "Template updated successfully",
  "data": {
    "_id": "646b8124cb0a330f257cb010",
    "templateType": "sms",
    "name": "Appointment reminder (updated)"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Delete template

**DELETE** `/api/templates/{templateId}`

Full URL: `https://api.hellocrm.ai/api/templates/{templateId}`

**Parameters**

- Path `templateId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Delete template

Deletes template by id. WhatsApp templates are removed from Meta when applicable.

**cURL**

```bash
curl -X DELETE https://api.hellocrm.ai/api/templates/646b8124cb0a330f257cb010 \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Template deleted

```json
{
  "success": true,
  "message": "Template deleted successfully"
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Contacts

Create, update, upsert, and delete contacts.

### Create a new contact

**POST** `/api/contacts`

Full URL: `https://api.hellocrm.ai/api/contacts`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Create a new contact

`status`: open, in-progress, closed. `lifecycleStage`: Form, Live Chat, Ads, Event, CRM, Other.

`status`: open, in-progress, closed. `lifecycleStage`: Form, Live Chat, Ads, Event, CRM, Other.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `firstName` | string | Yes |  |
| `lastName` | string | Yes |  |
| `email` | string | No |  |
| `phone` | string | No | E.164 recommended. |
| `status` | enum (`open`, `in-progress`, `closed`) | No | Contact status. |
| `source` | string | No | Lead source label. |
| `lifecycleStage` | string | No | Form, Live Chat, Ads, Event, CRM, Other, Lead, Customer, etc. |
| `groupIds` | array | No | Group ids. |
| `additionalFields` | object | No | Custom field key/value map. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/contacts \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1234567890",
    "status": "open",
    "source": "Website",
    "lifecycleStage": "Lead",
    "groupIds": ["64f91a7d28ae948d8e9e8435"],
    "additionalFields": {
      "job_title": "Marketing Manager",
      "city": "New York"
    }
  }'
```

**201**

Contact created

```json
{
  "success": true,
  "message": "Contact created successfully.",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1234567890",
    "status": "open",
    "lifecycleStage": "Lead",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "createdAt": "2025-01-15T10:00:00.000Z",
    "updatedAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Update an existing contact

**PUT** `/api/contacts/{contactId}`

Full URL: `https://api.hellocrm.ai/api/contacts/{contactId}`

**Parameters**

- Path `contactId` (required) — (Required)

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Update an existing contact

Updates a contact by id.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `firstName` | string | No |  |
| `lastName` | string | No |  |
| `email` | string | No |  |
| `phone` | string | No |  |
| `status` | enum (`open`, `in-progress`, `closed`) | No |  |
| `source` | string | No |  |
| `lifecycleStage` | string | No |  |
| `groupIds` | array | No |  |
| `company` | string | No | Company id. |
| `additionalFields` | object | No |  |

**cURL**

```bash
curl -X PUT https://api.hellocrm.ai/api/contacts/CONTACT_ID_HERE \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane.doe@example.com",
    "phone": "+19876543210",
    "status": "open",
    "source": "LinkedIn",
    "lifecycleStage": "Customer",
    "groupIds": ["64f91a7d28ae948d8e9e8435"],
    "company": "64f91a7d28ae948d8e9e9999",
    "additionalFields": {
      "job_title": "CTO",
      "location": "San Francisco"
    }
  }'
```

**200**

Contact updated

```json
{
  "success": true,
  "message": "Contact updated successfully.",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1234567890",
    "status": "open",
    "lifecycleStage": "Customer",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "createdAt": "2025-01-15T10:00:00.000Z",
    "updatedAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Delete a contact by id

**DELETE** `/api/contacts/{contactId}`

Full URL: `https://api.hellocrm.ai/api/contacts/{contactId}`

**Parameters**

- Path `contactId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Delete a contact by id

Deletes a contact.

**cURL**

```bash
curl -X DELETE https://api.hellocrm.ai/api/contacts/CONTACT_ID_HERE \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Contact deleted

```json
{
  "success": true,
  "message": "Contact and associated data deleted successfully.",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1234567890",
    "status": "open",
    "lifecycleStage": "Lead",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "createdAt": "2025-01-15T10:00:00.000Z",
    "updatedAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Upsert a contact by matching rules (email/phone)

**POST** `/api/contacts/createOrUpdateContact`

Full URL: `https://api.hellocrm.ai/api/contacts/createOrUpdateContact`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Upsert a contact by matching rules (email/phone)

Use `Content-Type: application/json` (not `text/plain`).

Use `Content-Type: application/json` (not `text/plain`).

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `firstName` | string | Yes |  |
| `lastName` | string | Yes |  |
| `email` | string | No |  |
| `phone` | string | No |  |
| `status` | string | No |  |
| `source` | string | No |  |
| `lifecycleStage` | string | No |  |
| `additionalFields` | object | No |  |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/contacts/createOrUpdateContact \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1234567890",
    "status": "open",
    "source": "CRM",
    "lifecycleStage": "Lead",
    "additionalFields": {
      "job_title": "Marketing Manager",
      "city": "New York"
    }
  }'
```

**200**

Contact created or updated

```json
{
  "success": true,
  "message": "Contact created successfully.",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1234567890",
    "status": "open",
    "lifecycleStage": "Lead",
    "teamId": "64f91a7d28ae948d8e9e8400",
    "createdAt": "2025-01-15T10:00:00.000Z",
    "updatedAt": "2025-01-15T10:00:00.000Z"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Delete contacts matching an email address

**DELETE** `/api/contacts/deleteContactsByEmail`

Full URL: `https://api.hellocrm.ai/api/contacts/deleteContactsByEmail`

**Parameters**

- Query `email` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Delete contacts matching an email address

Deletes contacts for the given `email` query parameter.

**cURL**

```bash
curl -X DELETE "https://api.hellocrm.ai/api/contacts/deleteContactsByEmail?email=test@gmail.com" \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Contacts deleted by email

```json
{
  "success": true,
  "message": "Deleted 1 contact(s) and associated data successfully."
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Companies

Public API: `POST /api/companies/create`, `PUT /api/companies/edit/{companyId}`, `DELETE /api/companies/delete/{companyId}`.

### Create company

**POST** `/api/companies/create`

Full URL: `https://api.hellocrm.ai/api/companies/create`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Create company

Creates a company.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes |  |
| `domain` | string | No |  |
| `industry` | string | No |  |
| `phone` | string | No |  |
| `address` | string | No |  |
| `city` | string | No |  |
| `state` | string | No |  |
| `zip` | string | No |  |
| `country` | string | No |  |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/companies/create \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "name": "Acme Corporation",
    "domain": "acme.com",
    "industry": "Technology",
    "email": "info@acme.com",
    "phoneNumber": "+1234567890",
    "logoUrl": "https://logo.clearbit.com/acme.com",
    "address": "123 Main St",
    "city": "San Francisco",
    "state": "CA",
    "postalCode": "94105",
    "country": "USA",
    "employeeCount": 200,
    "annualRevenue": 5000000,
    "contacts": ["64f91a7d28ae948d8e9e8431"],
    "additionalFields": {
      "founded": "2005",
      "website": "https://www.acme.com"
    }
  }'
```

**201**

Company created

```json
{
  "success": true,
  "message": "Company created successfully",
  "data": {
    "_id": "64f91a7d28ae948d8e9e9999",
    "name": "Acme Corporation",
    "domain": "acme.com",
    "teamId": "64f91a7d28ae948d8e9e8400"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Update company

**PUT** `/api/companies/edit/{companyId}`

Full URL: `https://api.hellocrm.ai/api/companies/edit/{companyId}`

**Parameters**

- Path `companyId` (required) — (Required)

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Update company

Updates a company by id.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No |  |
| `domain` | string | No |  |
| `industry` | string | No |  |
| `phone` | string | No |  |
| `address` | string | No |  |
| `city` | string | No |  |
| `state` | string | No |  |
| `zip` | string | No |  |
| `country` | string | No |  |

**cURL**

```bash
curl -X PUT https://api.hellocrm.ai/api/companies/edit/COMPANY_ID_HERE \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "name": "Acme Corp International",
    "domain": "acme.com",
    "industry": "Enterprise Software",
    "additionalFields": {
      "updated_by": "Admin"
    }
  }'
```

**200**

Company updated

```json
{
  "success": true,
  "message": "Company updated successfully",
  "data": {
    "_id": "64f91a7d28ae948d8e9e9999",
    "name": "Acme Corp International",
    "domain": "acme.com",
    "teamId": "64f91a7d28ae948d8e9e8400"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Delete company

**DELETE** `/api/companies/delete/{companyId}`

Full URL: `https://api.hellocrm.ai/api/companies/delete/{companyId}`

**Parameters**

- Path `companyId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Delete company

Deletes a company by id.

**cURL**

```bash
curl -X DELETE https://api.hellocrm.ai/api/companies/delete/COMPANY_ID_HERE \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Company deleted

```json
{
  "success": true,
  "message": "Company deleted successfully"
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Products

Create, update, and delete products.

### Create a product

**POST** `/api/products`

Full URL: `https://api.hellocrm.ai/api/products`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Create a product

`billingFrequency`: one-time, weekly, every-two-weeks, monthly, quarterly, semi-annually, annually, etc.

`billingFrequency`: one-time, weekly, every-two-weeks, monthly, quarterly, semi-annually, annually, every-two-years, every-three-years, every-four-years, every-five-years.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes |  |
| `sku` | string | No |  |
| `description` | string | No |  |
| `unitPrice` | number | Yes | Sell price. |
| `unitCost` | number | No | Cost basis. |
| `billingFrequency` | enum (`one_time`, `monthly`, `quarterly`, `annually`) | No | Billing cadence. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/products \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "name": "Pro CRM Subscription",
    "sku": "PRO-CRM-001",
    "description": "Advanced CRM plan with automation and reporting",
    "billingFrequency": "monthly",
    "term": "12 months",
    "productType": "subscription",
    "imageUrl": "https://example.com/images/product.png",
    "url": "https://example.com/products/pro-crm",
    "unitCost": 20,
    "unitPrice": 50
  }'
```

**201**

Product created

```json
{
  "success": true,
  "message": "Product created successfully",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "name": "Pro CRM Subscription",
    "sku": "PRO-CRM-001",
    "unitPrice": 50,
    "unitCost": 20
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Update a product

**PUT** `/api/products/{productId}`

Full URL: `https://api.hellocrm.ai/api/products/{productId}`

**Parameters**

- Path `productId` (required) — (Required)

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Update a product

Updates a product by id.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No |  |
| `sku` | string | No |  |
| `description` | string | No |  |
| `unitPrice` | number | No |  |
| `unitCost` | number | No |  |
| `billingFrequency` | enum (`one_time`, `monthly`, `quarterly`, `annually`) | No |  |

**cURL**

```bash
curl -X PUT https://api.hellocrm.ai/api/products/PRODUCT_ID_HERE \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "name": "Pro CRM Plus",
    "sku": "PRO-CRM-002",
    "description": "Updated plan with more integrations",
    "billingFrequency": "monthly",
    "term": "12 months",
    "productType": "subscription",
    "imageUrl": "https://example.com/images/pro-crm-plus.png",
    "url": "https://example.com/products/pro-crm-plus",
    "unitCost": 25,
    "unitPrice": 60
  }'
```

**200**

Product updated

```json
{
  "success": true,
  "message": "Product updated successfully",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8430",
    "name": "Pro CRM Plus",
    "sku": "PRO-CRM-001",
    "unitPrice": 60,
    "unitCost": 20
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Delete a product

**DELETE** `/api/products/{productId}`

Full URL: `https://api.hellocrm.ai/api/products/{productId}`

**Parameters**

- Path `productId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Delete a product

Deletes a product.

**cURL**

```bash
curl -X DELETE https://api.hellocrm.ai/api/products/PRODUCT_ID_HERE \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Product deleted

```json
{
  "success": true,
  "message": "Product deleted successfully"
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Deals

Public API: `POST /api/deals/create`, `PUT /api/deals/edit/{dealId}`, `DELETE /api/deals/delete/{dealId}`.

### Create deal

**POST** `/api/deals/create`

Full URL: `https://api.hellocrm.ai/api/deals/create`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Create deal

Creates a deal.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes |  |
| `amount` | number | No |  |
| `currency` | string | No | ISO 4217, e.g. USD. |
| `pipeline` | string | Yes | Pipeline id. |
| `stage` | string | Yes | Stage id. |
| `contactId` | string | No |  |
| `companyId` | string | No |  |
| `closeDate` | string | No | ISO date string. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/deals/create \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "name": "Enterprise CRM Deal",
    "description": "Annual CRM contract",
    "amount": 50000,
    "currency": "USD",
    "pipeline": "PIPELINE_ID_HERE",
    "stage": "STAGE_ID_HERE",
    "closeDate": "2025-08-30",
    "contacts": ["CONTACT_ID_1", "CONTACT_ID_2"],
    "company": "COMPANY_ID_HERE",
    "owner": "USER_ID_HERE"
  }'
```

**200**

Deal created

```json
{
  "success": true,
  "message": "Deal created successfully",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8888",
    "name": "Enterprise CRM Deal",
    "amount": 50000,
    "currency": "USD",
    "stage": "STAGE_ID_HERE",
    "pipeline": "PIPELINE_ID_HERE"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Update deal

**PUT** `/api/deals/edit/{dealId}`

Full URL: `https://api.hellocrm.ai/api/deals/edit/{dealId}`

**Parameters**

- Path `dealId` (required) — (Required)

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Update deal

Updates a deal by id.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No |  |
| `amount` | number | No |  |
| `currency` | string | No |  |
| `pipeline` | string | No |  |
| `stage` | string | No |  |
| `contactId` | string | No |  |
| `companyId` | string | No |  |
| `closeDate` | string | No |  |

**cURL**

```bash
curl -X PUT https://api.hellocrm.ai/api/deals/edit/DEAL_ID_HERE \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -d '{
    "name": "Updated CRM Enterprise Deal",
    "description": "Updated description for annual enterprise deal",
    "amount": 60000,
    "currency": "USD",
    "pipeline": "PIPELINE_ID_HERE",
    "stage": "STAGE_ID_HERE",
    "closeDate": "2025-12-31",
    "contacts": ["CONTACT_ID_1", "CONTACT_ID_3"],
    "company": "COMPANY_ID_HERE",
    "owner": "USER_ID_HERE"
  }'
```

**200**

Deal updated

```json
{
  "success": true,
  "message": "Saved successfully",
  "data": {
    "_id": "64f91a7d28ae948d8e9e8888",
    "name": "Enterprise CRM Deal",
    "amount": 60000,
    "currency": "USD",
    "stage": "STAGE_ID_HERE",
    "pipeline": "PIPELINE_ID_HERE"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Delete deal

**DELETE** `/api/deals/delete/{dealId}`

Full URL: `https://api.hellocrm.ai/api/deals/delete/{dealId}`

**Parameters**

- Path `dealId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Delete deal

Deletes a deal (`DELETE /api/deals/delete/{dealId}`).

**cURL**

```bash
curl -X DELETE https://api.hellocrm.ai/api/deals/delete/DEAL_ID_HERE \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Deal deleted

```json
{
  "success": true,
  "message": "Deal and associated data deleted successfully"
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```



## Quotes

Create, update, delete quotes. `signatureOption`: no-signature, written-signature. `status`: draft, published, expired. `template`: default-basic.

### Create a quote from a deal

**POST** `/api/quotes`

Full URL: `https://api.hellocrm.ai/api/quotes`

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Create a quote from a deal

Creates a quote for a deal.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `dealId` | string | Yes | Deal id. |
| `template` | string | No | Quote template key, e.g. default-basic. |
| `name` | string | No | Quote title override. |

**cURL**

```bash
curl -X POST https://api.hellocrm.ai/api/quotes \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "dealId": "YOUR_DEAL_ID"
  }'
```

**201**

Quote created

```json
{
  "success": true,
  "message": "Quote created successfully",
  "data": {
    "_id": "YOUR_QUOTE_ID",
    "dealId": "YOUR_DEAL_ID",
    "name": "Enterprise CRM Deal",
    "status": "draft",
    "template": "default-basic"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Update quote presentation and terms

**PUT** `/api/quotes/{quoteId}`

Full URL: `https://api.hellocrm.ai/api/quotes/{quoteId}`

**Parameters**

- Path `quoteId` (required) — (Required)

**Headers**

- `Idempotency-Key`: Unique key for safe retries on creates and message sends.
- `Content-Type`: e.g. `application/json`
- `Accept`: e.g. `application/json`

#### Update quote presentation and terms

Updates quote fields.

`signatureOption`: no-signature, written-signature. `status`: draft, published, expired. `template`: default-basic.

**Request body fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No |  |
| `status` | enum (`draft`, `sent`, `accepted`, `declined`) | No |  |
| `template` | string | No |  |
| `terms` | string | No |  |
| `notes` | string | No |  |

**cURL**

```bash
curl -X PUT https://api.hellocrm.ai/api/quotes/YOUR_QUOTE_ID \
  -H "x-api-key: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "signatureOption": "written-signature",
    "name": "Updated Quote Name",
    "url": "https://quotes.example.com/q-123",
    "template": "default-basic",
    "expirationDate": "2025-10-10T00:00:00Z",
    "commentsToBuyer": "Please review this quote.",
    "purchaseTerms": "Net 30",
    "status": "published",
    "acceptOnlinePayment": true
  }'
```

**200**

Quote updated

```json
{
  "success": true,
  "message": "Quote updated successfully",
  "data": {
    "_id": "YOUR_QUOTE_ID",
    "dealId": "YOUR_DEAL_ID",
    "name": "Enterprise CRM Deal",
    "status": "published",
    "template": "default-basic"
  }
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```


### Delete a quote

**DELETE** `/api/quotes/{quoteId}`

Full URL: `https://api.hellocrm.ai/api/quotes/{quoteId}`

**Parameters**

- Path `quoteId` (required) — (Required)

**Headers**

- `Accept`: e.g. `application/json`

#### Delete a quote

Deletes a quote.

**cURL**

```bash
curl -X DELETE https://api.hellocrm.ai/api/quotes/YOUR_QUOTE_ID \
  -H "x-api-key: YOUR_API_KEY_HERE"
```

**200**

Quote deleted

```json
{
  "success": true,
  "message": "Quote deleted successfully"
}
```

**400**

Bad request — missing or invalid fields

```json
{
  "success": false,
  "message": "At least one recipientId is required"
}
```

**401**

Missing or invalid API key or token

```json
{
  "success": false,
  "message": "Unauthorized"
}
```

**404**

Resource not found

```json
{
  "success": false,
  "message": "Resource not found"
}
```

**500**

Server error

```json
{
  "success": false,
  "message": "Internal server error"
}
```




---

*Generated from `postman/HelloCRM.postman_collection.json`. Last regenerated by `hellocrm-backend/scripts/postman-to-markdown.mjs`.*
