# Account settings
Source: https://docs.heffl.com/account-settings
Account settings are your personal settings, the ones that affect only you, not the whole workspace. This guide covers your profile, preferences, and password. You will find these under **Settings**, in the **Personal** section.
***
## Finding your settings
Open **Settings** from the sidebar. The menu is split into two groups:
* **Personal**: settings that affect only you (Account Settings and Notifications)
* **Organization**: settings that affect the whole workspace (covered in [Workspace and organization settings](https://docs.heffl.com/workspace-and-organization-settings))
This page covers the Personal > **Account Settings** screen. Notifications has its own page; see [Notification settings](https://docs.heffl.com/untitled-page).
***
## Your profile
Under **Account Settings**, update the details that identify you across the workspace:
* **Name**, shown on records, activity, and assignments
* **Email**, your login and where notifications are sent
* **Profile photo**, the avatar teammates see next to your actions
* **Phone**, your contact number
Keeping your name and photo current helps teammates recognize your activity, since your avatar appears on the records, tasks, and comments you create.
***
## Language and timezone
Set your regional preferences so dates, times, and the interface suit you:
* **Timezone**, ensures meetings, due dates, and timestamps display in your local time. Heffl detects this at signup, but you can change it here.
* **Language**, the interface language, if multiple are available
Your timezone matters most, since it affects how every date and time in Heffl appears to you, including follow-up dates and scheduled jobs.
***
## Changing your password
To update your password:
1. Open **Account Settings**
2. Find the password or security option
3. Enter your current password, then your new one
4. Save
Choose a strong password of at least 8 characters. If you log in with a one-time code (OTP) instead of a password, you may not need to set one. See [How to sign up and log in](https://docs.heffl.com/getting-started/how-to-sign-up-and-log-in).
***
### Personal preferences
Account Settings also holds preferences that shape your own experience of Heffl, such as display options and defaults. These apply only to your account and do not change anything for your teammates.
***
### Personal versus organization settings
It helps to know the difference:
* **Personal settings** (Account Settings, Notifications) affect only you
* **Organization settings** (Organization, CRM, Sales, Integrations, and the rest) affect the whole workspace and usually require admin or owner access
So changing your timezone or photo here is yours alone, while workspace-wide changes live under the Organization group. See [Workspace and organization settings](https://docs.heffl.com/workspace-and-organization-settings).
***
### What to do next
1. Set your [notification preferences](https://docs.heffl.com/untitled-page)
2. Review [workspace and organization settings](https://docs.heffl.com/workspace-and-organization-settings) if you are an admin
3. Confirm your timezone so dates and schedules display correctly
# Adding and managing companies
Source: https://docs.heffl.com/adding-and-managing-companies
Companies are the businesses you work with. In Heffl, a company moves through stages from Lead to Active Client, so the same record covers a prospect and a paying client at different points. This guide covers adding, organizing, and managing companies.
***
## Adding a company
1. Go to **Companies** in the sidebar
2. Click **Add Company** in the top right (or press **C**)
3. Enter the **Company name**
4. Fill in the other details as needed (all optional except the name):
* **Website**
* **Owner**, the team member responsible
* **Primary Contact**, the main person you deal with
* **Stage** (Lead, Opportunity, Active Client, Past Client)
* **Tax number** and **Opening balance**
* **Preferred currency**
* **Tags** and **Source**
5. Click **Add Company** (or press **Ctrl + Enter**)
The form also has tabs for **Other details**, **Billing Address**, and **Field service** to capture more information when you need it.
**Customizing the form** Click **Customize** at the top of the Add Company panel to control which fields appear. This opens the custom fields settings, where you manage fields for companies and other record types. See Creating and managing custom fields.
***
## Company stages
Each company has a stage showing where it stands in your relationship:
* **Lead** is a prospect you have not yet won
* **Opportunity** is an active sales opportunity
* **Active Client** is a current paying client
* **Past Client** is a former client
Change a stage by clicking the Stage cell in the list, or from within the company record. Stages let you treat your whole client base and prospect list as one connected set of records.
***
## Viewing and organizing companies
The Companies page opens in a list, one company per row, showing columns such as #, Name, Contacts, Tax number, Address, Opening balance, Stage, Owner, Tags, and First created. Your total count shows at the bottom (for example, "89 companies").
### **Saved views (tabs)** Across the top are saved views that filter the list for you:
* **All** shows every company
* **Leads** shows companies at the Lead stage
* **Opportunity** shows active opportunities
* **Active clients** shows current clients
Click the **+** next to the tabs to create your own saved view.
### **Sort and filter**
* **Sort** orders companies by created date and other fields
* **Filters** narrows the list by your chosen criteria
* The **search** icon finds a specific company by name
***
## Editing a company
Click any company row to open its full record, where you can update details, view linked contacts, deals, and quotes, and log activity.
You can also edit some fields directly from the list:
* **Stage** by clicking the stage cell
* **Tags** by clicking the **+** in the Tags column
* Contact and other details by clicking the relevant cell
Changes save automatically.
***
## Linking contacts to a company
A company can hold several contacts, the individual people you deal with there. Set a **Primary Contact** when adding the company, and link more contacts from the company record. See [Linking contacts to a company](https://docs.heffl.com/linking-contacts-to-a-company) for the full process.
***
## Importing companies
If you have companies in a spreadsheet, click **Import** to add them in bulk. The flow works like the lead import: upload your file, select the header row, and map your columns to Heffl fields. See [Importing leads from a file](https://docs.heffl.com/importing-leads-from-a-file-upload-select-header-map-columns) for the step-by-step process, which is the same here.
***
## What to do next
1. Link contacts to your companies
2. Move companies through their stages as relationships develop
3. Create deals and quotations tied to a company
# Adding and managing contacts
Source: https://docs.heffl.com/adding-and-managing-contacts
Contacts are the individual people you deal with, whether at a company or on their own. This guide covers adding, organizing, and managing contacts.
***
## Adding a contact
1. Go to **Contacts** in the sidebar
2. Click **Add Contact** in the top right (or press **C**)
3. Enter the contact's details:
* **Title**, **First name**, and **Last name**
* **Phone** (with country code) and **Email**
* **Company** the contact belongs to
* **Job title** and **Owner**
* **Stage** and **Lead status**
4. Click **Add Contact** (or press **Ctrl + Enter**)
The form also has tabs for **Other details**, **Billing Address**, and **Field service** to capture more information, such as tax number, preferred currency, tags, and source.
**Customizing the form** Click **Customize** at the top of the Add Contact panel to control which fields appear. This opens the custom fields settings.
***
## Linking a contact to a company
Set the **Company** field when adding or editing a contact to link them to the business they belong to. A contact belongs to one company, while a company can have many contacts. See [Linking contacts to a company](https://docs.heffl.com/linking-contacts-to-a-company) for the full process.
***
## Contact stages
Like companies, each contact has a stage showing where they stand:
* **Lead** is a new prospect
* **Qualified Lead** is a prospect who has been vetted
* **Opportunity** is an active opportunity
* **Active Client** is a current client
Change a stage by clicking the Stage cell in the list, or from within the contact record.
***
## Viewing and organizing contacts
The Contacts page opens in a list, one contact per row, showing columns such as #, Name, Phone, Email, Tax number, Address, Opening balance, Stage, Owner, Tags, and First created. Your total count shows at the bottom (for example, "129 contacts").
### **Saved views (tabs)** Across the top are saved views that filter the list:
* **All** shows every contact
* **Leads** shows contacts at the Lead stage
* **Opportunity** shows active opportunities
* **Active clients** shows current clients
Click the **+** next to the tabs to create your own saved view.
### **Sort and filter**
* **Sort** orders contacts by created date and other fields
* **Filters** narrows the list by your chosen criteria
* The **search** icon finds a specific contact by name
***
## Editing a contact
Click any contact row to open its full record, where you can update details, see the linked company, and view activity.
You can also edit some fields directly from the list:
* **Stage** by clicking the stage cell
* **Tags** by clicking the **+** in the Tags column
* Contact details by clicking the relevant cell
Changes save automatically.
***
## Importing contacts
If you have contacts in a spreadsheet, click **Import** to add them in bulk. The flow has three steps: upload, select header, and map columns.
The expected columns include First Name (required), Last Name, Email, Phone, Job Title, Salutation, Company Name, Tax Number, Opening Balance, the Billing Address fields, and Tag. Click **Download Template** to format your file correctly before uploading. The process is the same as the lead import, covered in [Importing leads from a file](https://docs.heffl.com/importing-leads-from-a-file-upload-select-header-map-columns).
***
## What to do next
1. [Link contacts to companies](https://docs.heffl.com/linking-contacts-to-a-company) to keep your data connected
2. Create [deals](https://docs.heffl.com/adding-and-managing-deals) tied to a contact
3. Send a [quotation](https://docs.heffl.com/creating-and-sending-quotations) to a contact
# Adding and managing deals
Source: https://docs.heffl.com/adding-and-managing-deals
Deals are your active sales opportunities. A deal represents a qualified chance to win business, with a value, a stage, and a pipeline it belongs to. This guide covers adding, organizing, and managing deals.
***
## Pipelines
Unlike leads, deals are split into separate **pipelines**, one per line of business. Your workspace has pipelines such as Cleaning, Machine, Software sales, Real estate, and Accounting. Each pipeline has its own stages suited to that kind of sale.
You will find your pipelines listed under Deals in the sidebar. Click one to see only the deals in it, or use **All Deals** to see everything.
***
## Adding a deal
1. Go to **Deals** in the sidebar
2. Click **+ Deal** in the top right (or press **C**)
3. Choose the **Company or contact** the deal is for (select an existing client or add a new one)
4. Select the **Pipeline** the deal belongs to
5. Fill in the other details as needed:
* **Source** and **Vendor**
* **Tags**
* **Assigned to** and **Owner**
* Any custom fields
6. Click **Add deal** (or press **Ctrl + Enter**)
Click **Customize** at the top of the form to control which fields appear. ]
Deals are also created automatically when you convert a lead. The lead's information carries into the new deal. See [Managing leads](https://docs.heffl.com/managing-leads-adding-editing-and-converting).
***
## Viewing deals
The Deals page offers two views, switchable from the tabs at the top:
* **All** shows deals as a Kanban board grouped by status
* **Table** shows deals in a list
On the board, deals are grouped into columns by status: **Active**, **Won**, and **Lost**. Each column header shows a count, and the top right shows the total value of all deals.
Each deal card shows its ID (such as DEAL-100), the client, the deal title, its value, and how long since it was created. Cards in the Active column may show a countdown such as "31d" indicating days until the expected close.
***
## The deal detail view
Click any deal to open it. Across the top is the pipeline's stage bar, showing the deal's progress through stages such as Qualified, Site visit, Quotation prepared, Won, Contract signed, and Lost.
The detail view has tabs for Activity, Quotations, Documents, Products, Files, Overview, and Forms. The Details panel on the right shows the client, title, tags, expected value, expected and actual close dates, assignees, owner, source, and linked lead.
The Contacts section lets you associate the specific people involved in the deal. See [Linking contacts to companies and deals](https://docs.heffl.com/linking-contacts-to-companies-and-deals).
***
## Moving a deal through stages
Move a deal forward as the opportunity progresses:
* On the board, drag a card between status columns (Active, Won, Lost)
* In the deal detail view, click a stage in the stage bar to set it
Marking a deal Won or Lost records the outcome and updates your totals. See [Moving deals between stages](https://docs.heffl.com/moving-deals-between-stages) for more on stages.
***
## Editing and converting a deal
Open a deal and click **Edit** to update its details, or **Delete** to remove it. A deal cannot be deleted if it has linked quotations, projects, or documents.
When a deal is won and work needs delivering, click **Convert to Project** to turn it into a project, carrying its details forward. See [Creating and managing projects](https://docs.heffl.com/creating-and-managing-projects).
***
## Importing deals
To add deals in bulk, click **Import**. First choose which **pipeline** to import the deals into, then follow the three steps: upload, select header, and map columns.
The expected columns include Title (required), Client (required), Room size (required), Value, Expected Close Date, Priority, Source, Contact Email, Notes, Tags, and Stage. Click **Download Template** to format your file first. The process otherwise matches [Importing leads from a file](https://docs.heffl.com/importing-leads-from-a-file-upload-select-header-map-columns).
***
## What to do next
1. [Moving deals between stages](https://docs.heffl.com/moving-deals-between-stages) to manage stages
2. Send a [quotation](https://docs.heffl.com/creating-and-sending-quotations) from a deal
3. [Convert a won deal](https://docs.heffl.com/creating-and-managing-projects) into a project
# Adding notes and tags to a lead
Source: https://docs.heffl.com/adding-notes-and-tags-to-a-lead
Notes and tags keep each lead organized and easy to find. Notes record what was discussed, while tags group leads so you can filter them later. This guide covers both.
***
## Adding a note
Notes capture conversations, agreements, and reminders attached to a specific lead.
**From the list view** Click **Add Note** in the Notes column of any lead row, type your note, and save. The note attaches to that lead.
### **From the lead detail view**
1. Open the lead by clicking its row
2. In the Activity area, click **Note**
3. Type your note
4. Save
Notes appear in the lead's activity timeline, so you and your team can see the full history in order. Pin important notes to keep them at the top.
***
## Logging other activity
Alongside notes, the lead detail view lets you log other interactions from the same row of buttons:
* **Log** records a call or general interaction
* **Note** adds a written note
* **Meeting** schedules or records a meeting
* **Email** logs an email
Each entry is timestamped and added to the timeline, building a complete record of every touchpoint with the lead.
***
## Adding a tag
Tags are labels you attach to leads to group them, such as VIP, Technical service, or any label that fits your workflow.
**From the list view** In the Tags column, click the **+** on any lead row and choose or create a tag. To remove a tag, click the **x** next to it.
### **From the lead detail view**
1. Open the lead
2. Find the **Tags** field in the Details panel on the right
3. Click to add a tag, or remove one with the **x**
A lead can hold several tags at once.
***
## Why tags are useful
Tags become powerful when combined with filtering. Once leads are tagged, you can:
* Filter the lead list to show only a certain tag
* Group similar leads regardless of their stage
* Spot patterns, such as all your VIP or high-priority leads
Decide on a small, consistent set of tags for your team rather than creating many one-off labels. A focused tag set keeps filtering meaningful.
***
### Notes versus tags
Use each for its purpose:
* **Notes** hold detail and history, the things you need to read
* **Tags** hold classification, the things you need to filter by
Together they keep each lead both well-documented and easy to group.
***
## What to do next
1. [Filter your leads](https://docs.heffl.com/filtering-and-sorting-leads) by tag to put your tags to work
2. [Convert qualified leads into deals](https://docs.heffl.com/adding-and-managing-deals), carrying their history forward
3. Set up custom fields to capture structured lead data beyond notes and tags
# Authentication (Legacy v1)
Source: https://docs.heffl.com/api-reference/authentication
How to authenticate with the Heffl legacy API v1
# Authentication
This page covers authentication for the [legacy API v1](/api-reference/introduction). API v2 uses the same `x-api-key` header — see [API v2 Authentication](/api-v2/authentication).
The Heffl API uses API keys for authentication. Every request must include a valid API key.
## Getting your API key
1. Go to **Settings > Developer** in your Heffl dashboard
2. Click **Create API Key**
3. Name your key to identify its purpose (e.g., "Website Forms", "Data Sync")
4. Copy the API key immediately
Your API key is shown only once when created. Copy it and store it securely. If you lose it, you'll need to create a new one.
## Using your API key
Include the API key in the `x-api-key` header with every request:
```bash theme={null}
curl https://api.heffl.com/api/v1/leads \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json"
```
### JavaScript example
```javascript theme={null}
const response = await fetch("https://api.heffl.com/api/v1/leads", {
headers: {
"x-api-key": process.env.HEFFL_API_KEY,
"Content-Type": "application/json",
},
});
const data = await response.json();
```
### Python example
```python theme={null}
import requests
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
response = requests.get(
"https://api.heffl.com/api/v1/leads",
headers=headers
)
data = response.json()
```
## API key scope
API keys operate at the workspace level. A key has access to all data within the workspace it was created in, subject to the same data boundaries as the user who created it.
## Revoking API keys
To revoke an API key:
1. Go to **Settings > Developer**
2. Find the key in the list
3. Click **Revoke**
Revoked keys stop working immediately. Any integration using that key will receive `401 Unauthorized` responses.
## Security best practices
| Practice | Description |
| ----------------------------------- | ----------------------------------------------------------- |
| **Use environment variables** | Store API keys in env vars, never hardcode them |
| **Separate keys per environment** | Use different keys for development, staging, and production |
| **Rotate periodically** | Create new keys and revoke old ones on a regular schedule |
| **Never expose client-side** | API keys should only be used in server-side code |
| **Audit usage** | Review active keys and revoke any that are unused |
| **Don't commit to version control** | Add `.env` files to `.gitignore` |
## Troubleshooting
### 401 Unauthorized
* Verify the API key is included in the `x-api-key` header (not `Authorization`)
* Check that the key hasn't been revoked
* Ensure there are no extra spaces or line breaks in the key
### 403 Forbidden
* The API key is valid but doesn't have access to the requested resource
* Check that the key was created in the correct workspace
## FAQ
No. The Heffl API exclusively uses the `x-api-key` header for authentication. Bearer tokens are used internally for the web app but are not available for API access.
API keys do not expire automatically. They remain active until manually revoked.
Currently, API keys have access to all available API endpoints. Endpoint-level restrictions are not yet supported.
# Legacy API (v1)
Source: https://docs.heffl.com/api-reference/introduction
Heffl REST API v1 — maintained for existing integrations
# Legacy API (v1)
This is the legacy API (v1). For new integrations, use [API v2](/api-v2/introduction) — it has clearer resource paths, a consistent response envelope, and structured errors.
The Heffl v1 API lets you programmatically access and manage your CRM, sales, and project data. Existing integrations continue to work without changes. v1 remains fully supported, but new features ship in v2 first.
## Base URL
```
https://api.heffl.com/api/v1
```
All API endpoints are served over HTTPS. HTTP requests are not supported.
## Authentication
Every request must include your API key in the `x-api-key` header:
```bash theme={null}
curl https://api.heffl.com/api/v1/leads \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json"
```
See [Authentication](/api-reference/authentication) for how to create and manage API keys.
## Request format
* All request bodies must be JSON with `Content-Type: application/json`
* Query parameters are used for filtering and pagination on list endpoints
* Resource IDs in URLs are string-based public IDs (e.g., `ld_abc123`) across business entities (leads, clients, deals, tasks, invoices, webhooks).
### Example: Create a lead
```bash theme={null}
curl -X POST https://api.heffl.com/api/v1/leads \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Smith",
"email": "jane@example.com",
"mobile": "+1234567890",
"title": "Product Demo Request"
}'
```
## Response format
All responses return JSON. Successful responses include the data directly:
**Single resource:**
```json theme={null}
{
"id": "ld_abc123",
"name": "Jane Smith",
"email": "jane@example.com",
"createdAt": "2025-01-15T10:30:00.000Z"
}
```
**List of resources:**
```json theme={null}
{
"items": [...],
"nextCursor": "cursor_value_or_null",
"hasMore": true
}
```
## Pagination
List endpoints support cursor pagination with these query parameters:
| Parameter | Type | Default | Description |
| --------- | ------ | ------- | ---------------------------------------- |
| `cursor` | string | *none* | Cursor returned by the previous response |
| `limit` | number | 20 | Items per response (max 100) |
```bash theme={null}
curl "https://api.heffl.com/api/v1/leads?limit=25" \
-H "x-api-key: YOUR_API_KEY"
```
## Error handling
Error responses include a descriptive message:
```json theme={null}
{
"code": "BAD_REQUEST",
"message": "Invalid email address format"
}
```
### Error codes
| Code | HTTP Status | Description |
| ------------------- | ----------- | ---------------------------------- |
| `UNAUTHORIZED` | 401 | Missing or invalid API key |
| `FORBIDDEN` | 403 | API key valid but lacks permission |
| `NOT_FOUND` | 404 | Resource does not exist |
| `BAD_REQUEST` | 400 | Invalid request parameters |
| `TOO_MANY_REQUESTS` | 429 | Rate limit exceeded |
## Rate limiting
API requests are rate limited to **60 requests per minute** per API key. If you exceed the limit, you'll receive a `429` response with `RateLimit-*` headers indicating your current usage and reset time. Include retry logic with exponential backoff in your integration.
## Custom fields
Entities that support custom fields (leads, deals, clients, invoices) accept them via the `cf_` prefix in create and update requests:
```json theme={null}
{
"name": "Jane Smith",
"email": "jane@example.com",
"cf_industry": "Technology",
"cf_company_size": "50-100"
}
```
Custom field keys are derived from the field label (lowercased, spaces replaced with underscores, prefixed with `cf_`).
## Available resources
### CRM
| Resource | Operations |
| ----------- | --------------------------------- |
| **Leads** | Create, List, Get, Update, Delete |
| **Clients** | Create, List, Get, Update, Delete |
| **Deals** | Create, List, Get, Update, Delete |
| **Tasks** | Create, List, Get, Update, Delete |
### Reference data
| Resource | Operations |
| ---------------- | ---------- |
| **Tags** | List |
| **Pipelines** | List, Get |
| **Products** | List, Get |
| **Lead Stages** | List |
| **Lead Sources** | List |
### Webhooks
| Resource | Description |
| ----------------------------------------------- | --------------------------- |
| [Webhooks](/api-reference/webhooks) | Setup, security, delivery |
| [Webhook Events](/api-reference/webhook-events) | Event catalog with payloads |
Browse the endpoint reference in the sidebar to see full request/response details with code examples in multiple languages.
## SDKs and tools
The Heffl API follows REST conventions and works with any HTTP client. Use tools like:
* **cURL** for command-line testing
* **Postman** for interactive exploration
* **Zapier / Make** for no-code integrations
* Any HTTP library in your programming language of choice
# Webhook Events
Source: https://docs.heffl.com/api-reference/webhook-events
Complete catalog of webhook event types and their payloads
# Webhook Events
Subscribe to these events to receive real-time notifications. All payloads are wrapped in the standard [webhook format](/api-reference/webhooks#payload-format).
## CRM Events
### lead.created
Fired when a new lead is created.
```json theme={null}
{
"event": "lead.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"payload": {
"id": "ld_abc123",
"name": "Jane Smith",
"mobile": "+1234567890",
"email": "jane@example.com",
"secondaryMobile": null,
"title": "Product Demo Request",
"value": 5000,
"source": "Website",
"createdAt": "2025-01-15T10:30:00.000Z",
"website": null,
"archived": false,
"stage": "New",
"stageId": 1,
"customFields": {},
"ownerId": 42,
"ownerName": "John Doe"
}
}
```
### lead.updated
Fired when a lead is updated (any field change).
Payload structure is the same as `lead.created` with the updated values.
### lead.deleted
Fired when a lead is deleted.
Payload contains the lead data as it was before deletion.
### lead.stageChanged
Fired when a lead moves to a different stage. This event fires in addition to `lead.updated`.
Payload structure is the same as `lead.created` with the new stage values.
***
### deal.created
Fired when a new deal is created.
```json theme={null}
{
"event": "deal.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"payload": {
"id": "dl_def456",
"title": "Enterprise License",
"number": "DL-0001",
"price": 25000,
"status": "ACTIVE",
"priority": "HIGH",
"expectedCloseDate": "2025-03-15T00:00:00.000Z",
"createdAt": "2025-01-15T10:30:00.000Z",
"client": {
"id": "cl_xyz789",
"name": "Acme Inc.",
"number": "CL-0001",
"taxNumber": null,
"website": null,
"customFields": {},
"type": "company",
"firstName": null,
"lastName": null,
"email": "info@acme.com",
"phone": "+1234567890"
},
"stage": "Proposal",
"stageId": 11,
"pipelineId": 1,
"source": "Referral",
"leadId": "ld_abc123",
"leadName": "Jane Smith",
"ownerId": 42,
"ownerName": "John Doe",
"customFields": {}
}
}
```
### deal.updated
Fired when a deal is updated. Payload structure is the same as `deal.created`.
### deal.deleted
Fired when a deal is deleted. Payload contains the deal data before deletion.
### deal.stageChanged
Fired when a deal moves to a different pipeline stage. Fires in addition to `deal.updated`.
***
### client.created
Fired when a new client is created.
```json theme={null}
{
"event": "client.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"payload": {
"id": "cl_xyz789",
"name": "Acme Inc.",
"number": "CL-0001",
"taxNumber": "TAX123456",
"website": "https://acme.com",
"customFields": {},
"type": "company",
"firstName": null,
"lastName": null,
"email": "info@acme.com",
"phone": "+1234567890"
}
}
```
### client.updated
Fired when a client is updated. Payload structure is the same as `client.created`.
### client.deleted
Fired when a client is deleted. Payload contains the client data before deletion.
***
Contact webhook events (`contact.created`, `contact.updated`,
`contact.deleted`) are planned but not yet implemented. They will be available
in a future release.
### contact.created
Fired when a new contact is created.
```json theme={null}
{
"event": "contact.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"payload": {
"id": "ct_qrs567",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@acme.com",
"mobile": "+1234567890",
"designation": "CTO",
"clientId": "cl_xyz789",
"createdAt": "2025-01-15T10:30:00.000Z"
}
}
```
### contact.updated
Fired when a contact is updated.
### contact.deleted
Fired when a contact is deleted.
### contact.stageChanged
Fired when a contact lifecycle stage changes.
***
## Sales Events
### invoice.created
Fired when a new invoice is created.
```json theme={null}
{
"event": "invoice.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"payload": {
"id": "inv_ghi012",
"number": "INV-0001",
"clientId": "cl_xyz789",
"clientName": "Acme Inc.",
"status": "SENT",
"total": 25000,
"dueDate": "2025-02-15T00:00:00.000Z",
"salesPersonId": 42,
"createdAt": "2025-01-15T10:30:00.000Z"
}
}
```
### invoice.updated
Fired when an invoice is updated.
### invoice.paid
Fired when an invoice is marked as paid.
### invoice.deleted
Fired when an invoice is deleted.
### invoice.statusChanged
Fired when an invoice status changes.
***
### quotation.created
Fired when a new quotation is created.
```json theme={null}
{
"event": "quotation.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"payload": {
"id": "qt_jkl345",
"number": "QT-0001",
"clientId": "cl_xyz789",
"clientName": "Acme Inc.",
"status": "DRAFT",
"total": 25000,
"dealId": "dl_def456",
"createdAt": "2025-01-15T10:30:00.000Z"
}
}
```
### quotation.updated
Fired when a quotation is updated.
### quotation.deleted
Fired when a quotation is deleted.
### quotation.statusChanged
Fired when a quotation status changes.
### payment.received
Fired when a payment is received.
***
### form.response.created
Fired when a new form response is submitted.
```json theme={null}
{
"event": "form.response.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"payload": {
"id": "rec_mno678",
"formId": "frm_pqr901",
"data": {
"name": "Jane Smith",
"email": "jane@example.com",
"message": "I'd like to learn more about your services."
},
"createdAt": "2025-01-15T10:30:00.000Z"
}
}
```
***
## Event summary
| Event | Category | Description |
| ------------------------- | -------- | -------------------------------------------- |
| `lead.created` | CRM | New lead created |
| `lead.updated` | CRM | Lead fields updated |
| `lead.deleted` | CRM | Lead deleted |
| `lead.stageChanged` | CRM | Lead moved to a different stage |
| `deal.created` | CRM | New deal created |
| `deal.updated` | CRM | Deal fields updated |
| `deal.deleted` | CRM | Deal deleted |
| `deal.stageChanged` | CRM | Deal moved to a different pipeline stage |
| `client.created` | CRM | New client created |
| `client.updated` | CRM | Client fields updated |
| `client.deleted` | CRM | Client deleted |
| `contact.created` | CRM | New contact created |
| `contact.updated` | CRM | Contact fields updated |
| `contact.deleted` | CRM | Contact deleted |
| `contact.stageChanged` | CRM | Contact moved to a different lifecycle stage |
| `invoice.created` | Sales | New invoice created |
| `invoice.updated` | Sales | Invoice fields updated |
| `invoice.paid` | Sales | Invoice marked as paid |
| `invoice.deleted` | Sales | Invoice deleted |
| `invoice.statusChanged` | Sales | Invoice status changed |
| `quotation.created` | Sales | New quotation created |
| `quotation.updated` | Sales | Quotation fields updated |
| `quotation.deleted` | Sales | Quotation deleted |
| `quotation.statusChanged` | Sales | Quotation status changed |
| `payment.received` | Sales | Payment received |
| `form.response.created` | CRM | New form response submitted |
## Payload design
Webhook payloads follow these conventions:
* **IDs included** for all related entities (e.g., `ownerId`, `leadId`, `stageId`)
* **Key scalar fields** for immediate identification (e.g., `ownerName`, `leadName`)
* **Related entity objects** may be included for convenience (e.g., `client` in deal events)
* **Public IDs** used for entities that support them (leads, clients, deals)
Use the [REST API](/api-reference/introduction) to fetch additional details not included in the webhook payload.
# Webhooks
Source: https://docs.heffl.com/api-reference/webhooks
Receive real-time notifications when events happen in your workspace
# Webhooks
Webhooks let you receive HTTP POST notifications when events occur in your Heffl workspace. Instead of polling the API, your server gets notified in real time when leads are created, deals change stage, invoices are paid, and more.
## Setup
1. Go to **Settings > Developer** in your Heffl workspace
2. Click **Add Webhook Endpoint**
3. Enter your endpoint URL (must be HTTPS in production)
4. Select the events you want to subscribe to
5. Save — you'll receive a signing secret starting with `whsec_`
Store your webhook signing secret securely. You'll need it to verify webhook signatures.
## API endpoints
* `POST /webhooks` creates a webhook subscription and returns the one-time signing `secret`
* `GET /webhooks` lists subscriptions with cursor pagination
* `GET /webhooks/{id}` returns a single subscription
* `DELETE /webhooks/{id}` deletes a subscription
## Payload format
Every webhook delivery sends a JSON POST request with this structure:
```json theme={null}
{
"event": "lead.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"payload": {
"id": "ld_abc123",
"name": "Jane Smith",
"email": "jane@example.com",
"mobile": "+1234567890",
"title": "Product Demo Request",
"value": 5000,
"source": "Website",
"stage": "New",
"stageId": 1,
"archived": false,
"createdAt": "2025-01-15T10:30:00.000Z",
"customFields": {},
"ownerId": 42,
"ownerName": "John Doe"
}
}
```
## Request headers
Every webhook request includes these headers:
| Header | Description |
| ------------------- | ----------------------------------------------------------- |
| `Content-Type` | `application/json` |
| `User-Agent` | `Heffl-Webhooks/1.0` |
| `webhook-id` | Unique message ID (e.g., `msg_2KWPBgLlAfxdpx2AI54pPJ85f4W`) |
| `webhook-timestamp` | Unix timestamp in seconds |
| `webhook-signature` | HMAC-SHA256 signature (see below) |
## Verifying signatures
Every webhook is signed using HMAC-SHA256 following the [Standard Webhooks](https://www.standardwebhooks.com) specification. Always verify signatures to ensure the request came from Heffl.
### How it works
1. The signed content is: `{webhook-id}.{webhook-timestamp}.{request-body}`
2. The signature is computed using HMAC-SHA256 with your signing secret
3. The signature header format is: `v1,{base64-encoded-signature}`
### Node.js verification example
```javascript theme={null}
const crypto = require('crypto');
function verifyWebhook(req, signingSecret) {
const msgId = req.headers['webhook-id'];
const timestamp = req.headers['webhook-timestamp'];
const signature = req.headers['webhook-signature'];
const body = JSON.stringify(req.body);
// Check timestamp tolerance (5 minutes)
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp)) > 300) {
throw new Error('Timestamp too old');
}
// Compute expected signature
const secret = Buffer.from(signingSecret.replace('whsec_', ''), 'base64');
const signedContent = `${msgId}.${timestamp}.${body}`;
const expectedSig = crypto
.createHmac('sha256', secret)
.update(signedContent)
.digest('base64');
// Compare signatures
const receivedSigs = signature.split(' ');
for (const sig of receivedSigs) {
const [version, hash] = sig.split(',');
if (version !== 'v1') continue;
const expected = Buffer.from(expectedSig);
const received = Buffer.from(hash);
if (expected.length === received.length &&
crypto.timingSafeEqual(expected, received)) {
return true; // Valid
}
}
throw new Error('Invalid signature');
}
```
### Python verification example
```python theme={null}
import hmac
import hashlib
import base64
import time
import json
def verify_webhook(headers, body, signing_secret):
msg_id = headers['webhook-id']
timestamp = headers['webhook-timestamp']
signature = headers['webhook-signature']
# Check timestamp tolerance (5 minutes)
now = int(time.time())
if abs(now - int(timestamp)) > 300:
raise ValueError('Timestamp too old')
# Compute expected signature
secret = base64.b64decode(signing_secret.replace('whsec_', ''))
signed_content = f"{msg_id}.{timestamp}.{body}".encode()
expected_sig = base64.b64encode(
hmac.new(secret, signed_content, hashlib.sha256).digest()
).decode()
# Compare signatures
for sig in signature.split(' '):
version, hash_value = sig.split(',', 1)
if version != 'v1':
continue
if hmac.compare_digest(expected_sig, hash_value):
return True
raise ValueError('Invalid signature')
```
## Retry policy
If your endpoint fails to respond with a `2xx` status within 20 seconds, Heffl retries delivery with exponential backoff:
| Attempt | Delay |
| ------- | ---------- |
| 1 | Immediate |
| 2 | 5 seconds |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
| 6 | 5 hours |
| 7 | 10 hours |
| 8 | 14 hours |
| 9 | 20 hours |
| 10 | 24 hours |
After 10 failed attempts, the delivery is marked as permanently failed.
### Retry behavior by status code
| Status | Behavior |
| ------------------- | ------------------------------------------- |
| `2xx` | Success — no retry |
| `410 Gone` | Endpoint disabled — no further deliveries |
| `429`, `502`, `504` | Retried |
| Other `4xx` | Not retried (likely permanent client error) |
| `5xx` | Retried |
## Best practices
* **Respond quickly.** Return a `200` status immediately and process the event asynchronously. The delivery timeout is 20 seconds.
* **Use idempotency.** The `webhook-id` header is unique per delivery. Store it to detect and skip duplicate deliveries.
* **Verify signatures.** Always validate the `webhook-signature` header to ensure the request is authentic.
* **Check timestamps.** Reject requests with timestamps older than 5 minutes to prevent replay attacks.
* **Use HTTPS.** Always use HTTPS endpoints in production. HTTP endpoints will generate warnings.
* **Handle gracefully.** If you receive an event type you don't recognize, return `200` and ignore it — new events may be added.
## Secret rotation
Heffl supports rotating webhook secrets without downtime. During rotation, signatures are generated with both the old and new secrets (space-separated in the `webhook-signature` header). Your verification code should check if **any** of the signatures is valid.
# Add a form field
Source: https://docs.heffl.com/api-v2-reference/objects/add-a-form-field
/openapi.v2.json post /forms/{id}/fields
Adds a question to a form (on its first page). SINGLE_OPTION / MULTIPLE_OPTION fields require a non-empty `values` list of allowed options. Returns the updated field list.
# Create a form submission
Source: https://docs.heffl.com/api-v2-reference/objects/create-a-form-submission
/openapi.v2.json post /forms/{id}/submissions
Submits an answer set for a form. `data` is an object keyed by field key (cf_*); list the form fields first to discover keys, data types, and allowed options. Returns the created submission.
# Create company
Source: https://docs.heffl.com/api-v2-reference/objects/create-company
/openapi.v2.json post /companies
Creates a new company record. The company is assigned to the user associated with your API key. Related entity IDs use prefixed string IDs (for example `cs_`, `usr_`, `tag_`). Tag with `tags` (`tag_` prefix). Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Create contact
Source: https://docs.heffl.com/api-v2-reference/objects/create-contact
/openapi.v2.json post /contacts
Creates a new contact record. The contact is assigned to the user associated with your API key. Related entity IDs use prefixed string IDs (for example `clt_`, `cs_`, `usr_`, `tag_`). Tag with `tags` (`tag_` prefix). Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Create deal
Source: https://docs.heffl.com/api-v2-reference/objects/create-deal
/openapi.v2.json post /deals
Creates a new deal in your CRM pipeline. Related entity IDs use prefixed string IDs (for example `clt_`, `dpl_`, `dps_`). Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Create form
Source: https://docs.heffl.com/api-v2-reference/objects/create-form
/openapi.v2.json post /forms
Creates a new form. Optionally pass `fields` to add questions to the form's first page in one call. SINGLE_OPTION / MULTIPLE_OPTION fields must include a non-empty `values` list of allowed options.
# Create project
Source: https://docs.heffl.com/api-v2-reference/objects/create-project
/openapi.v2.json post /projects
Creates a new project. Required: title, pipelineId (ppl_). Optional stageId (pps_) — if omitted, the first OPEN stage in the pipeline is used. Call GET /project-pipelines to discover IDs. projectLeadId defaults to the API key user. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Create quotation
Source: https://docs.heffl.com/api-v2-reference/objects/create-quotation
/openapi.v2.json post /quotations
Creates a new quotation with line items. Requires clientId (clt_) and templateId (tpl_). Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Create task
Source: https://docs.heffl.com/api-v2-reference/objects/create-task
/openapi.v2.json post /tasks
Creates a new task. Link it to a deal, lead, or project using `entity` and `entityId`. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Delete a company
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-company
/openapi.v2.json delete /companies/{id}
Permanently deletes a company. Will fail if the company has associated deals, invoices, or quotations.
# Delete a contact
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-contact
/openapi.v2.json delete /contacts/{id}
Permanently deletes a contact. Will fail if the contact has associated deals, invoices, or quotations.
# Delete a deal
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-deal
/openapi.v2.json delete /deals/{id}
Permanently deletes a deal. Will fail if the deal has associated quotations, projects, or documents.
# Delete a form
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-form
/openapi.v2.json delete /forms/{id}
Permanently deletes a form and all of its submissions. Returns the form ID and deleted: true.
# Delete a form field
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-form-field
/openapi.v2.json delete /forms/{id}/fields/{key}
Removes a question from a form, identified by its field `key`. Existing submissions keep their stored answers. Returns the field key and deleted: true.
# Delete a form submission
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-form-submission
/openapi.v2.json delete /forms/{id}/submissions/{submissionId}
Permanently deletes a submission. Returns the submission ID and deleted: true.
# Delete a project
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-project
/openapi.v2.json delete /projects/{id}
Permanently deletes a project and its sections and files. Tasks, invoices, and other linked records may block deletion.
# Delete a quotation
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-quotation
/openapi.v2.json delete /quotations/{id}
Permanently deletes a quotation.
# Delete a task
Source: https://docs.heffl.com/api-v2-reference/objects/delete-a-task
/openapi.v2.json delete /tasks/{id}
Permanently deletes a task.
# Get a deal
Source: https://docs.heffl.com/api-v2-reference/objects/get-a-deal
/openapi.v2.json get /deals/{id}
Retrieves a single deal by its ID.
# Get a form
Source: https://docs.heffl.com/api-v2-reference/objects/get-a-form
/openapi.v2.json get /forms/{id}
Retrieves a single form by its ID (frm_ prefix).
# Get a form submission
Source: https://docs.heffl.com/api-v2-reference/objects/get-a-form-submission
/openapi.v2.json get /forms/{id}/submissions/{submissionId}
Retrieves a single submission by its ID (cor_ prefix), including all answers in `data`.
# Get a project
Source: https://docs.heffl.com/api-v2-reference/objects/get-a-project
/openapi.v2.json get /projects/{id}
Retrieves a single project by its ID (prj_ prefix).
# Get a quotation
Source: https://docs.heffl.com/api-v2-reference/objects/get-a-quotation
/openapi.v2.json get /quotations/{id}
Retrieves a single quotation by its ID (qtn_ prefix), including line items and totals.
# Get a task
Source: https://docs.heffl.com/api-v2-reference/objects/get-a-task
/openapi.v2.json get /tasks/{id}
Retrieves a single task by its ID (tsk_ prefix).
# List companies
Source: https://docs.heffl.com/api-v2-reference/objects/list-companies
/openapi.v2.json get /companies
Returns a paginated list of company records. Supports cursor pagination, full-text search, structured filters (stage, owner, tags, dates), and sorting. Results respect the API key user's ownership permissions. See the [Listing & filters](/api-v2/listing-and-filters) guide for filter syntax.
# List contacts
Source: https://docs.heffl.com/api-v2-reference/objects/list-contacts
/openapi.v2.json get /contacts
Returns a paginated list of contact records. Supports cursor pagination, full-text search, structured filters (stage, owner, tags, dates), and sorting. Results respect the API key user's ownership permissions. See the [Listing & filters](/api-v2/listing-and-filters) guide for filter syntax.
# List deals
Source: https://docs.heffl.com/api-v2-reference/objects/list-deals
/openapi.v2.json get /deals
Returns a paginated list of deals. Supports cursor pagination, full-text search, structured filters (pipeline, stage, client, owner, status, tags, dates), and sorting. Results respect the API key user's ownership permissions. See the [Listing & filters](/api-v2/listing-and-filters) guide for filter syntax.
# List form fields
Source: https://docs.heffl.com/api-v2-reference/objects/list-form-fields
/openapi.v2.json get /forms/{id}/fields
Returns the ordered list of fields (questions) on a form, including each field's `key`, data type, whether it is required, and the allowed `options` for choice fields. Use the `key` of each field as the property name inside a submission `data` object.
# List form submissions
Source: https://docs.heffl.com/api-v2-reference/objects/list-form-submissions
/openapi.v2.json get /forms/{id}/submissions
Returns a paginated list of submissions for a form. Each submission's `data` holds answers keyed by field key (cf_*).
# List forms
Source: https://docs.heffl.com/api-v2-reference/objects/list-forms
/openapi.v2.json get /forms
Returns a paginated list of forms. Supports cursor pagination and a `search` query that matches the form title.
# List projects
Source: https://docs.heffl.com/api-v2-reference/objects/list-projects
/openapi.v2.json get /projects
Returns a paginated list of projects. Supports cursor pagination, full-text search (title, number, description), and filtering by status, type, pipeline, stage, client, or project lead.
# List quotations
Source: https://docs.heffl.com/api-v2-reference/objects/list-quotations
/openapi.v2.json get /quotations
Returns a paginated list of quotations. Supports cursor pagination, full-text search, structured filters (status, client, sales person, tags, dates), and sorting. Results respect the API key user's ownership permissions. See the [Listing & filters](/api-v2/listing-and-filters) guide for filter syntax.
# List tasks
Source: https://docs.heffl.com/api-v2-reference/objects/list-tasks
/openapi.v2.json get /tasks
Returns a paginated list of tasks. Supports cursor pagination, full-text search, structured filters (status, type, priority, assignees, tags, dates), and sorting. Results respect the API key user's permissions. See the [Listing & filters](/api-v2/listing-and-filters) guide for filter syntax.
# Update a company
Source: https://docs.heffl.com/api-v2-reference/objects/update-a-company
/openapi.v2.json patch /companies/{id}
Updates an existing company. Only provided fields will be updated. When `tags` is provided, it replaces the full set. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Update a contact
Source: https://docs.heffl.com/api-v2-reference/objects/update-a-contact
/openapi.v2.json patch /contacts/{id}
Updates an existing contact. Only provided fields will be updated. When `tags` is provided, it replaces the full set. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Update a deal
Source: https://docs.heffl.com/api-v2-reference/objects/update-a-deal
/openapi.v2.json patch /deals/{id}
Updates an existing deal. Only provided fields will be updated. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Update a form
Source: https://docs.heffl.com/api-v2-reference/objects/update-a-form
/openapi.v2.json patch /forms/{id}
Updates a form's title or description. Only provided fields are changed. To manage questions, use the form field endpoints.
# Update a form field
Source: https://docs.heffl.com/api-v2-reference/objects/update-a-form-field
/openapi.v2.json patch /forms/{id}/fields/{key}
Updates a question on a form, identified by its field `key`. Only provided properties are changed. For choice fields, `values` replaces the full list of allowed options. A field's data type cannot be changed — delete the field and add a new one to change its type.
# Update a project
Source: https://docs.heffl.com/api-v2-reference/objects/update-a-project
/openapi.v2.json patch /projects/{id}
Updates an existing project. Only provided fields will be updated. Moving stageId to a closed (WON) stage completes the project; you can also set status directly. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Update a quotation
Source: https://docs.heffl.com/api-v2-reference/objects/update-a-quotation
/openapi.v2.json patch /quotations/{id}
Updates an existing quotation (partial update). Line items and tags replace the full set when provided. Custom field values use `cf_*` keys and are merged with existing values.
# Update a task
Source: https://docs.heffl.com/api-v2-reference/objects/update-a-task
/openapi.v2.json patch /tasks/{id}
Updates an existing task. Only provided fields will be updated. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Add a stage to a deal pipeline
Source: https://docs.heffl.com/api-v2-reference/reference-data/add-a-stage-to-a-deal-pipeline
/openapi.v2.json post /pipelines/{id}/stages
Adds a new stage to an existing pipeline. Returns the created stage with its ID (dps_).
# Create a deal pipeline
Source: https://docs.heffl.com/api-v2-reference/reference-data/create-a-deal-pipeline
/openapi.v2.json post /pipelines
Creates a deal pipeline with its stages. A pipeline must include at least one ACTIVE, one WON, and one LOST stage. Returns the new pipeline with stage IDs (dps_) you can use when creating deals.
# Create client stage
Source: https://docs.heffl.com/api-v2-reference/reference-data/create-client-stage
/openapi.v2.json post /client-stages
Creates a new client stage. It is added at the end of the stage list.
# Create lead stage
Source: https://docs.heffl.com/api-v2-reference/reference-data/create-lead-stage
/openapi.v2.json post /lead-stages
Creates a new lead stage. It is added at the end of the stage list.
# Create product
Source: https://docs.heffl.com/api-v2-reference/reference-data/create-product
/openapi.v2.json post /products
Creates a new product. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Create source
Source: https://docs.heffl.com/api-v2-reference/reference-data/create-source
/openapi.v2.json post /sources
Creates a new CRM source.
# Create tag
Source: https://docs.heffl.com/api-v2-reference/reference-data/create-tag
/openapi.v2.json post /tags
Creates a new tag for the given entity type.
# Delete a product
Source: https://docs.heffl.com/api-v2-reference/reference-data/delete-a-product
/openapi.v2.json delete /products/{id}
Permanently deletes a product.
# Delete a source
Source: https://docs.heffl.com/api-v2-reference/reference-data/delete-a-source
/openapi.v2.json delete /sources/{id}
Permanently deletes a CRM source.
# Delete a tag
Source: https://docs.heffl.com/api-v2-reference/reference-data/delete-a-tag
/openapi.v2.json delete /tags/{id}
Permanently deletes a tag and removes it from all associated records.
# Get a deal pipeline
Source: https://docs.heffl.com/api-v2-reference/reference-data/get-a-deal-pipeline
/openapi.v2.json get /pipelines/{id}
Returns a single deal pipeline with its stages.
# Get a document template
Source: https://docs.heffl.com/api-v2-reference/reference-data/get-a-document-template
/openapi.v2.json get /document-templates/{id}
Returns a single document template (quotation, invoice, proforma, etc.) including template-scoped custom field definitions.
# Get a product
Source: https://docs.heffl.com/api-v2-reference/reference-data/get-a-product
/openapi.v2.json get /products/{id}
Returns a single product by ID.
# Get a project pipeline
Source: https://docs.heffl.com/api-v2-reference/reference-data/get-a-project-pipeline
/openapi.v2.json get /project-pipelines/{id}
Returns a single project pipeline with its stages. Use stage IDs (pps_) when creating projects or filtering by stageId.
# List client stages
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-client-stages
/openapi.v2.json get /client-stages
Returns all client stages ordered by position.
# List custom field definitions
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-custom-field-definitions
/openapi.v2.json get /custom-fields
Returns custom field definitions for contacts, companies, deals, quotations, or tasks. Use the key values as cf_* fields on create/update.
# List deal pipelines
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-deal-pipelines
/openapi.v2.json get /pipelines
Returns all active deal pipelines with stages. Use before creating deals — see Agent workflows guide.
# List document templates
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-document-templates
/openapi.v2.json get /document-templates
Returns templates used for Heffl documents (quotations, invoices, proforma invoices, purchase orders, etc.) — not project or email templates. Filter by type (for example quotations) to find a templateId for API creates.
# List lead stages
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-lead-stages
/openapi.v2.json get /lead-stages
Returns all lead stages ordered by position.
# List products
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-products
/openapi.v2.json get /products
Returns a paginated list of products. Supports cursor pagination and search by name.
# List project pipelines
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-project-pipelines
/openapi.v2.json get /project-pipelines
Returns all active project pipelines with their stages. Use before creating or filtering projects — you need a pipeline ID (ppl_) and usually a stage ID (pps_) from the nested stages array.
# List sources
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-sources
/openapi.v2.json get /sources
Returns all CRM sources (lead/deal sources) for your team. By default only active sources are returned.
# List tags
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-tags
/openapi.v2.json get /tags
Returns all tags for your team, optionally filtered by the entity type they apply to.
# List users
Source: https://docs.heffl.com/api-v2-reference/reference-data/list-users
/openapi.v2.json get /users
Returns a paginated list of users who belong to the API key's team. Supports cursor pagination, search, and filtering by active membership status.
# Update a client stage
Source: https://docs.heffl.com/api-v2-reference/reference-data/update-a-client-stage
/openapi.v2.json patch /client-stages/{id}
Updates a client stage's label.
# Update a deal pipeline
Source: https://docs.heffl.com/api-v2-reference/reference-data/update-a-deal-pipeline
/openapi.v2.json patch /pipelines/{id}
Updates a pipeline's name, icon, or active state. Only provided fields are changed. To add or edit stages, use the stage endpoints.
# Update a deal pipeline stage
Source: https://docs.heffl.com/api-v2-reference/reference-data/update-a-deal-pipeline-stage
/openapi.v2.json patch /pipeline-stages/{id}
Updates a pipeline stage's name, position, probability, rotting days, or type. Only provided fields are changed.
# Update a lead stage
Source: https://docs.heffl.com/api-v2-reference/reference-data/update-a-lead-stage
/openapi.v2.json patch /lead-stages/{id}
Updates a lead stage's label or type. Only provided fields are changed.
# Update a product
Source: https://docs.heffl.com/api-v2-reference/reference-data/update-a-product
/openapi.v2.json patch /products/{id}
Updates an existing product. Only provided fields will be updated. Custom field values use `cf_*` keys — see the [Custom fields](/api-v2/custom-fields) guide.
# Update a source
Source: https://docs.heffl.com/api-v2-reference/reference-data/update-a-source
/openapi.v2.json patch /sources/{id}
Updates an existing CRM source. Only provided fields will be updated.
# Update a tag
Source: https://docs.heffl.com/api-v2-reference/reference-data/update-a-tag
/openapi.v2.json patch /tags/{id}
Updates a tag's name, color, or icon. The tag type cannot be changed.
# Agent workflows
Source: https://docs.heffl.com/api-v2/agent-workflows
Common multi-step API sequences for automation and AI agents
# Agent workflows
These sequences show how to chain API v2 calls for typical automation tasks. All requests require the `x-api-key` header. See [ID prefixes](/api-v2/id-prefixes) for ID formats.
## Create a deal in a pipeline
1. **List pipelines** — get `dpl_` and `dps_` IDs:
```bash theme={null}
curl "https://api.heffl.com/api/v2/pipelines" \
-H "x-api-key: YOUR_API_KEY"
```
Pick a pipeline `id` and an **ACTIVE** stage `id` from `stages` (check `type` is `ACTIVE`).
2. **Resolve the client** — search contacts or companies, or create one:
```bash theme={null}
curl "https://api.heffl.com/api/v2/contacts?search=acme&pageSize=5" \
-H "x-api-key: YOUR_API_KEY"
```
3. **Optional: custom fields** — discover valid `cf_*` keys:
```bash theme={null}
curl "https://api.heffl.com/api/v2/custom-fields?entity=deals&pipelineId=dpl_abc123" \
-H "x-api-key: YOUR_API_KEY"
```
4. **Create the deal**:
```bash theme={null}
curl -X POST "https://api.heffl.com/api/v2/deals" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Enterprise license",
"clientId": "clt_abc123",
"pipelineId": "dpl_abc123",
"stageId": "dps_abc123",
"price": 25000,
"expectedCloseDate": "2026-06-30T00:00:00.000Z"
}'
```
`stageId` is optional; if omitted, the first ACTIVE stage in the pipeline is used.
## Close a deal (won or lost)
**Option A — update stage** (recommended when matching your pipeline):
```bash theme={null}
curl -X PATCH "https://api.heffl.com/api/v2/deals/dl_abc123" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "stageId": "dps_won_stage_id" }'
```
Use a stage with `type` `WON` or `LOST` from `GET /pipelines`.
**Option B — set status directly**:
```bash theme={null}
curl -X PATCH "https://api.heffl.com/api/v2/deals/dl_abc123" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "WON" }'
```
## Create a follow-up task on a deal
```bash theme={null}
curl -X POST "https://api.heffl.com/api/v2/tasks" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Follow up on proposal",
"type": "call",
"dueDate": "2026-06-01T10:00:00.000Z",
"entity": "deals",
"entityId": "dl_abc123",
"assigneeIds": ["usr_xyz789"]
}'
```
`entity` and `entityId` must be sent together. List users with `GET /users` for assignee IDs.
## Create a quotation
1. **List quotation document templates** (layout presets for quotations, not project templates) — get a `tpl_` ID:
```bash theme={null}
curl "https://api.heffl.com/api/v2/document-templates?type=quotations" \
-H "x-api-key: YOUR_API_KEY"
```
2. **Optional: template custom fields** — `GET /document-templates/{id}` for `customFields` keys to send as `cf_*` on create.
3. **Create the quotation** — see [Document templates](/api-v2/document-templates) and [API v2 overview — Quotations](/api-v2/introduction#quotations).
## List open deals in a pipeline
Pass `filters` as a **JSON-encoded query string** (recommended for agents and curl):
```bash theme={null}
curl -G "https://api.heffl.com/api/v2/deals" \
-H "x-api-key: YOUR_API_KEY" \
--data-urlencode 'pageSize=25' \
--data-urlencode 'filters={"pipelineId":{"operator":"is","values":["dpl_abc123"]},"status":{"operator":"is","values":["ACTIVE"]}}'
```
Paginate with `cursor` from `meta.nextCursor`. See [Listing & filters](/api-v2/listing-and-filters).
## Delete a contact
Deletion fails with `400` if the contact has linked deals, invoices, or quotations:
```bash theme={null}
curl -X DELETE "https://api.heffl.com/api/v2/contacts/clt_abc123" \
-H "x-api-key: YOUR_API_KEY"
```
## Error handling
All errors use `{ "error": { "code", "message", "details?" } }`. Validation failures include `details.issues` with `field` and `message`. See [Errors](/api-v2/errors). Retry `429` after the rate limit window; do not retry `400` without changing the request.
# Authentication
Source: https://docs.heffl.com/api-v2/authentication
Authenticate API v2 requests with API keys
# Authentication
API v2 uses the same API key authentication as v1. Every request must include a valid key in the `x-api-key` header.
## API keys
Create and manage keys in **Settings → Developer** in the Heffl app, or at [app.heffl.com/settings/developers](https://app.heffl.com/settings/developers).
Each key is scoped to a team and acts on behalf of the user who created it.
## Request header
```bash theme={null}
curl https://api.heffl.com/api/v2/contacts \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json"
```
## Unauthorized requests
Missing or invalid keys return `401`:
```json theme={null}
{
"error": {
"code": "UNAUTHORIZED",
"message": "API key required. Include 'x-api-key' header."
}
}
```
## Rate limiting
API v2 shares the same rate limit as v1: **60 requests per minute** per API key. Exceeding the limit returns `429` with `RateLimit-*` headers.
## Permissions
The API key inherits the creating user's permissions. If the user cannot create, update, or delete contacts in the app, the API will return `403 Forbidden`.
# Custom fields
Source: https://docs.heffl.com/api-v2/custom-fields
Pass and read custom field values in API v2 requests and responses
# Custom fields
Entities that support custom fields use the `cf_` prefix. Send values as top-level keys on create and update; responses return the same keys on the resource object — not inside a `customFields` property.
## Supported resources
| Resource | Endpoints |
| ---------- | --------------------------------------------------------------------------------------------- |
| Contacts | `/api/v2/contacts` |
| Companies | `/api/v2/companies` |
| Deals | `/api/v2/deals` |
| Quotations | `/api/v2/quotations` |
| Tasks | `/api/v2/tasks` |
| Projects | `/api/v2/projects` |
| Products | `/api/v2/products` (accept `cf_*` on create/update; not returned on the product resource yet) |
## Naming convention
Custom field keys are derived from the field label in Heffl:
1. Lowercase the label
2. Replace spaces with underscores
3. Prefix with `cf_`
| Field label in Heffl | API key |
| -------------------- | ----------------- |
| Industry | `cf_industry` |
| Company Size | `cf_company_size` |
| Lead Score | `cf_lead_score` |
## Example — create
```bash theme={null}
curl -X POST https://api.heffl.com/api/v2/companies \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme LLC",
"email": "hello@acme.example",
"cf_industry": "Technology",
"cf_lead_source_detail": "Webinar signup"
}'
```
## Example — update
On update, custom fields are merged with existing values. Omitted `cf_*` keys are left unchanged.
```bash theme={null}
curl -X PATCH https://api.heffl.com/api/v2/contacts/clt_abc123 \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"cf_industry": "SaaS",
"cf_lead_score": 85
}'
```
## Responses
Custom field values appear as top-level `cf_*` keys on the resource (in list `data` items and on create/update/get responses). There is no `customFields` object in API v2.
```json theme={null}
{
"id": "clt_abc123",
"name": "Acme LLC",
"cf_industry": "Technology",
"cf_lead_source_detail": "Webinar signup"
}
```
Deal example:
```json theme={null}
{
"id": "deal_abc123",
"title": "Enterprise plan",
"cf_priority": "high"
}
```
Configured fields may appear with `null` when unset (especially on list rows).
## Validation
* Only documented fields and `cf_*` keys are allowed — unknown fields return a validation error
* Field types must match the custom field definition in your workspace (text, number, date, etc.)
Configure custom fields in **Settings → Custom fields** in the Heffl app.
## Discover field keys via API
List definitions (key, label, type, allowed values) before writing integrations:
```bash theme={null}
curl "https://api.heffl.com/api/v2/custom-fields?entity=deals&pipelineId=dpl_abc123" \
-H "x-api-key: YOUR_API_KEY"
```
Supported `entity` values: `contacts`, `companies`, `deals`, `tasks`. For deals, pass `pipelineId` to include pipeline-scoped fields.
# Document templates
Source: https://docs.heffl.com/api-v2/document-templates
Templates used for sales and purchase documents — quotations, invoices, proforma invoices, and more
# Document templates
Document templates are the **layout and settings presets** used when you create documents in Heffl — not project templates or email templates. Each template belongs to one document type, for example:
* **Quotations** (`type: quotations`)
* **Invoices** (`type: invoices`)
* **Proforma invoices** (`type: proforma_invoices`)
* **Purchase orders** (`type: purchase_orders`)
* **Bills**, **sales orders**, **documents**, and other types supported in your workspace
They control PDF/HTML layout, numbering, signatures, and template-scoped custom fields. In API v2, each template has a prefixed string **id** (`tpl_` prefix). Use it as `templateId` when creating records that require a template (for example `POST /quotations`).
## List templates
Filter by document type to find templates for a specific workflow:
```bash theme={null}
curl "https://api.heffl.com/api/v2/document-templates?type=quotations" \
-H "x-api-key: YOUR_API_KEY"
```
Optional query parameters:
| Parameter | Description |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `type` | Document type — `quotations`, `invoices`, `proforma_invoices`, `purchase_orders`, `bills`, `sales_orders`, `documents`, etc. |
| `search` | Case-insensitive prefix match on template name |
| `includeInactive` | When `true`, includes inactive templates |
Response:
```json theme={null}
{
"data": [
{
"id": "tpl_abc123",
"name": "Standard quotation",
"type": "quotations",
"isActive": true,
"isSignatureRequired": false,
"valueType": "DYNAMIC"
}
]
}
```
## Get a template
Use this when you need template-scoped custom field keys before creating a quotation:
```bash theme={null}
curl "https://api.heffl.com/api/v2/document-templates/tpl_abc123" \
-H "x-api-key: YOUR_API_KEY"
```
The response includes a `customFields` array. Use each `key` as a top-level `cf_*` field on `POST /quotations` (same convention as [Custom fields](https://docs.heffl.com/api-v2/custom-fields)).
## Create a quotation
1. List templates with `type=quotations` and pick an `id`.
2. Optionally call `GET /document-templates/{id}` for `customFields`.
3. Create the quotation with `templateId`:
```bash theme={null}
curl -X POST "https://api.heffl.com/api/v2/quotations" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": "clt_abc123",
"templateId": "tpl_abc123",
"date": "2026-05-31T00:00:00.000Z",
"quotationProducts": [
{ "name": "Discovery workshop", "quantity": 1, "price": 2500 }
]
}'
```
`templateId` cannot be changed after creation. See [API v2 overview — Quotations](https://docs.heffl.com/api-v2/introduction#quotations).
## Related
* [ID prefixes](https://docs.heffl.com/api-v2/id-prefixes) — `tpl_` template IDs
* [Custom fields](https://docs.heffl.com/api-v2/custom-fields) — team-wide field definitions; template detail also lists template-scoped fields
# Errors
Source: https://docs.heffl.com/api-v2/errors
API v2 error format and codes
# Errors
API v2 returns structured error objects inside an `error` key.
## Error shape
```json theme={null}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Some fields are invalid. Please check and try again.",
"details": {
"issues": [
{ "field": "email", "message": "Please enter a valid email address." }
]
}
}
}
```
| Field | Description |
| --------- | ------------------------------------------------------- |
| `code` | Machine-readable error code |
| `message` | Human-readable summary |
| `details` | Optional extra context (validation issues, retry hints) |
## Error codes
| Code | HTTP Status | Description |
| ----------------------- | ----------- | -------------------------------------- |
| `UNAUTHORIZED` | 401 | Missing or invalid API key |
| `FORBIDDEN` | 403 | Valid key but insufficient permission |
| `NOT_FOUND` | 404 | Resource does not exist |
| `VALIDATION_ERROR` | 400 | Invalid request body or parameters |
| `BAD_REQUEST` | 400 | General bad request |
| `CONFLICT` | 409 | Operation conflicts with existing data |
| `TOO_MANY_REQUESTS` | 429 | Rate limit exceeded |
| `INTERNAL_SERVER_ERROR` | 500 | Unexpected server error |
## Validation errors
When request validation fails, `details.issues` lists each problem:
```json theme={null}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Some fields are invalid. Please check and try again.",
"details": {
"issues": [
{ "field": "firstName", "message": "Required" },
{ "message": "Unknown field: foo. Only documented fields and cf_* keys are allowed." }
]
}
}
}
```
## Retry guidance
* **429** — Back off and retry after the window in `RateLimit-Reset`
* **500** — Retry with exponential backoff
* **400 / 409** — Fix the request; retrying without changes will fail
# ID prefixes
Source: https://docs.heffl.com/api-v2/id-prefixes
Prefixed string IDs used across API v2 requests and responses
# ID prefixes
API v2 uses **prefixed string IDs** everywhere in requests and responses. The prefix identifies the resource type. There is no separate "public ID" concept in the API — these strings are the `id` fields you send and receive.
## Prefix reference
| Prefix | Resource | Example | Used in |
| ------- | -------------------------------------------------------- | ------------- | ----------------------------------------------------------------------- |
| `clt_` | Contact or company (client) | `clt_abc123` | `clientId`, contact/company `id`, deal filters |
| `dpl_` | Deal pipeline | `dpl_abc123` | `pipelineId`, deal filters |
| `dps_` | Deal pipeline stage | `dps_abc123` | `stageId`, deal filters |
| `dl_` | Deal | `dl_abc123` | Deal `id`, quotation `dealId`, task `entityId` when `entity` is `deals` |
| `qtn_` | Quotation | `qtn_abc123` | Quotation `id` |
| `tpl_` | Document template (quotations, invoices, proforma, etc.) | `tpl_abc123` | Quotation `templateId` |
| `txr_` | Tax rate | `txr_abc123` | Line item `taxRateId` on quotations and deals |
| `tsk_` | Task | `tsk_abc123` | Task `id` |
| `usr_` | Team user | `usr_abc123` | `ownerUserId`, `assigneeIds`, filters |
| `tag_` | Tag | `tag_abc123` | `tags`, `tagIds`, filters |
| `cs_` | Client stage | `cs_abc123` | Contact/company `stageId` |
| `lstg_` | Lead stage | `lstg_abc123` | `leadStageId` |
| `src_` | CRM source | `src_abc123` | `sourceId`, `crmSourceId` |
| `lst_` | List | `lst_abc123` | List filters |
| `prd_` | Product | `prd_abc123` | Deal line items, `services` filter |
| `ld_` | Lead | `ld_abc123` | `leadId`, task `entityId` when `entity` is `leads` |
| `prj_` | Project | `prj_abc123` | Project `id`, project filters |
| `ppl_` | Project pipeline | `ppl_abc123` | Project `pipelineId`, project filters |
| `pps_` | Project pipeline stage | `pps_abc123` | Project `stageId`, project filters |
## Discovering IDs
| You need | Call |
| --------------------------------------- | ------------------------------------------------------------------------- |
| Pipeline and stage IDs | `GET /pipelines` or `GET /pipelines/{id}` |
| Project pipeline and stage IDs | `GET /project-pipelines` or `GET /project-pipelines/{id}` |
| User IDs | `GET /users` |
| Tag IDs | `GET /tags` |
| Client stage IDs | `GET /client-stages` |
| Source IDs | `GET /sources` |
| Product IDs | `GET /products` |
| Custom field keys (`cf_*`) | `GET /custom-fields?entity=deals` (and other entities) |
| Document template IDs | `GET /document-templates` (use `type=quotations` for quotation templates) |
| Contact/company/deal/quotation/task IDs | List or create the resource |
## Response consistency
All resource IDs in API v2 responses use the same prefixed string format as requests — including `pipelineId`, `stageId`, `clientId`, and `ownerUserId` on deals.
# API v2 Overview
Source: https://docs.heffl.com/api-v2/introduction
Heffl REST API v2 — resource-oriented endpoints with consistent envelopes
# API v2 Overview Beta
Heffl API v2 is the current REST API for programmatic access to your workspace. System and custom object records are exposed at resource paths such as `/contacts`, `/companies`, `/deals`, `/quotations`, and `/tasks` with a consistent response envelope and structured errors.
API v2 is in **beta**. Endpoints, schemas, and behavior may change as we expand coverage. Prefer it for new integrations, but expect breaking changes until GA. [Legacy API v1](https://docs.heffl.com/using-the-heffl-api) remains fully supported for existing integrations.
## Base URL
```
https://api.heffl.com/api/v2
```
All endpoints are served over HTTPS.
## What's new in v2
| Feature | v1 (legacy) | v2 |
| -------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Response shape | Flat resource object | List: `{ data, meta }` envelope; create/update/delete return the resource directly |
| Error shape | `{ code, message }` | `{ error: { code, message, details? } }` |
| Resource paths | Flat (`/clients`) | Resource-based (`/contacts`, `/companies`) |
| Contacts | `POST /clients` with `type: "contact"` | `GET /contacts`, `POST /contacts`, `PATCH /contacts/{id}`, `DELETE /contacts/{id}` |
| Companies | `POST /clients` with `type: "company"` | `GET /companies`, `POST /companies`, `PATCH /companies/{id}`, `DELETE /companies/{id}` |
| Deals | `GET /deals`, `POST /deals`, `GET /deals/{id}`, `PATCH /deals/{id}`, `DELETE /deals/{id}` | `GET /deals`, `POST /deals`, `GET /deals/{id}`, `PATCH /deals/{id}`, `DELETE /deals/{id}` |
| Quotations | — | `GET /quotations`, `POST /quotations`, `GET /quotations/{id}`, `PATCH /quotations/{id}`, `DELETE /quotations/{id}` |
| Tasks | `GET /tasks`, `POST /tasks`, `GET /tasks/{id}`, `PATCH /tasks/{id}`, `DELETE /tasks/{id}` | `GET /tasks`, `POST /tasks`, `PATCH /tasks/{id}`, `DELETE /tasks/{id}` |
## Contacts
| Method | Path | Description |
| -------- | ---------------- | ------------------------------------- |
| `GET` | `/contacts` | List contacts (paginated, filterable) |
| `POST` | `/contacts` | Create a contact |
| `PATCH` | `/contacts/{id}` | Update a contact |
| `DELETE` | `/contacts/{id}` | Delete a contact |
## Companies
| Method | Path | Description |
| -------- | ----------------- | -------------------------------------- |
| `GET` | `/companies` | List companies (paginated, filterable) |
| `POST` | `/companies` | Create a company |
| `PATCH` | `/companies/{id}` | Update a company |
| `DELETE` | `/companies/{id}` | Delete a company |
## Deals
| Method | Path | Description |
| -------- | ------------- | ---------------------------------- |
| `GET` | `/deals` | List deals (paginated, filterable) |
| `GET` | `/deals/{id}` | Get a deal |
| `POST` | `/deals` | Create a deal |
| `PATCH` | `/deals/{id}` | Update a deal |
| `DELETE` | `/deals/{id}` | Delete a deal |
List active deals in a pipeline:
```bash theme={null}
curl -G "https://api.heffl.com/api/v2/deals" \
-H "x-api-key: YOUR_API_KEY" \
--data-urlencode 'pageSize=25' \
--data-urlencode 'filters={"pipelineId":{"operator":"is","values":["dpl_abc123"]},"status":{"operator":"is","values":["ACTIVE"]}}'
```
Create a deal by linking a client, pipeline, and stage:
```bash theme={null}
curl -X POST "https://api.heffl.com/api/v2/deals" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Enterprise license",
"clientId": "clt_abc123",
"pipelineId": "dpl_abc123",
"stageId": "dps_abc123",
"price": 25000,
"expectedCloseDate": "2026-06-30T00:00:00.000Z"
}'
```
## Quotations
| Method | Path | Description |
| -------- | ------------------ | ------------------------------------------ |
| `GET` | `/quotations` | List quotations (paginated, filterable) |
| `GET` | `/quotations/{id}` | Get a quotation with line items and totals |
| `POST` | `/quotations` | Create a quotation |
| `PATCH` | `/quotations/{id}` | Update a quotation |
| `DELETE` | `/quotations/{id}` | Delete a quotation |
Create a quotation for a client with line items:
```bash theme={null}
curl -X POST "https://api.heffl.com/api/v2/quotations" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": "clt_abc123",
"templateId": "tpl_abc123",
"date": "2026-05-31T00:00:00.000Z",
"subject": "Website redesign proposal",
"quotationProducts": [
{
"name": "Discovery workshop",
"quantity": 1,
"price": 2500,
"taxRateId": "txr_abc123"
}
]
}'
```
`clientId` is a contact or company ID (`clt_` prefix) — use the `id` from `GET /contacts` or `GET /companies`. Optional `contactId` (`clt_`) sets the contact person when the client is a company.
`templateId` is required (`tpl_` prefix). List quotation templates with `GET /document-templates?type=quotations` — see [Document templates](https://docs.heffl.com/api-v2/document-templates). Pass `dealId` (`dl_` prefix) to link the quote to a deal, and `tags` with `tag_` IDs. Custom fields use `cf_*` keys — see [Custom fields](https://docs.heffl.com/api-v2/custom-fields).
## Document templates
Templates used for **documents** in Heffl — quotations, invoices, proforma invoices, purchase orders, and similar (not project or email templates). List by `type` to get the `templateId` for API creates.
| Method | Path | Description |
| ------ | -------------------------- | -------------------------------------------------------- |
| `GET` | `/document-templates` | List document templates (filter by type, search by name) |
| `GET` | `/document-templates/{id}` | Get a template with template-scoped custom fields |
```bash theme={null}
curl "https://api.heffl.com/api/v2/document-templates?type=quotations" \
-H "x-api-key: YOUR_API_KEY"
```
## Tasks
| Method | Path | Description |
| -------- | ------------- | ---------------------------------- |
| `GET` | `/tasks` | List tasks (paginated, filterable) |
| `POST` | `/tasks` | Create a task |
| `PATCH` | `/tasks/{id}` | Update a task |
| `DELETE` | `/tasks/{id}` | Delete a task |
Link a task to a deal, lead, or project using `entity` and `entityId`:
```bash theme={null}
curl -X POST "https://api.heffl.com/api/v2/tasks" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Follow up on proposal",
"type": "call",
"dueDate": "2026-06-01T10:00:00.000Z",
"entity": "deals",
"entityId": "dl_abc123"
}'
```
## Quick start
List contacts with your API key:
```bash theme={null}
curl "https://api.heffl.com/api/v2/contacts?pageSize=25" \
-H "x-api-key: YOUR_API_KEY"
```
Response:
```json theme={null}
{
"data": [
{
"id": "clt_abc123",
"number": "CON001",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"phone": "+971501234567",
"createdAt": "2025-01-15T10:30:00.000Z",
"cf_industry": "Technology"
}
],
"meta": {
"nextCursor": null,
"hasMore": false
}
}
```
Update a contact (partial update — only send fields you want to change):
```bash theme={null}
curl -X PATCH "https://api.heffl.com/api/v2/contacts/clt_abc123" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobTitle": "Head of Sales",
"companyId": "clt_company456"
}'
```
Response:
```json theme={null}
{
"id": "clt_abc123",
"number": "CON001",
"firstName": "Jane",
"lastName": "Smith",
"jobTitle": "Head of Sales",
"companyId": "clt_company456",
"createdAt": "2025-01-15T10:30:00.000Z"
}
```
Delete a contact:
```bash theme={null}
curl -X DELETE "https://api.heffl.com/api/v2/contacts/clt_abc123" \
-H "x-api-key: YOUR_API_KEY"
```
Response:
```json theme={null}
{
"id": "clt_abc123",
"deleted": true
}
```
Deletion fails with `400` if the contact has linked deals, invoices, or quotations.
## Authentication
Same as v1 — include your API key in the `x-api-key` header on every request. See [Authentication](https://docs.heffl.com/api-v2/authentication).
## Response shape
**List endpoints** return a paginated envelope:
```json theme={null}
{
"data": [ ... ],
"meta": {
"nextCursor": null,
"hasMore": false
}
}
```
**Create, update, and delete** return the resource (or delete result) directly — not wrapped in `data`:
```json theme={null}
{
"id": "clt_abc123",
"firstName": "Jane",
"lastName": "Smith"
}
```
**Custom fields** are returned as top-level `cf_*` keys on each resource (for example `cf_industry`), not in a `customFields` object. See [Custom fields](https://docs.heffl.com/api-v2/custom-fields).
## Next steps
* [Agent workflows](https://docs.heffl.com/api-v2/agent-workflows) — multi-step sequences (create deal, close deal, tasks)
* [ID prefixes](https://docs.heffl.com/api-v2/id-prefixes) — `clt_`, `dpl_`, `dps_`, `dl_`, and other ID formats
* [Authentication](https://docs.heffl.com/api-v2/authentication) — API keys and permissions
* [Errors](https://docs.heffl.com/api-v2/errors) — error codes and validation details
* [Pagination](https://docs.heffl.com/api-v2/pagination) — cursor-based paging with `pageSize`
* [Listing & filters](https://docs.heffl.com/api-v2/listing-and-filters) — search, sort, and structured filters
* [Custom fields](https://docs.heffl.com/api-v2/custom-fields) — `cf_*` field conventions; discover keys via `GET /custom-fields`
* [Document templates](https://docs.heffl.com/api-v2/document-templates) — templates for quotations, invoices, proforma invoices, and other documents
* Browse endpoint reference in the sidebar
# Listing & filters
Source: https://docs.heffl.com/api-v2/listing-and-filters
Search, pagination, sorting, and structured filters in API v2 list endpoints
# Listing & filters
List endpoints in API v2 share the same query model used in the Heffl app. This applies to `GET /contacts`, `GET /companies`, `GET /deals`, `GET /quotations`, `GET /leads`, and `GET /tasks`.
Pass `filters` as a **JSON-encoded string** in the query (use `curl -G` with `--data-urlencode`). Example: `filters={"status":{"operator":"is","values":["ACTIVE"]}}`. Do not rely on nested query-object encoding — JSON in one query parameter is the supported approach for agents and integrations.
## Query parameters
| Parameter | Type | Default | Description |
| ---------- | ------ | ----------- | ------------------------------------------------------ |
| `cursor` | string | *none* | Cursor from the previous response (`meta.nextCursor`) |
| `pageSize` | number | 30 | Items per page (max 100) |
| `search` | string | *none* | Full-text search (fields vary by endpoint — see below) |
| `orderBy` | string | `createdAt` | Sort field (allowed values vary by endpoint) |
| `orderDir` | string | `desc` | Sort direction: `asc` or `desc` |
| `filters` | object | *none* | Structured filters (see below) |
API v2 list endpoints use `pageSize`, not `limit`. Legacy v1 endpoints still use `limit`.
## Basic list
```bash theme={null}
curl "https://api.heffl.com/api/v2/contacts?pageSize=25" \
-H "x-api-key: YOUR_API_KEY"
```
## Search
```bash theme={null}
curl "https://api.heffl.com/api/v2/contacts?search=jane%40example.com" \
-H "x-api-key: YOUR_API_KEY"
```
## Sorting
```bash theme={null}
curl "https://api.heffl.com/api/v2/contacts?orderBy=name&orderDir=asc" \
-H "x-api-key: YOUR_API_KEY"
```
## Structured filters
Each filter field accepts an object with `operator` and `values`:
```json theme={null}
{
"stageId": {
"operator": "is",
"values": ["cs_abc123"]
}
}
```
Pass filters as a JSON-encoded query parameter:
```bash theme={null}
curl -G "https://api.heffl.com/api/v2/contacts" \
-H "x-api-key: YOUR_API_KEY" \
--data-urlencode 'filters={"stageId":{"operator":"is","values":["cs_abc123"]}}'
```
### Available contact and company filters
| Field | Type | Value type | Example operators |
| ------------- | ------------ | ------------------ | ----------------------------------------------------------------------------------------------- |
| `stageId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `leadStageId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `ownerUserId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `createdById` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `listId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `tagId` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, `include_all_of`, `exclude_if_any_of`, `exclude_if_all` |
| `createdAt` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
Option and tag filters take **string IDs** — the same prefixed IDs returned by the API (for example `cs_abc123`, `usr_xyz789`, `tag_def456`). Date filters take ISO 8601 strings. `GET /contacts` always returns contacts only and `GET /companies` always returns companies only — you do not need to pass a `type` filter. Both support `search` on name, number, email, and phone, and `orderBy` of `createdAt`, `name`, or `number`.
### Available deal filters
| Field | Type | Value type | Example operators |
| ------------------- | ------------ | ------------------------------ | ----------------------------------------------------------------------------------------------- |
| `clientId` | option | contact or company ID (`clt_`) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `pipelineId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `stageId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `status` | option | `ACTIVE`, `WON`, `LOST` | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `priority` | option | `LOW`, `MEDIUM`, `HIGH` | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `ownerUserId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `crmSourceId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `createdById` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `listId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `tagId` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, `include_all_of`, `exclude_if_any_of`, `exclude_if_all` |
| `services` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, `include_all_of`, `exclude_if_any_of`, `exclude_if_all` |
| `createdAt` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
| `expectedCloseDate` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
Deals support `search` on title, number, and client name, and `orderBy` of `createdAt`, `position`, `expectedCloseDate`, or `price`. Client IDs use the `clt_` prefix; pipeline and stage IDs use `dpl_` and `dps_`; product filters use `prd_`. See [ID prefixes](https://docs.heffl.com/api-v2/id-prefixes).
### Available lead filters
| Field | Type | Value type | Example operators |
| ------------------ | ------------ | ------------------ | ----------------------------------------------------------------------------------------------- |
| `stageId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `ownerUserId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `assignedTo` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, `include_all_of`, `exclude_if_any_of`, `exclude_if_all` |
| `tagId` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, `include_all_of`, `exclude_if_any_of`, `exclude_if_all` |
| `crmSourceId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `listId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `archived` | option | boolean | `is`, `is_not` |
| `createdAt` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
| `nextActivityDate` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
| `createdById` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
Leads support `search` on name, title, mobile, email, secondary mobile, and website, and `orderBy` of `createdAt`, `position`, `name`, or `value`. Stage IDs use the `lstg_` prefix; assignee and owner filters use `usr_`; tags use `tag_`.
### Available task filters
| Field | Type | Value type | Example operators |
| ------------- | ------------ | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `status` | option | `OPEN`, `IN_PROGRESS`, `ON_HOLD`, `COMPLETED`, `CANCELLED` | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `type` | option | `call`, `todo`, `meeting` | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `priority` | option | `LOW`, `MEDIUM`, `HIGH` | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `createdById` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `assigneeIds` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, `include_all_of`, `exclude_if_any_of`, `exclude_if_all` |
| `tagIds` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, `include_all_of`, `exclude_if_any_of`, `exclude_if_all` |
| `createdAt` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
| `startDate` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
| `dueDate` | date | ISO 8601 date-time (due date) | `is`, `is_before`, `is_after`, `is_between`, … |
Tasks support `search` on title, number, and description, and `orderBy` of `createdAt`, `dueDate`, `startDate`, `number`, or `title`. Assignee and tag filters use `usr_` and `tag_` prefixes.
### Available quotation filters
| Field | Type | Value type | Example operators |
| ------------------ | ------------ | --------------------------------------- | ---------------------------------------------- |
| `status` | option | `DRAFT`, `SENT`, `ACCEPTED`, `REJECTED` | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `clientId` | option | contact or company ID (`clt_`) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `contactId` | option | contact person ID (`clt_`) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `salesPersonId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `createdById` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `tagId` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, … |
| `productId` | multi-option | string (ID) | `include`, `exclude`, `include_any_of`, … |
| `templateId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `dealId` | option | string (ID) | `is`, `is_not`, `is_any_of`, `is_none_of` |
| `subject` | text | string | `contains`, `does_not_contain`, … |
| `number` | text | string | `contains`, `does_not_contain`, … |
| `date` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
| `expiryDate` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
| `markedAcceptedOn` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
| `createdAt` | date | ISO 8601 date-time | `is`, `is_before`, `is_after`, `is_between`, … |
Quotations support `search` on number, subject, client name, and line item text. `orderBy` accepts `createdAt`, `date`, `number`, or `expiryDate`. Client IDs use `clt_`; deal IDs use `dl_`; template IDs use `tpl_`; product filters use `prd_`. See [ID prefixes](https://docs.heffl.com/api-v2/id-prefixes).
```bash theme={null}
curl -G "https://api.heffl.com/api/v2/deals" \
-H "x-api-key: YOUR_API_KEY" \
--data-urlencode 'filters={"pipelineId":{"operator":"is","values":["dpl_abc123"]},"status":{"operator":"is","values":["ACTIVE"]}}'
```
### Filter examples
Owner is a specific user:
```json theme={null}
{
"ownerUserId": {
"operator": "is",
"values": ["usr_xyz789"]
}
}
```
Contacts tagged with any of several tags:
```json theme={null}
{
"tagId": {
"operator": "include_any_of",
"values": ["tag_abc", "tag_def"]
}
}
```
Created in a date range:
```json theme={null}
{
"createdAt": {
"operator": "is_between",
"values": ["2025-01-01T00:00:00.000Z", "2025-01-31T23:59:59.999Z"]
}
}
```
## Permissions
List results respect the API key user's permissions:
* **Contacts and companies** — If the user cannot view records owned by others, results are limited to records they own.
* **Deals** — If the user cannot view deals owned by others, results include only deals they own or are assigned to.
* **Leads** — If the user cannot view leads owned by others, results include only leads they own or are assigned to.
* **Tasks** — If the user cannot view tasks assigned to others, results include only tasks they created or are assigned to.
* **Quotations** — If the user cannot view quotations owned by others, results include only quotations where they are the sales person (or `salesPersonId` is unset).
## Response
```json theme={null}
{
"data": [
{
"id": "clt_abc123",
"number": "CON001",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"phone": "+971501234567",
"salutation": "Ms.",
"jobTitle": "Operations Manager",
"companyId": "clt_company456",
"createdAt": "2025-01-15T10:30:00.000Z",
"cf_industry": "Technology"
}
],
"meta": {
"nextCursor": "clt_xyz789",
"hasMore": true
}
}
```
Fetch the next page with the cursor:
```bash theme={null}
curl "https://api.heffl.com/api/v2/contacts?cursor=clt_xyz789&pageSize=25" \
-H "x-api-key: YOUR_API_KEY"
```
# Connect Heffl to AI (MCP)
Source: https://docs.heffl.com/api-v2/mcp
Let Claude, ChatGPT, or Cursor work with your Heffl data — no coding, no API keys
# Connect Heffl to your AI assistant
You can connect Heffl to AI assistants like **Claude**, **ChatGPT**, and **Cursor** so they can look up and update your Heffl data for you — right inside a normal chat.
Once connected, you can simply ask things like:
> "Show me my open deals over AED 50,000."
>
> "Create a contact for Sarah at Acme, email [sarah@acme.com](mailto:sarah@acme.com)."
>
> "List tasks due this week and mark the Acme follow-up as done."
The assistant does the work in Heffl for you. No spreadsheets, no API keys, no setup files.
This uses a standard called **MCP** (Model Context Protocol). You don't need
to know what that means — just follow the steps for your app below.
## Supported apps
Free or paid
Paid plan required
Free or paid
## Before you start
You'll need:
* A **Heffl account** you can sign in to (the same email and password you normally use).
* One of the supported apps shown above.
* This one address, which you'll paste into your app:
```
https://api.heffl.com/api/mcp
```
Copy that address now — every app below asks you to paste it in one box.
## Connect your app
Go to [claude.ai](https://claude.ai), click your **profile icon** in the
corner, and choose **Settings**.
In the sidebar, click **Connectors**. Scroll to the bottom and click
**Add custom connector**.
In the box that appears, paste:
```
https://api.heffl.com/api/mcp
```
You can name it **Heffl**. Click **Add**.
A Heffl sign-in window opens. Log in with your usual email and password.
If you belong to more than one team, pick the team the assistant should
use. Then click **Authorize** to allow access.
Heffl now appears in your connectors. Start a new chat and ask Claude
about your Heffl data.
Custom connectors in ChatGPT require a **paid plan** (Plus, Pro, Team,
Business, or Enterprise) and **Developer Mode** turned on. The free plan
can't add custom connectors.
In ChatGPT, go to **Settings → Apps** (or **Connectors**) →
**Advanced settings**, and turn on **Developer mode**.
On a Business/Enterprise workspace, an admin may need to enable this
under **Workspace Settings → Connectors**.
Go to **Settings → Connectors** and click **Create** (or
**New connector**).
For the server URL, paste:
```
https://api.heffl.com/api/mcp
```
Name it **Heffl** and save.
A Heffl sign-in window opens. Log in with your usual email and password.
If you belong to more than one team, pick the team the assistant should
use, then click **Authorize**.
In a chat, open the **apps / connectors** menu and turn on **Heffl** to
let ChatGPT use it.
In Cursor, open **Settings** and find the **MCP** (or **Tools**)
section. Click **Add new MCP server**.
Choose a remote / URL server and paste:
```
https://api.heffl.com/api/mcp
```
Or, if Cursor asks for a config file, use:
```json theme={null}
{
"mcpServers": {
"heffl": {
"url": "https://api.heffl.com/api/mcp"
}
}
}
```
The first time you use it, a Heffl sign-in window opens. Log in, pick a
team if asked, and click **Authorize**.
## Choosing a team
If your Heffl login has access to **more than one team**, the sign-in step asks
you to **pick one team**. The assistant will only see and change data in that
team.
To switch the assistant to a different team later, **remove the Heffl connector
and add it again**, then pick the other team when you sign in.
## What the assistant can do
Once connected, the assistant can help with the same things you can do in Heffl,
for example:
| You can ask… | It will… |
| ------------------------------------------ | --------------------------- |
| "List my contacts at Acme." | Find contacts and show them |
| "Create a deal for Acme worth AED 80,000." | Add a new deal |
| "What invoices are unpaid this month?" | Look up invoices |
| "Add a task to call Sarah tomorrow." | Create a task |
| "Update Acme's stage to Won." | Change the record |
The assistant makes **real changes** in your Heffl account — creating a
contact or deal actually creates it. There's no practice mode. Read what it's
about to do before approving an action.
## Is it safe?
* The assistant signs in **as you** and can only do what your Heffl role allows.
* It only ever touches the **one team** you picked during sign-in.
* You never share your password with the AI app — you log in on Heffl's own
secure page, just like signing in to the website.
* You can disconnect anytime by removing the Heffl connector in your app's
settings.
## Troubleshooting
Double-check the address is exactly `https://api.heffl.com/api/mcp` with no
extra spaces. Then remove the connector and add it again.
Your browser may have blocked a pop-up. Allow pop-ups for the app, remove
the Heffl connector, and add it again so the sign-in window can open.
Remove the Heffl connector in your app's settings and add it again. When the
Heffl sign-in appears, choose the correct team.
Custom connectors need a **paid ChatGPT plan** and **Developer Mode** turned
on. On a company workspace, ask your admin to enable custom connectors.
The assistant can only do what your Heffl user is allowed to do. If you
can't perform the action in Heffl yourself, the assistant can't either — ask
your Heffl admin to adjust your permissions.
## For developers
The MCP server is exposed at `https://api.heffl.com/api/mcp` using the
**Streamable HTTP** transport and authenticates with **OAuth 2.1** (dynamic
client registration — clients register themselves, no manual API key).
Every [API v2](https://docs.heffl.com/api-v2/introduction) operation is offered as a tool, named
`
# Pagination
Source: https://docs.heffl.com/api-v2/pagination
Cursor pagination in API v2
# Pagination
List endpoints in API v2 use cursor-based pagination with a consistent shape:
```json theme={null}
{
"data": [ ... ],
"meta": {
"nextCursor": "cursor_value_or_null",
"hasMore": true
}
}
```
## Query parameters
| Parameter | Type | Default | Description |
| ---------- | ------ | ------- | ----------------------------------------------------- |
| `cursor` | string | *none* | Cursor from the previous response (`meta.nextCursor`) |
| `pageSize` | number | 30 | Items per page (max 100) |
API v2 uses `pageSize`. Legacy v1 list endpoints use `limit` instead.
## Example
```bash theme={null}
curl "https://api.heffl.com/api/v2/contacts?pageSize=25" \
-H "x-api-key: YOUR_API_KEY"
```
Response:
```json theme={null}
{
"data": [
{
"id": "clt_abc123",
"number": "CON001",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com"
}
],
"meta": {
"nextCursor": null,
"hasMore": false
}
}
```
See [Listing & filters](https://docs.heffl.com/api-v2/listing-and-filters) for search, sorting, and structured filters.
# Breaking projects into tasks
Source: https://docs.heffl.com/breaking-projects-into-tasks
Tasks are the individual pieces of work that make up a project. Breaking a project into tasks lets you assign work to people, track what is done, and see overall progress. This guide covers creating and managing tasks within a project.
***
## How tasks relate to projects
A project is the whole body of work; tasks are the steps to complete it. For example, a "Website" project might have tasks like Planning, Designing, and Internal Review.
Each task belongs to a project and carries its own ID based on the project (such as MFE-1 or CR3-1). As tasks are completed, the project's **progress percentage** updates, which you can see on the Kanban cards (for example, "3 tasks, 67%").
***
## Where to find tasks
You can work with tasks in two places:
* **Inside a project**, where the project's own tasks are listed and managed together
* **The Tasks area** in the sidebar, which collects tasks across all projects and records in one place
Working inside a project keeps you focused on one piece of work; the Tasks area gives you a single to-do list across everything.
***
## Adding a task to a project
1. Open the project
2. Find its tasks section
3. Add a new task
4. Give it a title and set its details (see below)
If you start a project from a **template**, it comes with preset tasks already added, so you do not build the list from scratch each time. This is useful for repeatable work like a maintenance or registration project. See [Creating and managing projects](https://docs.heffl.com/creating-and-managing-projects).
***
## Task details
When adding or editing a task, you can typically set:
* **Title**, what the task is
* **Assignee**, who is responsible
* **Due date** or schedule
* **Status**, marking it open or complete
* A **description** with any notes
Assigning each task to a person and giving it a date means everyone knows what they are responsible for and by when.
***
## Tracking progress
As tasks are marked complete, the project's progress updates automatically. On the Kanban board, each project card shows its task count and completion percentage, so you can spot at a glance which projects are on track and which are stalled.
***
## Logging time against tasks
Tasks connect directly to timesheets. When a team member logs time, they select the project and the specific task they worked on, so hours are attributed at the task level. This feeds your billable and non-billable totals. See [Logging timesheets and tracking hours](https://docs.heffl.com/logging-timesheets-and-tracking-hours).
***
## Quick task creation
For quick to-dos, the **Focus** area inside any record lets you add a task with a fast due date (In 1h, In 3h, Tomorrow, Next week, or a custom date). This is handy for capturing a follow-up without leaving what you are doing.
***
## What to do next
1. [Log timesheets](https://docs.heffl.com/logging-timesheets-and-tracking-hours) against your project tasks
2. Move the project through its stages as tasks complete
3. Set up [recurring projects](https://docs.heffl.com/creating-and-managing-projects) for repeating task lists
# Changelog
Source: https://docs.heffl.com/changelog
Product updates and releases for Heffl.
> **Note:** This page is generated from release JSON in `packages/changelog/src/data/`. After editing or adding files, run `npm run generate` in `packages/changelog`, then from `apps/docs` run `pnpm sync`.
## Issue 011 — 2026-05-19
*Deeper accounting sync, document kanban, and sales workflows*
This release expands QuickBooks and Zoho integrations with job sync, tax handling, and one-click resync, adds kanban and custom fields to documents, streamlines invoice and quotation editing, and brings bulk actions, ownership, and calendar preferences across CRM, sales, and purchases.
### Features
#### QuickBooks & Zoho: Jobs, Tax, and Resync
Accounting integrations go much further this release:
* Field service jobs can sync to QuickBooks as sub-customers under the parent client, with currency and tax handled correctly.
* Invoices, payments, clients, purchase orders, and jobs now have a Resync action when a sync fails or data changes after the first push.
* Zoho tax rates and chart of accounts sync into Heffl, and invoice and purchase order tax resolution is more reliable across both providers.
* Zoho Cliq notifications can be toggled from notification preferences.
#### Team Date Format and Week Start
Team settings now include a Week starts on preference (Monday or Sunday) that applies to calendars and date pickers across the app, alongside expanded date format options including D.M.YYYY. Your choice syncs instantly wherever dates are shown.
#### Documents: Kanban View and Custom Fields
Documents work more like the rest of your CRM:
* Switch documents to a kanban board grouped by status or any supported field, drag cards between columns, and configure which fields appear on each card.
* Add custom fields to documents and filter or display them in list and kanban views.
* Document numbers from your numbering settings are wired through creation and display, and document names are generated more consistently.
#### Bulk Mark Invoices as Sent
Select multiple draft invoices from the invoice list and mark them all as sent in one action. Non-draft invoices in the selection are skipped automatically, with a confirmation showing how many will be updated.
#### Purchases: Bulk Delete
Bills, expenses, payments, purchase orders, and vendors now support bulk delete from their list pages. Select multiple rows, confirm, and Heffl checks for blockers such as recorded payments before removing records.
***
## Issue 010 — 2026-04-18
*Document signing, AI editing, QuickBooks, and smarter forms*
This release brings an AI writing assistant for documents, a round of document signing and editor upgrades, a QuickBooks integration, one-click contact creation from form submissions, richer form settings, and Workers app permissions.
### Features
#### AI Writing Assistant in Documents
The document editor now includes an AI prompt that can draft, rewrite, and refine document content directly inside the editor, so you can produce polished quotations, proposals, and contracts much faster.

#### Document Signing and Editor Updates
A round of upgrades across sending, signing, and styling documents:
* Document recipients can now be client contacts or team members, so internal approvers and external clients can sign the same document through one flow.
* Signed documents render their signature blocks accurately in both the editor preview and the printable / client-hub view, so a signed document always looks the way the signer saw it.
* Toggle table borders on and off from the document editor toolbar.
* Tables without a set width no longer stretch to full page width, giving you much tighter control over quotations and proposals.

#### QuickBooks Integration
Connect Heffl to QuickBooks from the integrations page. Invoices created in Heffl flow through to QuickBooks, keeping your accounting in sync without double entry.

#### Forms: Contacts, Settings, and Polish
Forms got smarter end-to-end:
* Form responses detect the submitter's name, email, and phone automatically. A Create contact button turns any submission into a CRM contact in one click, and if a contact with that email already exists the modal links straight to it.
* Customize the label of the Previous button on multi-step forms from form settings.
* New form fields are now inserted in the correct position every time.
* The shared input, textarea, and rating components on public forms got a round of visual and keyboard-handling fixes.

#### Workers App Permission Sets
Field service workers can now be assigned granular permission sets that control what they see and do in the staff app, including whether client phone numbers and emails are visible on schedules.
### Fixes
#### Report Charts Rendering
Fixed an issue where report charts could fail to render because of the lazy-loaded Recharts setup, and tidied up chart behavior on the templates page at the same time.
***
## Issue 009 — 2026-04-05
*Multi-currency, Polish, and a faster command palette*
Recent updates make product news easier to follow, add multi-currency support where you create invoices and manage clients, expand language options, and speed up navigation across the app.
### Features
#### Multi-currency on clients and invoices
Choose the currency for an invoice with a searchable picker and flags, and work with client-level currency preferences so amounts match how you bill and get paid.

#### Polish language
Heffl is available in Polish in addition to existing languages, so more teams can use the product in their preferred language.
### Improvements
#### Command palette and settings navigation
The command palette and settings navigation were refined so you can jump to pages and tools faster with fewer clicks.
***
## Issue 008 — 2026-03-27
*From list speed to document workflows and reliability*
This release focuses on faster list navigation, broader sales and document workflows, stronger message templates, and a wide set of reliability fixes across CRM, projects, and field service.
### Features
#### Instant Form Share Responses
Added an option to view form share responses instantly from the form share view, making it easier to validate and react to new submissions in real time.
#### Project Template Assignee Replacement
Projects created from templates can now remap template task assignees during setup. Teams can replace template users with current assignees or leave tasks unassigned, making template-based project creation much more practical across different teams.
#### Bulk Job Completion
Field service teams can now complete multiple jobs in one action from the jobs list. Completing jobs in bulk also closes linked schedules that are still pending so job and schedule status stay aligned.
#### Message Templates for More Entity Types
Message template entity resolution now covers a wider set of records, including quotations, invoices, deals, leads, clients, bills, proforma invoices, purchase orders, and sales orders. Template boilerplates and variable metadata were also expanded so personalization works across more document workflows.
#### Email Actions for More Document Types
Email sending was extended and unified for bills, purchase orders, sales orders, and proforma invoices. Detail pages now expose more direct email actions, and the send pipeline produces more consistent document names and defaults across document types.
#### Required Salesperson and Job Fields
Teams can now require a salesperson on quotations and enforce required fields such as salesperson, payment method, and LPO number on field service jobs, with clearer validation messages when details are missing.
### Improvements
#### Sidebar and Navigation Polish
Sidebar expand controls and team-switcher navigation were refined for cleaner behavior and better nested-item presentation. These updates make the newer navigation surfaces feel more consistent across the app.
### Fixes
#### Lead Stage Change Triggers
Fixed an issue where automations and triggers were not reliably firing when lead stages were updated, so stage-based workflows now run consistently.
***
## Issue 007 — 2026-03-10
This release improves how projects are created and managed, with better templates, clearer workflows, and more flexible task views.
### Features
#### Richer Project Templates
Templates can now include defaults for project title, description, lead, assignees, tags, and predefined line items with totals. When a project is created from a template, these values are applied automatically.
#### More Detailed Template Tasks
Tasks inside templates now support types such as task, meeting, and call, along with priority, due-day offsets, assignees, tags, workflow stage, and subtasks in a cleaner editor. Template task lists are also easier to scan and reorder.
#### Stage-Based Task Workflow
Project task lists can now be grouped by workflow stage. Tasks can be reordered within a stage or moved between stages with drag-and-drop, and new tasks can be created directly inside any stage group.
#### Flexible Task Views
Tasks can now be viewed in table, calendar, kanban, or gantt layouts. Custom views can be saved and accessed as their own tabs so teams can work in the layout that fits their workflow.
### Improvements
#### Faster Project Setup
Creating a new project now starts with a pipeline selection step followed by a template picker. Teams can begin with a blank project or choose a template in the same flow, making project setup faster and clearer from the start.
***
## Issue 006 — 2026-03-07
Major public API expansion, automation upgrades, integrations, and broad platform reliability improvements.
### Features
#### Public API Expansion with Public IDs
Expanded public API coverage with broader CRUD endpoints across core CRM entities, migrated routes to public IDs, and improved OpenAPI documentation for external integrations.
#### Advanced Automation Capabilities
Added date-based triggers, delay actions, richer trigger outputs, enhanced control-flow handling, webhook action improvements, and expanded automation templates including agency-focused flows.
#### Integration Suite Enhancements
Shipped and improved Zapier, Fathom, TidyCal, Cal.com, LunaCal, WhatsApp, and SMTP integrations with stronger setup flows, validation, and webhook handling.
#### Forms and Custom Fields Expansion
Introduced Heffl AI-powered form import, form sharing and deletion capabilities, and expanded custom field support including KEY\_VALUE, SIGNATURE, RATING, OPINION\_SCALE, and BOOLEAN field types.
#### Client Portal and Payment Schedule Updates
Enhanced client portal workflows with payment scheduling improvements, overdue visibility, project files support, and refined access handling for contacts and clients.
### Improvements
#### Tax Treatment Coverage Across Sales and Purchases
Extended tax treatment logic and tax treatment code support across line items, bundles, invoices, bills, expenses, field service, and related schemas for more consistent accounting behavior.
#### Dashboards, Data Grids, and UI Performance
Added new dashboard widgets, improved table persistence and loading behavior, and delivered broad accessibility and performance refinements across UI components and list views.
#### Project and Task Workflow Enhancements
Upgraded recurring task/profile workflows, improved task modal ergonomics, added attachment-related improvements, and refined project/task data handling for better day-to-day execution.
#### Documents, Templates, and Print Experience
Enhanced document template rendering and navigation, improved quotation and invoice actions, expanded page number controls, and improved print/PDF rendering behavior.
#### Email and Messaging Workflow Refinements
Improved email normalization and send pipelines, added/expanded CC-BCC and attachment handling, and improved message template personalization and delivery reliability.
### Bug fixes
#### Integration Reliability and Sync Fixes
Resolved multiple issues across calendar and integration sync flows, webhook edge cases, OAuth/config handling, and provider-specific delivery behavior.
#### Platform Stability and Quality Fixes
Addressed a broad set of platform fixes across CRM, documents, tasks, forms, field service, and admin surfaces, including many low-level stability and regression patches.
***
## Issue 005 — 2026-01-04
Performance improvements, quick actions, invoice subject fields, and client portal updates.
### Features
#### Quick Actions Feature
Quick actions in sidebar for faster access to frequently used features.
#### Subject Field for Invoices
Added subject field to invoices for better organization.
#### Links in Files (Client Portal)
Added links support in client portal files.
#### Bulk Actions for Timesheets
Added bulk actions for timesheets to manage multiple entries at once.
### Improvements
#### Client Portal Settings Revamp
Redesigned client portal settings with improved UI and preview.
#### Client Portal UI Fixes and Enhancements
Fixed UI issues in client portal and improved visual consistency.
#### Project List Improvements
Improved project list performance and added new features.
#### Message Templates with Contact Variables
Added firstName and lastName variables to message templates.
#### Entity Selector Enhancements
Improved entity selector component across the platform.
### Bug fixes
#### Fixed Project Routes and Timesheets
Fixed issues in project routes and timesheets.
#### Various Bug Fixes and Improvements
Fixed various bugs and improved performance across the platform.
***
## Issue 004 — 2025-12-29
This release brings significant enhancements to the client portal with projects integration, new API endpoints for tasks, comprehensive custom fields improvements, enhanced form capabilities, improved client onboarding experience, and various bug fixes and performance optimizations across the platform.
### Features
#### Task API Endpoints
Added both public and regular task API endpoints, enabling external systems to create, read, update, and manage tasks programmatically. This opens up new integration possibilities for task management.
#### Custom Fields Enhancements
Enhanced custom fields functionality with improved field management, better handling of duplicate field names, and streamlined field configuration across the platform.
#### Form Ending Page with Redirect URL
Forms now support custom redirect URLs after completion. Configure a redirect URL in your form settings to send users to a specific page or website after they submit the form.
### Improvements
#### Activity Timeline Improvements
Added meeting activity button to the activity timeline. Leads and deals now use activity timeline actions for better tracking and visibility of all interactions and updates.
#### Download Progress Modal
Added download progress feedback for invoices and quotations. Users now see real-time progress indicators when downloading documents, providing better visibility into download status.
#### Message Templates with Contact Variables
Message templates now support firstName and lastName variables for contacts, enabling more personalized communication. Use `{{firstName}}` and `{{lastName}}` in your templates for dynamic personalization.
#### Block Editor Enhancements
Refactored block editor components with TypeScript improvements and enhanced MiniRichTextEditor. Improved code quality and maintainability while maintaining all existing functionality.
#### Date Format Support
Added date format functionality across the platform, providing consistent date formatting options and better date handling in various contexts.
#### Email Templates Updates
Updated email templates for clients, companies, and resources with improved content and better formatting for enhanced communication.
#### Resources Page with Videos and Changelog
Enhanced resources page with video content and integrated changelog functionality, providing users with better access to learning materials and release information.
### Bug fixes
#### Fixed Deals Search Issue
Resolved search functionality issues in the deals section, ensuring accurate and reliable search results.
#### Fixed Lead Conversion Issues
Fixed various issues related to lead conversion process, ensuring smooth conversion of leads to deals and clients.
#### Various Bug Fixes
Fixed multiple bugs across the platform including UI improvements, form handling fixes, client page view issues, and various performance optimizations.
***
## Issue 003 — 2025-12-12
This release brings significant enhancements to automations with templates and duplicate functionality, improved deal management with rotten deals tracking, comprehensive form improvements, new field service reporting capabilities, and various performance optimizations across the platform.
### Features
#### Automation Templates
Browse and use pre-built automation templates to quickly set up common workflows. Templates are now available in the automations section with preview functionality.
#### Duplicate Automation Functionality
Duplicate existing automations with a single click. All automation steps and configurations are preserved, making it easy to create variations of existing workflows.
#### Rotten Deals Tracking
Visual indicators for deals that haven't been updated within their configured rotting period. Rotten deals are now displayed in both kanban and mobile views with badges showing how many days they've been inactive.
#### Form Display Settings
Added display settings for forms allowing you to control logo visibility, title and description display, and progress bar visibility. Configure these settings in Form Settings.
#### Field Staff Work Report
New comprehensive report showing field service staff work hours, services breakdown, and performance metrics. Filter by date range and specific staff members.
#### Quotation Automation Triggers
Automation triggers for quotation events - created, updated, and deleted. Set up automations to respond automatically to quotation lifecycle changes.
#### Lead and Deal Stage Changed Triggers
Automation triggers that fire when leads or deals move between stages. Configure stage-specific automations with stageId and dealPipelineId inputs.
#### Lead Creation from Webhook Trigger
Create leads automatically from webhook triggers. Integrate external systems to create leads in your CRM when specific events occur.
#### Create Task Action in Automations
New automation action to create tasks automatically. Use this action in your automation workflows to generate tasks based on triggers.
#### Rich Text Editor for Automation Email Body
Rich text editor now available for email body fields in automations. Format your automation emails with rich text formatting, links, and more.
#### iOS App Back on App Store
Our iOS mobile app is now available again on the App Store. Access your CRM, manage deals, leads, and projects on the go with our native iOS application.
#### Duplicate Leads Functionality
Option to enable duplicate leads functionality in settings. Once enabled, you can quickly duplicate existing leads with a single click. All lead information, custom fields, and associated data are preserved, making it easy to create similar leads or follow-up opportunities.
### Improvements
#### Schedule Details Enhancement
Schedule details now use structured data selection for better performance. Improved query handling in schedule details modal.
#### Integration List Optimization
Optimized integration list with search functionality. Improved performance and user experience when managing integrations.
### Bug fixes
#### Various Bug Fixes
Fixed multiple bugs across the platform including form handling issues, automation trigger fixes, lead creation fixes, and various UI improvements.
***
## Issue 002 — 2025-11-25
This release includes significant API enhancements, email integration improvements, notification system upgrades, new integrations, code refactoring for better maintainability, and various bug fixes across the platform.
### Features
#### Public API Update Endpoints
Added Update endpoints for clients and leads.
#### Form Response Webhook Trigger
Webhook trigger for form responses.
#### German, Romanian Language Support in Client Portal
Added German and Romanian language support to the client portal.
### Improvements
#### Email Integration Encoding Fixes
Improved email sending for Gmail, Outlook, and Zoho Mail integrations.
### Bug fixes
#### Fixed Email Subject Encoding
Fixed email subject line encoding for Gmail integration to properly handle non-ASCII characters and special characters in email subjects.
***
## Issue 001 — 2025-11-20
So much has happened since the last release. We've added a lot of new features and improvements to the system. We've also fixed a lot of bugs and issues.
### Features
#### E-signature Support for Quotations
Introduced e-signature support for quotations. You can now enable this in Document Templates → Template Settings.
#### Stripe Integration (Beta)
Stripe integration (Beta) is now available for online payments.
#### Multi-language Support in Client Portal
Added multi-language support in the client portal for quotations and invoices — now supporting Dutch, French, and German.
#### Embed External URLs in Client Portal
You can now embed external URLs directly inside the client portal.
#### Webtabs Support
Added webtabs support, allowing you to display custom web content within the system.
#### Webhooks for Major Events
Introduced webhooks for all major events, enabling deeper integrations.
#### New API Endpoints
New API endpoints are now available to extend system connectivity.
### Improvements
#### Location Support for Zoho Books Integration
Added location support for Zoho Books integration.
#### Location Links in Google Calendar Sync
Added location links support in Google Calendar sync for meetings.
#### Fixed Google Calendar Sync for Tasks
Fixed Google Calendar sync issue for tasks.
#### Updated Invoice and Quotation Preview
Updated invoice and quotation preview to improve clarity and design.
#### Separate Product Descriptions
Added separate product descriptions for improved visibility.
#### More Customization Options
Added more customization options for branding and layout.
#### Bulk Delete for Products
Added bulk delete option for products.
#### Rebuilt Bulk Import
Bulk import for clients, deals, and leads fully rebuilt — now more accurate, faster, and reliable.
#### Kanban Boards Fully Revamped
Kanban boards fully revamped — significantly improved performance, smoother drag-and-drop, and bug-free.
### Bug fixes
#### Fixed Notification Issues for Tasks
Fixed various notification issues related to tasks.
***
# Creating and managing custom fields
Source: https://docs.heffl.com/creating-and-managing-custom-fields
Custom fields let you add your own data to Heffl's records, capturing the information specific to your business that the standard fields do not cover, such as a contract end date, a tenant name, or a tank size. You manage them under **Settings > Custom fields**, in the Customization section.
***
## What a custom field is
Every record type in Heffl (leads, deals, clients, projects, quotations, and more) comes with standard fields. A custom field adds an extra field of your choosing to one of those record types. Once created, it appears on that record's form so your team can fill it in, and it becomes available in filters, documents, and the API.
For example, a field service business might add a "Contract End date" to Projects, while an agency might add a "Referred by" field to Leads.
***
## Adding a custom field
1. Go to **Settings > Custom fields**
2. Click **+ Custom field** (or press **C**)
3. In the **Add custom field** dialog, set:
* **Object**, the record type the field attaches to (such as Lead, Deal, Client, Project, Quotation, Invoice, or Quotation Line Item)
* **Type**, the kind of data the field holds (see below)
* **Label**, the field's name as your team sees it
* **API Name**, the identifier used in the API, auto-prefixed with `cf_` (for example, `cf_contract_end_date`)
* **Helper text**, an optional placeholder or hint shown on the field
* **Required**, toggle on to make the field mandatory
* **Unique**, toggle on to require a different value for every record
4. For option-based types, add the choices under **Options** with **Add option**
5. Click **Add field**
The field then appears on the chosen record type immediately.
***
## Field types
Choose the type that matches the data you are capturing:
* **Text**: a single line of text
* **Long Text**: a longer, multi-line entry
* **Number**: numeric values
* **Date**: a calendar date
* **Single Option**: pick one choice from a list you define
* **Multiple Option**: pick several choices from a list
* **Array Text**: a list of text values
* **Phone Number**: a telephone number
* **Email**: an email address
* **Currency**: a monetary amount
* **Link**: a web URL
* **Relation**: link to another record
* **File Picker**: attach a file (available on AppSumo Tier 3)
* **Signature**: capture a signature (available on AppSumo Tier 3)
Pick the most specific type for your data, since it shapes how the field is entered and validated. A Date field gives a date picker, an Email field expects an email format, and option types restrict entries to your defined list.
***
## Options for choice fields
When you choose **Single Option** or **Multiple Option**, an **Options** section appears. Add each choice with **Add option**, and reorder them by dragging. These become the selectable values on the field, so your team picks from a consistent list rather than typing free text.
***
## Required and unique fields
Two toggles control how a field behaves:
* **Required** means the record cannot be saved without a value, use it for information you must always capture
* **Unique** means no two records can share the same value, useful for identifiers like a reference or account number
Use Required sparingly, only for fields that truly must be filled every time, so you do not slow down record creation.
***
## Managing existing custom fields
The Custom fields list shows every field as a card with its label, type, API name (such as `cf_passport_expiry`), and the entity it applies to. A Required badge marks mandatory fields.
To find a field, use:
* **Search** to look it up by name
* The **Status** filter (such as Active)
* The **Entity** filter to see fields for one record type
Open a field to edit it, and deactivate fields you no longer use rather than deleting them, so existing data is preserved.
***
## How custom fields connect elsewhere
Custom fields are not just for storing data; they flow through Heffl:
* They appear on the record's form for everyone to fill in
* They can be used in **filters** to segment records
* They are accessible through the **API** using their `cf_` key. See [Using the Heffl API](https://heffl.com).
* Document-scoped fields can appear on quotations and invoices
This means a custom field you add becomes a first-class part of your workspace, not an isolated note.
***
## What to do next
1. Add the fields your business needs to each record type
2. Use [filters](https://heffl.com) to segment records by your custom fields
3. Reference them via the [API](https://heffl.com) if you build integrations
# Creating and managing projects
Source: https://docs.heffl.com/creating-and-managing-projects
This guide covers creating a project, setting it up, and managing it through to completion. For an overview of how projects, pipelines, and views work, see [Introduction to project management in Heffl](https://docs.heffl.com/introduction-to-project-management-in-heffl).
***
### Creating a project
1. Go to **Projects** in the sidebar
2. Click **+ Project** in the top right (or press **C**)
3. **Choose a pipeline** for the type of work (Website, Bookkeeping, Construction, and so on). Each pipeline has its own stages.
4. **Pick a template or start blank**:
* **Continue blank** starts a fresh project with no preset tasks
* **Use template** starts from a saved template that pre-fills tasks and items (the card shows how many tasks and items it includes)
5. Fill in the project details
6. Save
You can also add a new template from this screen with **Add template**, or edit an existing one before using it.
***
### Creating a project from a deal
When a deal is won and work needs delivering, open the deal and click **Convert to Project**. The deal's client and details carry into the new project, so you do not re-enter them. See [Working with the deals pipeline](https://heffl.com/).
***
### Setting up the project
When creating or editing a project, set these details:
* **File title** or project name
* **Description**, a brief or notes about the work
* **Stage**, the starting point in the pipeline (such as Discovery)
* **Assignees** and **project lead**
* **Start date** and **End date**
* **Client**
* **Tags**
* **Budgeted hours**, the time you expect the project to take
* **Line items**, the products or services tied to the project
* **Billing type**, such as Flat Rate
A clear title, client, dates, and budgeted hours give you the foundation to track the project accurately.
***
### Viewing and finding projects
Switch views from the tabs at the top depending on what you need: **Kanban** for a status board, **Table** for a detailed list, and **Gantt** for a timeline. See the [introduction](https://heffl.com/) for what each view shows.
To find projects, use the toolbar:
* **Sort** orders by created date and other fields
* **Filters** narrows the list
* **Workflow** filters to a specific pipeline
* **Status** switches between Active and Archived
* **Search** finds a project by name
You can also create or edit pipelines from here using **Add workflow** and **Edit workflows**.
***
### Managing a project
Open a project to manage it. From the detail view you can:
* Move it through **stages** as work progresses
* Add and assign **tasks**. See [Breaking projects into tasks](https://docs.heffl.com/breaking-projects-into-tasks)
* Log **timesheets** against it. See [Logging timesheets and tracking hours](https://docs.heffl.com/logging-timesheets-and-tracking-hours)
* Attach **files** and briefs
* Update **details** such as dates, assignees, and budgeted hours
* Track **progress**, shown as a percentage based on completed tasks
***
### Moving a project through stages
Advance a project as the work moves forward:
* On the **Kanban board**, drag the project card between columns
* In the **Table view**, change the Phase (stage) directly
* In the **project detail view**, set the stage from the stage controls
Keeping stages current means your board, reports, and progress percentages stay accurate.
***
### Archiving and closing projects
When a project is finished, move it to its closing stage (such as Completed) so it shows under the Closed group on the board. To hide a project from the active list without deleting it, archive it. Archived projects can be viewed again using the Status filter.
***
### What to do next
1. [Break the project into tasks](https://docs.heffl.com/breaking-projects-into-tasks)
2. [Log timesheets](https://docs.heffl.com/logging-timesheets-and-tracking-hours) against the work
3. Set up [recurring projects](https://heffl.com/) for repeating work
# Creating and sending quotations
Source: https://docs.heffl.com/creating-and-sending-quotations
Quotations are the professional quotes you send to clients. Heffl lets you build one in minutes from a template, add line items and pricing, and send it for the client to accept. You will find Quotations in the sidebar (under Finance). This guide covers creating, building, and sending a quote.
***
## Creating a quotation
1. Go to **Quotations** in the sidebar
2. Click **+ Quotation** in the top right (or press **C**)
3. Choose a template (see below)
4. Fill in the quote details
5. Add your line items
6. Save and send
***
## Choosing a template
When you start a quote, Heffl opens the **Select a Template** window with two tabs:
* **My templates** are the templates saved in your workspace, plus a **Create from Scratch** option for a blank quote
* **Discover templates** are ready-made designs you can use, such as Web Development Quote, Business Proposal, and Service Quotation
Pick a template to start with its layout and styling, or create from scratch for a blank document. Using a template saves time and keeps your quotes consistent and branded.
***
## Filling in the quote details
At the top of the quote, set the key fields:
* **Template** and **Currency**
* **Date** and **Expiry date** (how long the quote is valid)
* **Tags** and **Sales person**
* **Client**, the company or contact the quote is for
* **Property**, **Contact**, and **Deal** to link the quote to related records
* **Subject**, a short description of the quote
Linking the quote to a client, contact, and deal keeps it connected to the rest of your records and pulls the right details automatically.
***
## Adding line items
The body of the quote is built from line items, the products or services you are quoting for. For each line you can set:
* **Item**, typed or selected from your product catalog
* **Description**
* **Qty** (quantity)
* **Rate** and **Discount**
* **Tax**, such as 5% standard
* **Amount**, calculated automatically
Use the buttons below the table to build the quote:
* **Line item** adds a product or service row
* **Heading** adds a section title to group items
* **Bundle** adds a predefined group of items
You can also set whether **Amounts are** inclusive or exclusive of tax. The **Subtotal**, **Tax**, and **Total** calculate automatically at the bottom as you add items.
To pull from your catalog, use **Add product**. See [Managing products and services (catalog)](https://docs.heffl.com/managing-products-and-services-catalog).
***
## Form and content views
At the top right, switch between:
* **Form**, where you enter the structured quote data (client, line items, totals)
* **Content**, where you edit the document's written content and layout
Use **Notes** to add internal notes, and **Settings** to adjust quote options.
***
## Saving and sending
Click **Save Draft** (or press **Ctrl + Enter**) to save the quote as a draft. When ready, send it to the client by email or share it through the client portal.
A quote moves through statuses you can track from the Quotations list: **Draft**, **Sent**, **Accepted**, and **Expired**. The list shows each quote's number, client, date, expiry, status, currency, subtotal, total, sales person, and creator.
***
## After the quote is accepted
Once a client accepts, convert the quote into an invoice in one click so you can collect payment. See [Invoices: creating, sending, and statuses](https://docs.heffl.com/invoices-creating-sending-and-statuses).
***
## What to do next
1. [Manage quotation line items and pricing](https://heffl.com/) in detail
2. [Convert an accepted quotation to an invoice](https://heffl.com/)
3. Set up your [products and services](https://heffl.com/) catalog for faster quoting
# Creating and sharing forms
Source: https://docs.heffl.com/creating-and-sharing-forms
Forms let you collect information from clients, leads, or your team through a shareable form, such as an intake form, a feedback survey, or an onboarding questionnaire. Responses are stored in Heffl where you can review them. You will find **Forms** in the sidebar.
***
## The Forms list
The Forms page lists every form with columns for:
* **Name**
* **Created At** and **Created By**
* **Entity**, the record type the form is associated with (such as "leads"), or "No entity linked"
* **Responses**, how many submissions it has received
Click a form to open it, or use **Search** to find one.
***
## Creating a form
Click **+ Form** to open **Create a new form**, then pick a starting point:
**Start from scratch** Build the form manually with full control over its pages and fields.
**Import with Heffl AI** Let AI draft the form for you. Choose one of:
* **Type or paste**, write a prompt or paste source text (for example, "Create a website intake form with contact info, brand goals, timeline, budget range, and required services")
* **Upload document**, drag in a `.txt` or `.docx` file and let Heffl AI turn it into a form
Then click **Generate draft with Heffl AI** to produce a draft you can refine.
**Use template** Reusable form templates (coming soon).
Tip: when prompting the AI, include phrases like "select one" or "select all that apply" so it builds the right option fields.
***
## Building the form
The form opens in the **Builder** tab, where you can:
* **Add fields** with **+ Field**, the questions and inputs your form collects
* **Add pages** with **+ Add**, to split a longer form into multiple steps
* Set a **Thank you / Ending page** shown after submission
* **Customize** the form's appearance
* Click any page or question to edit its settings
**Notify Users** Choose which team members are alerted when someone submits the form, so responses do not go unnoticed.
***
## Linking a form to an entity
A form can be associated with a record type (its **Entity**, such as leads), or left with no entity linked. This association organizes responses under that record type.
Note that linking a form to an entity does **not** automatically create a record when someone submits, it stores the response. If you want a submission to create a lead or another record, use an [automation](https://docs.heffl.com/introduction-to-automations) triggered by the form.
***
## Sharing a form
Once your form is ready, share it from the top-right actions:
* **Copy link**, share a public link people can open and fill in
* **Embed**, place the form directly on your website using the embed option
Anyone with the link, or anyone visiting the page where it is embedded, can submit the form without logging into Heffl.
***
## Viewing responses
Open the **Responses** tab to see submissions. Each response shows:
* **Created At**, when it was submitted
* A response **Number**
* **Linked To**, the record it is associated with, if any
The response count also appears on the Forms list, so you can see at a glance which forms are getting traction.
***
## What to do next
1. Share your form by [link or embed](https://heffl.com/) it on your site
2. Set up an [automation](https://docs.heffl.com/setting-up-your-first-automation) to act on submissions (for example, create a lead)
3. Review responses in the Responses tab
# Exporting and sharing a quotation
Source: https://docs.heffl.com/exporting-and-sharing-a-quotation
Once a quotation is ready, you can get it out of Heffl in several ways: download it as a PDF, print it, email it to the client, or share a link. This guide covers each option, all found at the top of the quotation detail view.
***
## Downloading as a PDF
To save a copy of the quote to your device:
1. Open the quotation from the **Quotations** list
2. Click the **download** icon in the top right
3. The quote saves as a PDF, named after the quote and client (for example, "Quotation QTTS-1027")
The PDF matches the template and preview exactly, including your logo, line items, totals, and terms. Use this when you need a file to keep, attach elsewhere, or archive.
***
## Printing
To print the quote or save it as a PDF through your browser:
1. Click **Print** in the top right
2. Your browser's print dialog opens, showing a preview of the quote
3. Choose your **Destination** (a printer, or "Save as PDF")
4. Set **Pages**, **Layout** (Portrait or Landscape), and **Color** as needed
5. Click **Print**
This is handy when a client wants a physical copy, or when you prefer your browser's PDF output.
***
## Sending by email
To send the quote straight to the client from Heffl:
1. Click **More** in the top right
2. Select **Send via email**
3. Confirm the recipient and message
4. Send
The client receives the quote by email. Sending this way keeps the quote's status accurate (it moves toward Sent) and logs the action in the quote's history.
You can also use **Mark as sent** to record that a quote has been sent if you delivered it another way.
***
## Sharing a link
To give the client a link they can open in a browser:
1. Click **More** in the top right
2. Select **Share a link**
3. Copy the link and send it to the client
A shared link lets the client view the quote online without needing a file attachment. This is the same way quotes appear in the client portal.
***
## Which method to use
Each option suits a different need:
* **Download PDF** when you need a file to keep or attach
* **Print** when you need a paper copy or browser-based PDF
* **Send via email** when you want Heffl to deliver it and track the status
* **Share a link** when the client prefers to view it online
For most cases, sending by email or sharing a link is best, since both keep the quote connected to its record and update its status automatically.
***
## What to do next
1. [Convert an accepted quotation to an invoice](https://docs.heffl.com/invoices-creating-sending-and-statuses)
2. [Track invoices and payment status](https://docs.heffl.com/payments-recording-and-collecting)
3. Set up [products and services](https://docs.heffl.com/managing-products-and-services-catalog) for faster quoting
# Filtering and sorting leads
Source: https://docs.heffl.com/filtering-and-sorting-leads
When your lead list grows, filtering and sorting help you focus on what matters. This guide covers every filter and sort option on the Leads page. All of these work in both list view and Kanban view, and they apply together, so you can stack filters and sorting to narrow down precisely.
***
## Sorting leads
Click **Sort** in the toolbar to choose how your leads are ordered. You pick a field and a direction.
### **Sort by**
* **Created at** orders by when the lead was added (the default)
* **Name** orders alphabetically
* **Value** orders by estimated deal value
### **Direction**
* **Ascending** goes from low to high, oldest to newest, or A to Z
* **Descending** goes from high to low, newest to oldest, or Z to A
The current sort shows in the toolbar, for example "Created at - desc", so you always know how the list is ordered.
***
## Filtering by stage
Click **Stage** to show only leads at certain points in your pipeline. Tick one or more stages:
* New
* Followed up
* Contacted
* Demo Done
* Unqualified
* Junk
* Converted
Tick several to see them together, or click **Clear** to remove the stage filter. Use the search box inside the dropdown to find a stage quickly if you have many.
***
## Filtering by status
Click **Status** to switch between:
* **Active** shows your live leads (the default)
* **Archived** shows leads you have archived but not deleted
Archived leads are hidden from the default view, so use this filter when you need to find one again.
***
## Filtering by next activity date
Click **Next Activity Date** to focus on leads that need attention within a time window:
* **Today**
* **Tomorrow**
* **Next 7 Days**
* **Next 30 Days**
* **Custom** for a specific date range you choose
This is the best filter for planning your day or week, since it surfaces the leads with follow-ups coming due. Click **Clear** to remove it.
***
## More filters
Click **Filters** for additional ways to narrow your leads:
* **Created at** filters by when leads were added
* **List** filters by a saved list the lead belongs to
* **Assigned to** filters by the team member assigned
* **Owners** filters by lead owner
* **Sources** filters by where the lead came from
* **Lost Reasons** filters leads marked unqualified by their reason
Use the search box at the top of the Filters panel to find an option quickly.
***
## Searching
For finding one specific lead rather than a group, use the **search** icon in the toolbar. Search matches the lead's name and other key details, and works alongside any filters you have applied.
***
## Combining filters and sorting
Filters and sorting stack. For example, you can:
* Filter to **Stage: Contacted** and **Next Activity Date: Next 7 Days**, then **Sort by Value, Descending**, to see your highest-value contacted leads needing follow-up this week.
Because these controls carry over when you [switch between list and Kanban view](https://docs.heffl.com/switching-between-list-view-and-kanban-view), you can set up your filters once and view the results either way.
***
## Clearing filters
Each filter dropdown has its own **Clear** option to remove just that filter. Remove filters one at a time to widen your view gradually, or clear them all to return to your full lead list.
***
## What to do next
1. Save a group of leads as a [List](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/c57ab4bf-6da5-47e1-86ee-f35998963ed4) for quick repeat access
2. [Add notes and tags](https://docs.heffl.com/adding-notes-and-tags-to-a-lead) to organize leads further
3. Convert qualified leads into [deals](https://docs.heffl.com/adding-and-managing-deals)
# How to Sign Up and Log In
Source: https://docs.heffl.com/getting-started/how-to-sign-up-and-log-in
## How to sign up and log in
This guide walks you through creating a new Heffl account, logging in, and managing your session.
***
## Creating a new account
### **Step 1: Go to the signup page**
Visit [app.heffl.com/signup](http://app.heffl.com/signup). You will see a registration form ready for your details.
### **Step 2: Enter your information**
* Name: Enter your full name
* Email: Use a valid email address (you will need to verify it)
* Password: Create a strong password of at least 8 characters
### **Step 3: Select your timezone**
Heffl automatically detects your timezone. Change it if needed to ensure dates and times display correctly across your workspace.
### **Step 4: Submit the form**
Click "Sign up". Heffl will create your account, send a verification email, and log you in automatically.
***
## Joining via team invitation
### **Step 1: Check your email**
Look for an invitation email from Heffl. It contains a signup link with your email address pre-filled.
### **Step 2: Click the invitation link**
The link takes you to the signup page with your email already entered. Add your name and create a password.
### **Step 3: Complete signup**
Submit the form. Heffl will create your account, add you to the team automatically, and take you to your new workspace.
***
## Logging in with email and password
1. Go to [app.heffl.com/login](https://app.heffl.com/login)
2. Enter your email address
3. Enter your password
4. Click "Login"
***
## OTP login (passwordless)
### **Step 1: Choose OTP login**
On the login page, select the OTP option instead of entering your password.
### **Step 2: Enter your email**
Type your email address and click "Send OTP". A 6-digit code will be sent to your inbox.
### **Step 3: Enter the code**
Return to Heffl, enter the 6-digit code, and click "Verify" to log in. Codes expire after a few minutes, so enter it promptly.
***
## Email verification
After signing up with email and password, you may need to verify your email before accessing all features.
### **Step 1: Check your inbox**
Look for a verification email from Heffl. It arrives within a few minutes of signup.
### **Step 2: Click the verification link**
Click the link in the email to confirm your address.
### **Step 3: Access your account**
Once verified, log in to access all Heffl features.
***
## Switching between workspaces
If you are a member of more than one Heffl workspace (for example, as a consultant or team member across multiple businesses):
1. Click your profile icon in the top right corner
2. Select "Switch workspace"
3. Choose the workspace you want to open
Each workspace has its own data, settings, and team members. Switching does not log you out.
***
## Mobile login
Heffl is available on iOS and Android.
1. Download the Heffl app from the [App Store](https://apps.apple.com/us/app/heffl/id6478108057)
2. Open the app and tap "Log in"
3. Enter your email and password, or use OTP login
4. Tap "Sign in" to access your workspace
All your data syncs automatically between the mobile app and the web version.
***
## Signing out
### **From your current device**
Click your profile icon in the top right corner and select "Sign out".
***
## Session timeout
Heffl keeps you logged in for 30 days on trusted devices. After 30 days of inactivity, you will be asked to log in again. If you are logged out unexpectedly, check your internet connection or clear your browser cache and try again.
***
## Troubleshooting
### **Verification email not received**
* Check your spam or junk folder
* Confirm you entered the correct email address
* Request a new verification email from the login page
### **Forgot your password**
Click "Sign in using OTP" on the login page. Heffl will send an OTP to your email.
### **Invitation link not working**
* Check if you already have a Heffl account with that email address
* Ask your team admin to resend the invitation
* If the issue persists, create an account first and ask the admin to add you manually
***
## What happens after login
### **First-time users**
Heffl walks you through a quick onboarding process:
1. Set up your company details
2. Choose which modules or apps you need
3. Invite team members (optional)
See the [Workspace setup guide](https://docs.heffl.com/getting-started/untitled-page-1) to learn more.
### **Returning users**
If you've already completed onboarding, you'll land on your Heffl dashboard ready to work.
# Navigating the interface
Source: https://docs.heffl.com/getting-started/navigating-the-interface
This guide explains how to find your way around Heffl. Once you know where things live, you can move between modules and records in seconds.
***
## The layout
The Heffl interface has three main areas:
* **The sidebar** on the left for navigation
* **The top bar** for dashboards, search, and account actions
* **The main area** in the center, where your content and records appear
***
## The sidebar
The sidebar is your primary way to move around. It is grouped into clear sections:
### **Top level**
* **Home** — your dashboard and starting point
* **Inbox** — messages and updates in one place
* **Tasks** — your to-do items across the workspace
* **Contracts** — active agreements
* **Notifications** — alerts and reminders
### **Records**
Direct access to your core business data: Leads, Companies, Contacts, Deals, Quotations, Projects, and Finance.
### **Apps**
Your activated modules: Field Service, Files, Forms, Automations, Reports, Templates, and Apps & integrations.
### **Bottom of the sidebar**
* **Configure features** — turn modules on or off
* **Web Tabs** — quick links to external sites you have pinned
You can collapse the sidebar using the arrow at the bottom to give yourself more screen space.
***
## Switching workspaces
At the very top of the sidebar, you will see your current workspace name (for example, "Heffl Cleaning") with a dropdown arrow. Click it to switch between workspaces if you belong to more than one. See [Switching between workspaces](https://heffl.com/) for details.
***
## The top bar
Running across the top of the screen:
* **Dashboard tabs** let you switch between your saved dashboards (Personal, CRM Dashboard, Financials, and others)
* The **+** next to the tabs creates a new dashboard
* **Search** (the magnifying glass) finds records, pages, and settings instantly
* The **+** button creates a new record quickly from anywhere
***
## Quick search
Click the search icon or use it from the top of the sidebar to find anything fast. Search works across leads, clients, deals, quotes, projects, and settings. Start typing a name or keyword and select the result to jump straight to it.
This is usually the fastest way to reach a specific record, rather than navigating through menus.
***
## The quick add button
The green **+** button near the top lets you create new records from anywhere in Heffl, without navigating to the right module first. Use it to quickly add a lead, task, deal, quote, or other item.
***
## Moving between records
Within any module, lists show your records in rows. Click a row to open the full record. From there you can:
* View and edit details
* See linked items (for example, deals linked to a client)
* Add activities, notes, or tasks
* Move back to the list using the back arrow or breadcrumb at the top
***
## On mobile
The Heffl mobile app uses the same structure in a compact form. The sidebar becomes a menu you open with the menu icon, and search and quick add remain easy to reach. Your data stays in sync with the web version automatically.
***
## What to do next
Now that you can navigate Heffl:
1. Use search to find your most-used records quickly
2. Pin frequent external links under Web Tabs
3. Customize your dashboard so your key information is front and center
# Quick start guide (5-minute setup)
Source: https://docs.heffl.com/getting-started/quick-start-guide-5-minute-setup
This guide gets you from a new account to your first sent quote in about five minutes. For detailed setup, see [Setting up your workspace](https://docs.heffl.com/getting-started/untitled-page-1).
***
## Before you begin
Have these ready:
* Your company name and logo
* Your bank details or a Stripe account (for payments)
* One client's name and email to test with
***
## Step 1: Add your company details (1 minute)
Go to **Settings > Organization > General** and enter your company name, logo, address, and default currency. These appear on every document you send, so this matters most.
***
## Step 2: Turn on the modules you need (30 seconds)
Go to **Settings > Organization > Permission Set** and enable what fits your business. If unsure, start with **CRM + Sales**. You can add more later.
***
## Step 3: Add your first lead (1 minute)
Go to **Records > Leads** and click **+Lead**. Enter their name and email. This is the client you will send a test quote to.
***
## Step 4: Create and send a quote (2 minutes)
1. Go to **Records > Quotations** and click **+Quotation** or press “C”
2. Select the client you just added
3. Add a product or type a line item with a price
4. Click **Send**
Your client receives a professional quote by email. You have now completed the core Heffl workflow.
***
## Step 5: Explore your dashboard (30 seconds)
Return to **Home**. Your dashboard shows tasks, meetings, and quick access to every module.
***
## What to do next
You are set up. From here:
* **Invite your team** so others can help. See [Inviting your team members](https://docs.heffl.com/getting-started/untitled-page-2).
* **Connect your email** to send documents from your own address. Go to **Settings > Organization > Integrations**.
* **Set up payments** so clients can pay online. Connect Stripe or add bank details under **Settings > Organization > Payment Methods**.
* **Explore your modules** from the sidebar to match Heffl to your full workflow.
# Modules in Heffl: quick overview
Source: https://docs.heffl.com/getting-started/untitled-page
Heffl is built around a modular system. You activate the features your business needs and add more as you grow, with each module designed to work alongside the others. This page introduces the main modules and how they connect.
***
## Core modules
These are the modules that power most businesses on Heffl.
### CRM (Customer Relationship Management)
Manage your customer relationships from first contact to long-term client, tracking every interaction so no follow-up is missed.
* **Leads**: capture and track potential customers
* **Deals**: manage your sales pipeline through visual stages
* **Companies and Contacts**: store complete client information and history
* **Dashboard**: view key metrics and activity
Best for sales, business development, and customer service.
### Sales and Finance
Handle everything from quotes to payments, creating professional documents in minutes and tracking each transaction.
* **Quotations**: create and send professional quotes
* **Invoices** and **Proforma**: bill clients and track payment status
* **Payments**: record receipts and manage outstanding balances
* **Products**: maintain your catalog of products and services
* **Recurring invoices**: bill on a schedule automatically
Best for billing, collections, and financial tracking.
### Projects
Organize work into projects and track tasks from start to finish.
* **Tasks**: create, assign, and track the work
* **Board, table, and Gantt views**: see projects by status or on a timeline
* **Timesheets**: log hours, billable or non-billable
* **Recurring projects**: regenerate repeating work automatically
Best for project managers, service delivery teams, and agencies.
***
## Supporting features
Alongside the core modules, these work across all your modules rather than standing alone:
* **Forms**: capture information from clients or your team
* **Automations**: trigger actions automatically
* **Files**: store and share documents
* **Wiki**: keep internal notes and guides
* **Inbox**: handle WhatsApp, LinkedIn, and email in one place
* **Reports** and **Templates**: analyze data and reuse document designs
* **Client Portal**: give clients a space to view and pay
***
## How modules work together
The real value comes from how the modules connect into end-to-end workflows.
### **Lead to invoice**
* Capture a lead in CRM
* Convert it to a deal when interest is shown
* Create a quote in Sales
* Convert the accepted quote into an invoice
* Record payments until it is fully paid
### **Project to billing**
* Create a project in Projects
* Track tasks and log time as work progresses
* Invoice the client with billable time included
* Record payments against the work
***
## Choosing your modules
During onboarding you select which features to activate, and you can adjust them later.
* Start from a **bundle** suited to a business type, for example CRM with Sales, or Field Service with CRM, Sales, and Purchases
* Or activate **individual modules** to match specific needs
* If a feature you expect is missing, an admin can enable it.
***
## Default features
Some things are in every workspace by default:
* **Settings**: configure your workspace and preferences
* **Templates**: access and manage document templates
* **Team management**: owners and admins invite and manage members
See [Workspace and organization settings](https://docs.heffl.com/workspace-and-organization-settings) and [Inviting your team members](https://docs.heffl.com/getting-started/untitled-page-2).
***
## Accessing your modules
Once active, reach your modules from:
* The **sidebar** on the left
* The **Apps** page, which shows active modules as cards
* The **global search** bar for quick access
***
## What to do next
1. [Set up your workspace](https://docs.heffl.com/getting-started/untitled-page-1) and activate your modules
2. Read [How Heffl is organized](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/82a3fe2b-502b-418f-ae00-afa5e487ba4b) to see how everything fits
3. Follow the [quick start guide](https://docs.heffl.com/getting-started/quick-start-guide-5-minute-setup) to get going
# Setting up your workspace
Source: https://docs.heffl.com/getting-started/untitled-page-1
This guide walks you through configuring your Heffl workspace after signing up for the first time. Complete these steps before inviting your team.
***
## 1. Company details
Go to **Settings > Company** and fill in the following:
* Company name
* Logo (used on quotes, invoices, and the client portal)
* Address
* Phone number
* Website
* Default currency
* Timezone
> These details appear automatically on all documents you send to clients, so make sure they are accurate before creating any quotes or invoices.
***
## 2. Set up your document templates
Go to **Settings > Templates** to configure the documents you send to clients.
* Select a quote template and set a default validity period
* Select an invoice template and configure payment terms
* Add your bank details or connect Stripe for online payments
* Set a default footer message or terms and conditions
> These defaults apply to every new document you create, saving you time on repeat work.
***
## 3. Configure your integrations
Go to **Settings > Integrations** to connect Heffl with the tools you already use.
* **Email** — connect Gmail, Outlook, or Zoho Mail to send documents directly from Heffl
* **Accounting** — sync invoices with QuickBooks or Zoho Books to avoid double entry
* **Calendar** — connect Calendly to sync meetings and follow-ups
* **Payments** — connect Stripe or Telr to accept online payments from clients
***
## 4. Invite your team
Go to **Settings > Members** and invite your team members.
1. Click "Invite member"
2. Enter their email address
3. Assign a role (Admin, Member, or custom)
4. Click "Send invite"
They will receive an email with a link to join your workspace. See [How to sign up and log in](https://docs.heffl.com/getting-started/how-to-sign-up-and-log-in) for what they will see on their end.
***
## What to do next
Once your workspace is set up, here is a suggested order to get started:
1. Add your first client in CRM
2. Create and send a quote from Sales
3. Convert the quote to an invoice once accepted
4. Schedule a job in Field Service or create a project in Projects
5. Invite your team and assign roles
See the [Modules overview](https://docs.heffl.com/getting-started/untitled-page) for a detailed guide on each module.
# Inviting your team members
Source: https://docs.heffl.com/getting-started/untitled-page-2
This guide explains how to invite people to your Heffl workspace, assign their roles, and manage their access. Inviting your team lets you share work, delegate tasks, and control who sees what.
***
## Sending an invitation
1. Go to **Settings > Organization > Members**
2. Click **Invite**
3. Enter the person's email address
4. Assign a role (see roles below)
5. Assign Permission Set
6. Send Invitation
Click **Send invite**
The person receives an email with a link to join. The link has their email pre-filled, so they only need to add their name and create a password.
***
## Choosing a role
The role you assign controls what each person can access. Set this carefully, as it determines how much of your business data they can see.
**Owner** The highest level of access. The owner has full control over every module, setting, and team member, and is the only role that can manage billing and delete the workspace. This role belongs to the person who created the workspace and is best kept with the business owner.
**Admin** Full access to all modules, settings, and team management. Admins can invite others, change roles, and edit workspace settings. Assign this only to people you trust with complete control.
**Member** Access only to the modules you assign. Members can do their work but cannot change workspace settings or manage the team. This is the right choice for most people.
**Field service worker** A restricted role for field staff who use the mobile staff app. You can control exactly what they see, including whether client phone numbers and email addresses appear on their schedules.
You can change anyone's role later from **Settings > Members**.
***
## What happens after you invite someone
Once you send the invite:
* The person appears in your **Invitation** tab.
* They receive the invitation email
* When they accept and sign up, their status changes to **Active**
If they do not see the email, ask them to check their spam folder, or resend the invite from the team list.
***
## Managing your team
From **Settings > Members**, you can:
* **Resend an invite** if someone did not receive it
* **Cancel a pending invite** before it is accepted
* **Change a role** as someone's responsibilities change
* **Deactivate a member** to remove their access without deleting their history
* **Reactivate a member** to restore access later
Deactivating a member keeps all their past work, comments, and records intact. Their name stays attached to the tasks and documents they handled.
***
## Controlling Permission Sets
When you invite a member, you can choose which modules they see by assigning Permission Sets. For example:
* A salesperson might get CRM and Sales only
* A project manager might get Projects and CRM
* A technician might get Field Service only
This keeps each person focused on their work and keeps sensitive data limited to those who need it.
***
## Troubleshooting
**The invite email did not arrive**
* Ask the person to check their spam or junk folder
* Confirm the email address is spelled correctly
* Resend the invite.
**The person already has a Heffl account** If their email is already linked to another Heffl workspace, they can use the same login and switch between workspaces.
**The invite link expired** Cancel the old invite and send a fresh one.
***
## What to do next
After your team has joined:
1. Confirm each person has the right role and permission sets
2. Assign tasks or deals to specific members
3. Set up notifications so the team stays updated
# Importing leads from a file (upload, select header, map columns)
Source: https://docs.heffl.com/importing-leads-from-a-file-upload-select-header-map-columns
If you already have leads in a spreadsheet, you can import them all at once instead of adding them one by one. Heffl walks you through a three-step process: upload, select header, and map columns.
***
## Before you start
### Prepare your file:
* Use a spreadsheet file (CSV or Excel)
* Put each lead on its own row
* Include a header row with column titles such as Name, Mobile, and Email
* At minimum, every lead needs a **Name**. All other fields are optional.
To match Heffl's format exactly, click **Download Template** on the import screen and fill it in. This is the easiest way to avoid mapping errors later.
***
## Step 1: Upload your file
1. Go to **Leads** in the sidebar
2. Click **Import** in the top right
3. Drop your file into the upload area, or click **Browse files** to select it
The panel on the right shows the columns Heffl expects, including Name (required), Mobile, Secondary Mobile, Email, Title, Value, Source, Tag, Website, Referred by, Company, Client types, Client type, and Channel.
***
## Step 2: Select the header row
Tell Heffl which row in your file contains the column titles. This is usually the first row.
Heffl uses this row to understand what each column means, so the next step can match your columns to the right fields.
***
## Step 3: Map columns
Match each column in your file to the matching Heffl field.
* Heffl auto-matches columns where the names are obvious (for example, a "Name" column maps to Name)
* Review each mapping and correct any that are wrong
* Leave a column unmapped if you do not want to import it
* Make sure your Name column is mapped, since it is required
When every column is mapped correctly, confirm to start the import.
***
## After importing
Once the import finishes:
* Your new leads appear in the Leads list
* Each lead enters at the default first stage (New)
* You can filter, tag, and assign them like any other lead
Review a few imported leads to confirm the data landed in the right fields. If something looks off, you can edit leads individually or archive the batch and re-import with corrected mapping.
***
## Troubleshooting
**Some rows did not import** Check that every row has a Name. Rows without a name are skipped.
**Data landed in the wrong field** Your column mapping was likely off. Re-import and check each mapping in Step 3 against the expected columns.
**The file would not upload** Confirm it is a supported format (CSV or Excel) and that it has a header row. Download the template and copy your data into it if problems continue.
***
## What to do next
After importing your leads:
1. [Filter and sort](https://docs.heffl.com/filtering-and-sorting-leads) to organize the new batch
2. [Add tags to group them](https://docs.heffl.com/adding-notes-and-tags-to-a-lead)
3. [Start converting qualified leads into deals](https://docs.heffl.com/managing-leads-adding-editing-and-converting)
# Inbox: managing conversations
Source: https://docs.heffl.com/inbox-managing-conversations
The Inbox brings your client conversations into one place, so your team can read and reply without switching between apps. Messages from connected channels arrive in a single unified view. You will find the **Inbox** in the sidebar, with each connected channel (such as WhatsApp) nested beneath it.
***
## Connecting a channel
Before messages appear, you connect a channel. For WhatsApp:
1. Open the **Inbox** and select **WhatsApp**
2. On the **Connect WhatsApp** screen, click **Connect WhatsApp**
3. Complete the secure connection flow
4. Once connected, your WhatsApp conversations load into the Inbox
The same approach applies to other channels: connect the account, and its conversations flow in. You manage these connections under Apps & integrations. See [Integrations](https://docs.heffl.com/integrations-and-connected-apps).
***
## A unified inbox
Instead of checking WhatsApp on one device, LinkedIn in a browser, and email somewhere else, the Inbox collects conversations from connected channels together:
* **WhatsApp**
* **LinkedIn**
* **Email** (Gmail, Outlook, or Zoho Mail)
Each conversation shows in one thread, so anyone on your team can pick it up and see the full history regardless of which channel the client used.
***
## Reading and replying
A connected channel opens with three areas:
* A **conversation list** on the left
* The **message thread** in the middle
* A **contact info** panel on the right
Open a conversation to read its full history and type a reply at the bottom. Your reply goes back out through the same channel, so a WhatsApp message is answered on WhatsApp, all without leaving Heffl.
Because conversations live in Heffl rather than on one person's phone or account, replies and history are visible to the team, not locked to a single device.
***
## Assigning conversations
Conversations can be assigned to team members, so it is clear who is responsible for responding. Assigning helps when several people share the Inbox: each conversation has an owner, nothing is answered twice, and nothing falls through the cracks.
***
## Converting a conversation into a lead
When a conversation turns into a real opportunity, convert it into a lead or contact directly from the Inbox. The conversation's details carry across, so you capture the prospect in your CRM without retyping anything.
Once converted, the lead behaves like any other, you can track its stage, log follow-ups, and move it toward a deal. See [Managing leads](https://docs.heffl.com/managing-leads-adding-editing-and-converting).
***
## Why a unified inbox helps
* No channel gets missed because it was on someone's personal app
* The whole team sees the full history of each client
* Replies, assignments, and follow-ups stay in one system
* A promising chat becomes a tracked lead in a click
***
## What to do next
1. [Connect your channels](https://heffl.com/) so messages flow in
2. [Convert promising conversations](https://heffl.com/) into leads
3. Assign conversations so your team knows who owns each one
# Integrations and connected apps
Source: https://docs.heffl.com/integrations-and-connected-apps
Heffl connects to the tools you already use, so data flows between them instead of being entered twice. You manage everything from **Apps & integrations** in the sidebar. This page lists the available integrations by category and how to connect them.
***
## How integrations work
Open **Apps & integrations** to see two areas:
* **Installed apps**, the Heffl modules already part of your workspace (CRM, Sales, Forms, Automations, Files, Field Service, and Purchases)
* **Integrations to connect**, third-party services you can link to Heffl
Use the **Search** box to find an integration quickly.
**What connecting looks like** Each integration opens its own **Connect** dialog. Depending on the service, you will either sign in and authorize Heffl, or enter account details such as an API key or credentials. Some, like Zoho Cliq, set up a bot or notification channel during the connect step. Follow the prompts and confirm to finish. Once connected, the integration moves into your installed apps and its data sync begins.
***
## Email
Connect an email account to send documents and messages from your own address, and bring email into the Inbox.
* **Gmail**, connect your Gmail account
* **Outlook**, connect your Outlook account
* **Zoho Mail**, connect your Zoho Mail account
* **SMTP Server**, connect your own mail server to send emails
***
## Messaging
Bring client conversations into Heffl's Inbox and send messages from automations.
* **WhatsApp API**, connect WhatsApp Cloud API to manage chats and send automation messages
* **Zoho Cliq**, receive Heffl notifications as direct messages from a Zoho Cliq bot
These feed the unified Inbox. See [Inbox: managing conversations](https://docs.heffl.com/inbox-managing-conversations).
***
## Payments
Let clients pay invoices online.
* **Stripe** (Beta), accept payments online with Stripe
* **Telr**, connect your Telr account
Once connected, payment options appear on shared invoices and in the client portal. See [Setting up the client portal](https://docs.heffl.com/setting-up-the-client-portal).
***
## Accounting
Sync your financial records to avoid double entry.
* **Zoho Books**, connect your Zoho Books account
* **Wafeq**, connect your Wafeq account
***
## Scheduling and booking
Sync meetings and bookings to your Heffl contacts.
* **Google Calendar**, see and update Google Calendar events directly in Heffl
* **Calendly**, sync Calendly bookings to Heffl contacts
* **TidyCal**, sync TidyCal bookings to Heffl contacts
* **LunaCal**, sync LunaCal bookings automatically when someone books through your LunaCal scheduling page
* [**Cal.com**](http://Cal.com), sync [Cal.com](http://Cal.com) bookings to Heffl contacts (coming soon)
***
## Meeting notes
* **Fathom**, connect Fathom AI to sync meeting notes, summaries, and action items into Heffl
***
## Forms
* **Forms**, connect your Forms account and set a webhook so form submissions flow into your workspace. See [Creating and sharing forms](https://docs.heffl.com/creating-and-sharing-forms).
***
## Disconnecting an integration
To disconnect, return to **Apps & integrations**, open the integration, and remove it. Disconnecting stops the data sync but does not delete data already in Heffl.
***
## What to do next
1. Connect your [email](https://heffl.com/) to send from your own address
2. Connect [WhatsApp or LinkedIn](https://heffl.com/) to use the Inbox
3. Connect [Stripe or Telr](https://heffl.com/) to accept online payments
# What is Heffl?
Source: https://docs.heffl.com/introduction
Welcome to Heffl - the all-in-one agency management platform
Whether you are a solo founder or managing a team, Heffl helps you track leads, send quotes and invoices, deliver work, and get paid, all in one place.
Heffl is an all-in-one agency management platform. It brings customer relationship management, sales, projects, field service, and more into one workspace, so you can run your operations without juggling separate tools.
## What can you do with Heffl?
**Track leads and deals** \
Capture leads from forms and other sources, track their status and activity, set follow-up reminders, and convert them into deals. Manage your sales pipeline visually, moving deals through stages without spreadsheets. See [Managing leads](https://docs.heffl.com/managing-leads-adding-editing-and-converting) and [Moving deals between stages](https://docs.heffl.com/moving-deals-between-stages).
**Send quotes and invoices** \
Create professional quotations from templates, auto-fill client details from your CRM, and send them by email or through the client portal. Convert accepted quotes into invoices in one click, and track their status. See [Creating and sending quotations](https://docs.heffl.com/creating-and-sending-quotations).
**Collect payments** \
Record payments, track outstanding balances, and let clients pay online through Stripe or Telr. Set up recurring invoices for clients you bill on a schedule. See [Payments: recording and collecting](https://docs.heffl.com/payments-recording-and-collecting).
**Deliver projects** \
Plan work across your team with projects, tasks, timesheets, and recurring projects, viewable as a board, table, or timeline. See [Introduction to project management in Heffl](https://docs.heffl.com/introduction-to-project-management-in-heffl).
**Work with clients directly** \
Give clients a portal to view their quotes, invoices, and jobs, and to pay online, without contacting your team. See [Setting up the client portal](https://docs.heffl.com/setting-up-the-client-portal).
## Getting started
New to Heffl? Follow these guides to set up your workspace:
Sign up at [app.heffl.com](https://app.heffl.com) and create your organization.
Add team members and assign roles with the right permissions.
Import contacts, configure deal pipelines, and define lifecycle stages.
Link your email, calendar, and payment gateway in Settings > Integrations.
Need help getting started? Check our [Getting Started guide](https://docs.heffl.com/getting-started/quick-start-guide-5-minute-setup) for a step-by-step walkthrough.
## How Heffl is organized
Heffl is built around connected areas that work together. The main ones are:
* **CRM**: leads, deals, companies, and contacts, everything in your sales pipeline
* **Sales and Finance**: quotations, invoices, proforma, payments, products, and recurring invoices
* **Projects**: tasks, timesheets, and recurring work
* **Field Service**: jobs, schedules, and service reports
* **Client Portal**: a secure space for your clients
* **Inbox**: WhatsApp, LinkedIn, and email conversations in one view
* **Wiki**: internal notes and documents
* **Apps**: Forms, Automations, Files, Reports, Templates, and integrations
These connect into a natural workflow: capture a lead, convert it to a deal and send a quote, turn the accepted quote into a project or field service job, then share updates and collect payment through the client portal, with automations handling the repetitive steps along the way.
***
## Who uses Heffl
Heffl is built for service businesses that manage clients, teams, and recurring work:
* **Small and medium businesses** that want one platform for CRM, invoicing, and operations
* **Field service companies** like cleaning, pest control, and maintenance firms that schedule jobs and send teams on site
* **Agencies** managing multiple clients, projects, and deadlines
* **Freelancers** who need a simple way to manage clients, quote, deliver, and get paid
***
## What's new
Heffl updates regularly. The What's new changelog tracks the latest features and improvements, worth checking after each release.
***
## Ready to get started?
Setting up Heffl takes only a few minutes. See [How to sign up and log in](https://docs.heffl.com/getting-started/how-to-sign-up-and-log-in) to create your account, then the [Quick start guide](https://docs.heffl.com/getting-started/quick-start-guide-5-minute-setup) to find your way around.
***
## What to do next
1. [Sign up and log in](https://heffl.mintlify.app/getting-started/how-to-sign-up-and-log-in#how-to-sign-up-and-log-in) to create your workspace
2. Follow the [quick start guide](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/418bb23c-50e2-46e8-8604-402b02d6027f) to get oriented
3. [Invite your team members](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/e381be99-1a4e-40dc-a4b1-2149feb2778f) and start working
**Work with clients directly** \
Give clients a portal to view their quotes, invoices, and jobs, and to pay online, without contacting your team. See [Setting up the client portal](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/a1a490df-7936-4c16-8a86-ec063e23e64e).
Sign up at [app.heffl.com](https://app.heffl.com) and create your organization.
Add team members and assign roles with the right permissions.
Import contacts, configure deal pipelines, and define lifecycle stages.
Link your email, calendar, and payment gateway in Settings > Integrations.
Heffl updates regularly. The What's new changelog tracks the latest features and improvements, worth checking after each release.
Setting up Heffl takes only a few minutes. See [How to sign up and log in](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/19d040b4-4bc0-496a-878c-2efeef17fdfe) to create your account, then the [Quick start guide](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/418bb23c-50e2-46e8-8604-402b02d6027f) to find your way around.
1. [Sign up and log in](https://heffl.mintlify.app/getting-started/how-to-sign-up-and-log-in#how-to-sign-up-and-log-in) to create your workspace
2. Follow the [quick start guide](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/418bb23c-50e2-46e8-8604-402b02d6027f) to get oriented
3. [Invite your team members](https://app.mintlify.com/heffl/heffl/editor/Thejas/~/e381be99-1a4e-40dc-a4b1-2149feb2778f) and start working
# Introduction to automations
Source: https://docs.heffl.com/introduction-to-automations
Automations let Heffl do routine work for you. When something happens (a trigger), Heffl carries out the steps you define (actions), such as sending an email, creating a task, or messaging on WhatsApp. This means follow-ups, reminders, and handoffs happen automatically instead of relying on someone to remember. You will find **Automations** in the sidebar.
***
## How an automation works
Every automation has two parts:
* **A trigger**, the event that starts it (for example, "Lead Created" or "Deal Stage Changed")
* **One or more steps (actions)**, what Heffl does in response (for example, "Send email," "Create Task," or "Send message")
For example, when a new lead is created, an automation can instantly send a WhatsApp message and create a follow-up call task, so no lead goes cold.
***
## The Automations area
The Automations area has three tabs:
**Automations** Your list of automations, each with an on/off toggle and its last run time. Toggle one off to pause it without deleting it.
**Templates** Pre-built automations you can use as a starting point (see below).
**Runs** A log of every time an automation has executed. Each entry shows the Run ID, the automation name, its status (such as Completed), any failed step, the error if one occurred, and the run date. Use this to confirm automations are firing and to troubleshoot any that fail.
***
## Templates
Rather than build from nothing, you can start from a template. Templates are grouped by record type, Leads, Deals, Quotations, Invoices, and Payments, and each shows its trigger and steps. Examples include:
* **New Lead: Instant WhatsApp + Follow-up Task**, messages a new lead and creates a call task
* **Quotation Accepted: Welcome Email + Kickoff Task**, welcomes the client and sets up delivery
* **Invoice Sent: Payment Reminder Email**, schedules a reminder when an invoice is sent
* **Payment Received: Thank-you Email + Retention Task**, thanks the client and schedules follow-up
* **Deal Won: Create Project + Internal Handoff**, turns a won deal into a project and notifies the team
Each template has a **Use this template** button that creates an automation pre-filled with its trigger and steps, which you can then adjust.
***
## What triggers and actions are available
Triggers are tied to events across your records, such as a lead being created, a deal changing stage, a quotation's status changing, an invoice being sent, or a payment being received.
Actions include sending an email, sending a message (such as WhatsApp), creating a task, creating a project, sending a notification, and adding a delay between steps so actions happen later rather than all at once.
***
## Why automations help
* Follow-ups and reminders happen on time, every time
* New leads get an instant response
* Won deals flow into projects without manual handoff
* Your team spends less time on repetitive admin
* The Runs log gives you a record that it all happened
***
## What to do next
1. [Set up your first automation](https://docs.heffl.com/setting-up-your-first-automation), from a template or from scratch
2. Browse the templates to see what is possible
3. Check the Runs tab to confirm your automations are firing
Here's the second page:
***
# Introduction to project management in Heffl
Source: https://docs.heffl.com/introduction-to-project-management-in-heffl
Projects in Heffl help you plan, track, and deliver work for your clients. A project groups together the tasks, timesheets, files, and people needed to complete a piece of work, and moves through stages until it is done. This page introduces how projects work. You will find **Projects** in the sidebar.
***
## What a project is
A project represents a body of work you deliver, such as a monthly AC maintenance, a website build, or a VAT registration. Each project has a client, a workflow (pipeline), a current stage, dates, an assignee, and a project lead. Inside it you track tasks, log time, and store files.
Projects often begin life as a won deal. When a deal closes, you can convert it into a project so the work carries forward. You can also create a project directly. See [Creating and managing projects](https://docs.heffl.com/creating-and-managing-projects).
***
## Pipelines and workflows
Like deals, projects are organized into **pipelines** (also called workflows), one per type of work. Your workspace has pipelines such as:
* Website
* Registration - VAT/CT
* Google ads
* Bookkeeping
* Doctor onboarding
* Laundry
* Flight ticket
* Construction
* Agricultural land sales
* Launch Pad
Each pipeline has its own stages suited to that work. For example, Bookkeeping runs through Enquired, In progress, Completed, and Follow up, while Construction runs through Planning, Permits, Foundation, Construction, Finishing, Inspection, and more. You pick the pipeline when creating a project.
***
## Ways to view projects
The Projects area offers several views, switchable from the tabs at the top:
**Kanban** A board where projects are cards grouped by status (Open, Closed). Drag cards to move them. Each card shows the project name, ID, dates, client, billing type, and progress.
**Table** A list with columns for No, Title, Project Lead, Board (pipeline), Phase (stage), Tags, Start Date, End Date, and Assignee. Best for scanning and bulk work.
**Gantt** A timeline showing each project's start date, duration, and progress across a calendar, useful for seeing scheduling at a glance. Switch the scale between Days, Weeks, Months, and Quarters.
**Recurring** Projects that regenerate on a schedule (see below).
**Timesheets** Logged time across all projects (see below).
***
## What lives inside a project
Open a project and you will find everything related to that work in one place:
* **Tasks**, the individual to-dos that make up the project
* **Timesheets**, logged hours against the project and its tasks
* **Files**, documents and project briefs attached to the project
* **Stages**, showing progress through the pipeline
* **Details**, including client, lead, assignee, dates, budgeted hours, and billing type (such as Flat Rate)
Projects can be created from a template that pre-fills tasks, or as a blank project you build up yourself.
***
## Recurring projects
For work that repeats, such as a monthly maintenance or a quarterly audit, you set up a **recurring project**. It regenerates a new project on a schedule (Every week, Every month, Every 2 weeks, and so on). Recurring profiles have their own list with a status, frequency, client, and start and end dates. See [Creating and managing projects](https://docs.heffl.com/creating-and-managing-projects).
***
## Timesheets
Timesheets track the hours your team spends on projects and tasks. Each entry records the user, project, task, client, date, hours, whether it is billable, and an approval status (Pending or Approved). The Timesheets view totals your billable, non-billable, and total time, and flags entries to approve. See [Logging timesheets and tracking hours](https://docs.heffl.com/logging-timesheets-and-tracking-hours).
***
## A typical project flow
1. Win a deal, then convert it to a project (or create one directly)
2. Choose the pipeline and a template or blank start
3. Break the work into tasks and assign them
4. Log time against tasks as work happens
5. Move the project through its stages
6. Invoice the client, linking the invoice to the project
7. Close the project when the work is delivered
***
## What to do next
1. [Create and manage a project](https://docs.heffl.com/creating-and-managing-projects)
2. [Break a project into tasks](https://docs.heffl.com/breaking-projects-into-tasks)
3. [Log timesheets](https://docs.heffl.com/logging-timesheets-and-tracking-hours) against your projects
# Invoices: creating, sending, and statuses
Source: https://docs.heffl.com/invoices-creating-sending-and-statuses
Invoices are the bills you send clients to collect payment. They work much like quotations, with the same template, line item, and sending tools, but an invoice is a request for payment rather than an offer. This guide covers what is specific to invoices. You will find **Invoices** in the sidebar under Finance.
***
## Creating an invoice
1. Go to **Invoices** in the sidebar
2. Click **+ Invoice** (or press **C**)
3. Choose a template and fill in the details
4. Add line items
5. Save
***
### Filling in the invoice
The invoice form mirrors the quotation form, with a few invoice-specific fields:
* **Template** and **Currency**
* **Date** and **Due date**, when payment is expected
* **Tags** and **Sales person**
* **Client** and **Contact**
* **Project** and **Job**, to link the invoice to work being delivered
* **Subject**
Add line items exactly as you do on a quote, using **Line item**, **Heading**, and **Bundle**, with Qty, Rate, Discount, and Tax. The **Subtotal**, **Discount**, **Tax**, and **Total** calculate automatically. See [Creating and sending quotations](https://docs.heffl.com/creating-and-sending-quotations) for the full line-item details, which are identical here.
Two toggles are specific to invoices:
* **I have received the payment**, to mark the invoice paid immediately if the client has already paid
* **Payment schedule**, to split the invoice into scheduled installments
***
### Form and content views
As with quotes, switch between **Form** (the structured data) and **Content** (the document layout) at the top right.
The Content editor uses merge variables such as `{{Invoice.Number}}`, `{{Invoice.DueDate}}`, `{{Client.Name}}`, `{{Contact.Email}}`, and `{{Invoice.LineItems}}`. These fill in automatically with the invoice's real data when the document is generated, so your template stays reusable.
***
### Invoice statuses
Each invoice carries a status you can see in the list and filter by:
* **Draft**, created but not yet sent
* **Sent**, delivered to the client and awaiting payment
* **Paid**, payment received in full
* **Overdue**, past the due date without full payment
The list also shows useful columns: number, subject, date, client, **Amount**, **Amount Excl VAT**, and **Output VAT**, so you can see tax breakdowns at a glance. Your total count appears at the bottom (for example, "212 invoices").
To see a grand total, click **Calculate** next to Total in the toolbar.
***
### Sending an invoice
Send an invoice the same way as a quote, from the buttons at the top of the invoice:
* **Send via email** delivers it to the client
* **Share a link** gives the client a link to view and pay online
* **Print** opens the print dialog, where you can print or save as PDF
* **Export PDF** downloads a PDF copy
Sending an invoice updates its status to Sent. If the client pays online through a shared link or the portal, the payment can be recorded against it. See [Setting up the client portal](https://docs.heffl.com/setting-up-the-client-portal).
***
### Recording payment
When a client pays, record it against the invoice so its status and balance update. An invoice shows its **Paid** amount and **Balance Due** so you always know what is outstanding. See [Payments: recording and collecting](https://docs.heffl.com/payments-recording-and-collecting).
***
### Exporting invoices
To export your invoice list, use **Export PDF** in the top right of the Invoices page. For a single invoice, use Export PDF or Print from within the invoice.
***
### What to do next
1. [Record and collect payments](https://docs.heffl.com/payments-recording-and-collecting) against your invoices
2. Set up [recurring invoices](https://docs.heffl.com/recurring-invoices) for repeat billing
3. Review [proforma invoices](https://docs.heffl.com/proforma-invoices) for advance billing
# Create a new client
Source: https://docs.heffl.com/legacy-api-reference/clients/create-a-new-client
/openapi.json post /clients
Creates a new client/company in your CRM. The client will be assigned to the user associated with your API key.
# Delete a client
Source: https://docs.heffl.com/legacy-api-reference/clients/delete-a-client
/openapi.json delete /clients/{id}
Permanently deletes a client. Will fail if the client has associated deals, invoices, or quotations.
# Get a client
Source: https://docs.heffl.com/legacy-api-reference/clients/get-a-client
/openapi.json get /clients/{id}
Returns a single client by its public ID.
# List clients
Source: https://docs.heffl.com/legacy-api-reference/clients/list-clients
/openapi.json get /clients
Returns a paginated list of clients. Supports search and type filtering.
# Update a client
Source: https://docs.heffl.com/legacy-api-reference/clients/update-a-client
/openapi.json patch /clients/{id}
Updates an existing client/company in your CRM. Only provided fields will be updated.
# Create a new deal
Source: https://docs.heffl.com/legacy-api-reference/deals/create-a-new-deal
/openapi.json post /deals
Creates a new deal in your CRM pipeline.
# Delete a deal
Source: https://docs.heffl.com/legacy-api-reference/deals/delete-a-deal
/openapi.json delete /deals/{id}
Permanently deletes a deal. Will fail if the deal has associated quotations, projects, or documents.
# Get a deal
Source: https://docs.heffl.com/legacy-api-reference/deals/get-a-deal
/openapi.json get /deals/{id}
Returns a single deal by its public ID.
# List deals
Source: https://docs.heffl.com/legacy-api-reference/deals/list-deals
/openapi.json get /deals
Returns a paginated list of deals. Supports search and filtering.
# Update a deal
Source: https://docs.heffl.com/legacy-api-reference/deals/update-a-deal
/openapi.json patch /deals/{id}
Updates an existing deal. Only provided fields will be updated.
# Create a new invoice
Source: https://docs.heffl.com/legacy-api-reference/invoices/create-a-new-invoice
/openapi.json post /invoices
Creates a new invoice with line items. Returns the invoice with calculated totals.
# Create a new lead
Source: https://docs.heffl.com/legacy-api-reference/leads/create-a-new-lead
/openapi.json post /leads
Creates a new lead in your CRM. The lead will be assigned to the user associated with your API key.
# Delete a lead
Source: https://docs.heffl.com/legacy-api-reference/leads/delete-a-lead
/openapi.json delete /leads/{id}
Permanently deletes a lead. This action cannot be undone.
# Get a lead
Source: https://docs.heffl.com/legacy-api-reference/leads/get-a-lead
/openapi.json get /leads/{id}
Returns a single lead by its public ID.
# List leads
Source: https://docs.heffl.com/legacy-api-reference/leads/list-leads
/openapi.json get /leads
Returns a paginated list of leads. Supports search and filtering.
# Update a lead
Source: https://docs.heffl.com/legacy-api-reference/leads/update-a-lead
/openapi.json patch /leads/{id}
Updates an existing lead in your CRM. Only provided fields will be updated.
# Get a pipeline
Source: https://docs.heffl.com/legacy-api-reference/reference-data/get-a-pipeline
/openapi.json get /pipelines/{id}
Returns a single deal pipeline with its stages.
# Get a product
Source: https://docs.heffl.com/legacy-api-reference/reference-data/get-a-product
/openapi.json get /products/{id}
Returns a single product by public ID.
# List deal pipelines
Source: https://docs.heffl.com/legacy-api-reference/reference-data/list-deal-pipelines
/openapi.json get /pipelines
Returns all deal pipelines with their stages.
# List lead sources
Source: https://docs.heffl.com/legacy-api-reference/reference-data/list-lead-sources
/openapi.json get /leads/sources
Returns all CRM sources (lead sources).
# List lead stages
Source: https://docs.heffl.com/legacy-api-reference/reference-data/list-lead-stages
/openapi.json get /leads/stages
Returns all lead stages ordered by position.
# List products
Source: https://docs.heffl.com/legacy-api-reference/reference-data/list-products
/openapi.json get /products
Returns a paginated list of products.
# List tags
Source: https://docs.heffl.com/legacy-api-reference/reference-data/list-tags
/openapi.json get /tags
Returns all tags for your team, optionally filtered by type.
# Create a new task
Source: https://docs.heffl.com/legacy-api-reference/tasks/create-a-new-task
/openapi.json post /tasks
Creates a new task. The task will be assigned to the user associated with your API key.
# Delete a task
Source: https://docs.heffl.com/legacy-api-reference/tasks/delete-a-task
/openapi.json delete /tasks/{id}
Permanently deletes a task.
# Get a task
Source: https://docs.heffl.com/legacy-api-reference/tasks/get-a-task
/openapi.json get /tasks/{id}
Returns a single task by its public ID.
# List tasks
Source: https://docs.heffl.com/legacy-api-reference/tasks/list-tasks
/openapi.json get /tasks
Returns a paginated list of tasks. Supports search and filtering.
# Update a task
Source: https://docs.heffl.com/legacy-api-reference/tasks/update-a-task
/openapi.json patch /tasks/{id}
Updates an existing task. Only provided fields will be updated.
# List users
Source: https://docs.heffl.com/legacy-api-reference/users/list-users
/openapi.json get /users
Returns a paginated list of users who belong to the API key's team.
# Get webhook subscription
Source: https://docs.heffl.com/legacy-api-reference/webhooks/get-webhook-subscription
/openapi.json get /webhooks/{id}
Returns a single webhook endpoint.
# List webhook subscriptions
Source: https://docs.heffl.com/legacy-api-reference/webhooks/list-webhook-subscriptions
/openapi.json get /webhooks
Returns webhook endpoints for your team.
# Subscribe to webhook events
Source: https://docs.heffl.com/legacy-api-reference/webhooks/subscribe-to-webhook-events
/openapi.json post /webhooks
Creates a webhook endpoint that receives HTTP POST notifications when specified events occur.
# Unsubscribe from webhook events
Source: https://docs.heffl.com/legacy-api-reference/webhooks/unsubscribe-from-webhook-events
/openapi.json delete /webhooks/{id}
Deletes a webhook endpoint and stops receiving events.
# Linking contacts to a company
Source: https://docs.heffl.com/linking-contacts-to-a-company
Contacts are the individual people you deal with, and companies are the businesses they belong to. Linking them keeps each person connected to the right organization, so opening a company shows everyone you work with there. This guide covers how to link contacts to a company.
***
## How contacts and companies relate
A company can have many contacts, but each contact belongs to one company. For example, the company "Epic Games" might have several contacts such as a primary buyer and an accounts person.
One contact is marked as the **Primary Contact**, the main person you deal with at that company. The primary contact shows in the Contacts column of the company list.
***
## Linking a contact when adding a company
When you create a company, you can set its primary contact straight away:
1. Click **Add Company**
2. In the **Primary Contact** field, select an existing contact or create a new one
3. Finish adding the company
The contact is now linked, and you can add more contacts later from the company record.
***
## Linking a contact from the company record
To add or change contacts on an existing company:
1. Open the company by clicking its row in the Companies list
2. Find the **Contacts** section
3. Add an existing contact, or create a new one to link it
4. Set or change which contact is the **Primary Contact** if needed
All linked contacts appear together on the company record, so you can see everyone at that business in one place.
***
## Linking from the contact side
You can also set the link when working with a contact:
1. Go to **Contacts** in the sidebar
2. Open or create a contact
3. Set the **Company** field to the business they belong to
This creates the same link, just approached from the contact rather than the company. Either way, the two records become connected.
***
## Changing the primary contact
If the main person you deal with changes, update the primary contact:
1. Open the company record
2. In the Contacts section, set a different contact as primary
The new primary contact then shows in the company list and on documents where the primary contact appears.
***
## Why linking matters
Linking contacts to companies keeps your data connected and useful:
* Opening a company shows all its people at once
* Quotes and invoices can pull the right contact automatically
* You avoid duplicate or orphaned contact records
* Your team always knows who to reach at each business
***
## What to do next
1. [Add and manage contacts](https://docs.heffl.com/adding-and-managing-contacts) in detail
2. Create [deals](https://docs.heffl.com/adding-and-managing-deals) linked to a company and its contacts
3. Send a [quotation](https://docs.heffl.com/creating-and-sending-quotations) to a company's primary contact
# Linking contacts to companies and deals
Source: https://docs.heffl.com/linking-contacts-to-companies-and-deals
Contacts become most useful when connected to the companies they work for and the deals they are part of. Linking keeps your records joined up, so you always know who belongs where. This guide covers both links from the contact's side.
***
## Linking a contact to a company
A contact belongs to one company. To set or change that link:
1. Open the contact by clicking its row in the Contacts list
2. In the **Details** panel on the right, find the **Company** field
3. Click it and search for the company
4. Select the company to link it
The contact is now tied to that company, and it appears among the company's contacts. To unlink, clear the Company field.
You can also set this when first adding the contact, using the Company field in the Add Contact form.
***
## Linking a contact to a deal
Deals track sales opportunities, and each deal can have one or more contacts associated with it, the people involved in that opportunity.
1. Open the deal by clicking it in the Deals list
2. Find the **Contacts** section on the right of the deal record
3. Click to add a contact
4. Select the contact to associate it with the deal
If a deal has no contacts yet, Heffl prompts you to add one so the opportunity is tied to a real person.
A deal also has a **Client** field, which is the company or contact the deal belongs to. The Client is the main account, while the Contacts section lists the specific people involved.
***
## How these links work together
When a lead converts into a deal, its contact information carries forward, so the deal is connected to the right people from the start. From there, the links flow naturally:
* The **contact** is linked to a **company**
* The **deal** is linked to a **client** (the company or contact)
* The **deal** lists the **contacts** involved
This means opening any one record shows you the others. Open a company to see its contacts, open a contact to see its company, and open a deal to see both its client and its contacts.
***
## Why linking matters
Keeping these links current gives you:
* A full picture of who you are dealing with on each deal
* The right contact pulled automatically onto quotes and documents
* Clean reporting, since deals trace back to real people and companies
* No orphaned records floating without context
***
## What to do next
1. [Add and manage deals](https://docs.heffl.com/adding-and-managing-deals) to track your opportunities
2. Work with the deals pipeline to move deals through stages
3. Send a [quotation](https://docs.heffl.com/creating-and-sending-quotations) to a linked contact
# Logging activities, notes, and follow-ups,
Source: https://docs.heffl.com/logging-activities-notes-and-follow-ups
Every lead, contact, and deal in Heffl has an Activity area where you record what happens over time: calls, meetings, notes, emails, and tasks. Keeping this up to date gives you a complete history of every interaction. This page applies to leads, contacts, and deals, since the Activity area works the same way in all three.
***
## Where to find it
Open any lead, contact, or deal and you will land on the **Activity** tab. It has two parts:
* **Focus** at the top, for setting a quick task or next action
* **History** below, a timeline of everything logged, newest grouped by date
A row of buttons (Task, Meeting, Log, Note, Email) lets you add each type of entry.
***
## Logging activity
Use the buttons to record different kinds of interaction:
**Log** Record a call or general interaction that has already happened. Use this to note the outcome of a phone call or conversation.
**Meeting** Schedule or record a meeting. Useful for tracking site visits, demos, and calls with a set time.
**Email** Log an email related to the record, keeping correspondence attached to the right lead, contact, or deal.
**Note** Add a written note (covered in detail below).
Each entry is timestamped and added to the History timeline, so you and your team can see the full sequence of events.
***
## Adding and viewing notes
Notes capture detail: what was discussed, what was agreed, or anything worth remembering.
### **To add a note**
1. Click **Note** in the button row
2. Type your note
3. Save
You can also write a quick comment in the History section using the comment box, and attach a file with the attachment icon.
**To view notes** All notes appear in the History timeline alongside other activity, grouped by date (for example, Last Week, Last Month). Pin important notes to keep them at the top.
***
## Setting follow-ups and next activity dates
Follow-ups make sure nothing goes cold. In the Focus area at the top of the Activity tab:
1. Type a task title in the **Task title** field
2. Choose when it is due using the quick options: **In 1h**, **In 3h**, **Tomorrow**, **Next week**, or **Other** for a specific date
3. The task is created and tied to this record
Setting a due date also feeds the **Next Activity Date**, which you can filter by in the lead list. This is the best way to plan your day and surface the records that need attention soon. See [Filtering and sorting leads](https://docs.heffl.com/filtering-and-sorting-leads).
***
## The activity timeline
The History timeline is a running record of everything that has happened, including:
* Activities you log (calls, meetings, emails)
* Notes and comments
* System events, such as "Lead converted to deal" or "created Deal"
* Who did each action and when
Because it captures both your entries and automatic events, the timeline is a reliable audit trail for any record.
***
## Why this matters
Logging activity consistently means:
* Anyone on your team can pick up a lead or deal and see its full history
* Follow-ups are scheduled, not forgotten
* Reports reflect real activity
* Nothing depends on one person's memory
***
## What to do next
1. Filter leads by next activity date to plan follow-ups
2. [Add notes and tags](https://docs.heffl.com/adding-notes-and-tags-to-a-lead) to organize records further
3. Convert active records into deals or projects
# Logging timesheets and tracking hours
Source: https://docs.heffl.com/logging-timesheets-and-tracking-hours
Timesheets record the hours your team spends on projects and tasks. Tracking time shows you where effort goes, what is billable, and how actual hours compare to your estimates. This guide covers logging time and managing timesheets. You will find **Timesheets** as a tab in the Projects area.
***
## What a timesheet entry captures
Each timesheet entry records one block of work, with:
* **User**, who did the work
* **Project** and **Task** the time was spent on
* **Client**
* **Date**
* **Hours**
* **Billable** or non-billable
* **Status**, either Pending or Approved
* **Notes**
This ties every hour to a specific person, project, and task, so your time data is accurate and reportable.
***
## Adding a timesheet entry
1. Go to the **Timesheets** tab in Projects
2. Click **+ Timesheet** (or press **C**)
3. Select the **User** who did the work
4. Choose the **Client**, **Project**, and **Task**
5. Choose how to enter time with **Type**:
* **Date** records a start and end time on a given day
* **Duration** records a length of time directly
6. Set the **Start Time** and **End Time** (or the duration)
7. Toggle **Billable** on if the time can be charged to the client
8. Add **Notes** if needed
9. Click **Add timesheet**
***
## Billable versus non-billable
Each entry is marked billable or non-billable:
* **Billable** time can be charged to the client and feeds into invoicing
* **Non-billable** time is internal work you track but do not charge for
Marking time correctly keeps your billable totals accurate and makes it clear what can be invoiced.
***
## The timesheets view
The Timesheets tab lists all entries with columns for Number, User, Project, Task, Client, Date, Hours, Status, Billable, Notes, and Actions.
At the top, summary figures show:
* **To approve**, entries awaiting approval
* **Total billable** hours
* **Total non-billable** hours
* **Total time** logged
Use **Dates** and **Users** filters to narrow the view, and **Sort** to order entries.
***
## Approving timesheets
Timesheet entries move through an approval flow:
* **Pending**, logged but not yet approved
* **Approved**, confirmed by a reviewer
From the Actions column, you can **Edit** an entry, **Approve** it, or **Reset** an approved entry back to pending. The "To approve" figure at the top shows how many entries are waiting, so reviewers know what needs attention.
***
## How timesheets connect to projects and billing
Timesheets tie back to your projects and billing in two ways:
* Logged hours count against a project's **budgeted hours**, so you can see whether work is on track. See [Creating and managing projects](https://docs.heffl.com/creating-and-managing-projects).
* Billable hours can feed into **invoices**, so client time is charged accurately. See [Invoices](https://docs.heffl.com/invoices-creating-sending-and-statuses).
***
## What to do next
1. Review logged hours against your project's [budgeted hours](https://docs.heffl.com/creating-and-managing-projects)
2. [Invoice](https://docs.heffl.com/invoices-creating-sending-and-statuses) billable time to clients
3. Use the [projects dashboard](https://docs.heffl.com/creating-and-managing-projects) to track time across projects
# Managing leads: adding, editing, and converting
Source: https://docs.heffl.com/managing-leads-adding-editing-and-converting
Leads are your potential customers. This guide covers adding a lead, editing its details, and converting it once they are ready to do business.
***
## Adding a lead
### **Option 1: Add a single lead**
1. Go to **Leads** in the sidebar
2. Click **+ Lead** in the top right (or press **C**)
3. Enter the lead's name (a person or business name)
4. Fill in any custom fields, such as Channel and Source
5. Click **Add lead** (or press **Ctrl + Enter**)
The lead is created and added to your pipeline at the first stage.
### **Option 2: Import many leads at once**
If you have leads in a spreadsheet, import them in bulk:
1. Click **Import** in the top right
2. **Upload** your file by dropping it in or clicking **Browse files**
3. **Select header** to tell Heffl which row contains your column titles
4. **Map columns** to match your file's columns to Heffl fields (Name, Mobile, Email, Title, Value, Source, and others). Only Name is required.
5. Confirm to finish the import
You can download a template from the import screen to format your file correctly before uploading.
***
## Viewing and organizing leads
The Leads page has two views, switchable from the tabs at the top:
* **All leads** shows your leads in a list, one row each
* **Kanban** shows leads as cards grouped by stage
To find or narrow down leads, use the controls above the list:
* **Search** to find a lead by name
* **Sort** to order by created date or other fields
* **Filters** to narrow by specific criteria
* **Stage** and **Status** to show only leads at a certain point
* **Next Activity Date** to focus on what needs attention soon
***
## Editing a lead
To edit a lead's core details, click the lead row to open it, then update any field.
You can also edit some fields directly from the list without opening the lead:
* **Stage** — click the stage cell to move the lead forward (New, Contacted, Followed Up, Converted)
* **Add Note** — click to attach a note
* **Tags** — click the **+** to add a tag such as VIP
* **Mobile, Email, Website** — click the cell to add or change contact details
Changes save automatically.
***
## Adding notes, tags, and activities
Keep each lead's history in one place:
* **Notes** record what was discussed or agreed
* **Tags** group leads for quick filtering (for example, VIP or Technical service)
* **Activities and follow-ups** track calls, meetings, and the next action date so nothing slips
Setting a next activity date is the best way to make sure no lead goes cold.
***
## Converting a lead to a Deal
When a lead is ready to do business, convert it. Converting turns the lead into a detailed Deal, while keeping all its history.
1. Open the lead
2. Click **Convert to Deal**
3. Enter the details
Once converted, the lead's stage shows as **Converted** in status and its information carries forward to the deal, so you do not have to re-enter anything.
***
## What to do next
After managing your leads:
1. Move active leads into [Deals](https://docs.heffl.com/adding-and-managing-deals) to track the sale
2. Send a [quotation](https://docs.heffl.com/creating-and-sending-quotations) to a converted lead
3. Set up custom fields to capture lead details specific to your business
# Managing products and services (catalog)
Source: https://docs.heffl.com/managing-products-and-services-catalog
Your product catalog is the list of products and services you sell. Once set up, you select items from it when building quotes, invoices, and deals, and the price, tax, and description fill in automatically. This guide covers managing the catalog. You will find **Products** in the sidebar under Finance.
***
## Why use a catalog
Maintaining a catalog means you enter each product's details once and reuse them everywhere. This keeps pricing consistent across all your documents and saves you from retyping the same items. Changes to the catalog do not affect documents you have already created.
***
## Adding a product or service
1. Go to **Products** in the sidebar
2. Click **Add Product**
3. Fill in the details:
* **Name**, the product or service name (must be unique)
* **Type**, either Product or Service
* **Price**, the selling price
* **Buy Price**, the cost price, used for margin tracking
* **SKU**, an optional stock keeping unit
* **Description**
* **Default Tax Rate**, applied automatically when the item is used
* **Image**, an optional photo or icon
* **Active**, whether the item appears in selection lists
4. Save
***
## Using products in documents
When adding line items to a quotation, invoice, or deal:
1. Start typing the product name in the line item field
2. Select it from the matching results
3. The price, tax, and description fill in automatically from the catalog
You can override any of these values for a specific document without changing the catalog itself. This lets you adjust a one-off price while keeping your standard pricing intact.
***
## Active and inactive products
To retire a product without deleting it, mark it inactive:
1. Open the product
2. Toggle the **Active** switch off
The product stops appearing in dropdown lists for new documents, but remains on any existing documents that already use it. Use this for items you no longer sell but want to keep for historical records.
***
## Client portal visibility
You can control which products your clients see in the client portal:
1. Edit the product
2. Enable **Client Portal Visibility**
3. Optionally add a **Client Portal Description** if you want clients to see different wording than your internal description
This lets you show a curated, client-friendly catalog in the portal. See [Setting up the client portal](https://docs.heffl.com/setting-up-the-client-portal).
***
## Bulk operations
For managing many products at once:
* **Bulk create** imports multiple products in one go
* **Bulk delete** lets you select and remove up to 300 products at a time
***
## Finding products
Use the controls on the Products page to locate items:
* **Search** finds products by name
* **Active/Inactive** filter shows only active products or all of them
* **Creator** filters by who added the product
***
## What to do next
1. [Create a quotation](https://docs.heffl.com/creating-and-sending-quotations) using items from your catalog
2. [Convert an accepted quote to an invoice](https://docs.heffl.com/invoices-creating-sending-and-statuses)
3. Set [client portal visibility](https://docs.heffl.com/setting-up-the-client-portal) on the products your clients should see
# Moving deals between stages
Source: https://docs.heffl.com/moving-deals-between-stages
As a deal progresses, you move it from one stage to the next so your pipeline always shows where each opportunity stands. This guide covers the practical ways to move deals, individually and in bulk.
***
## Moving a single deal from the board
On the Deals board (the **All** view), deals sit in columns by status:
1. Find the deal card you want to move
2. Click and hold it
3. Drag it to the target column
4. Release to drop it there
The deal updates to its new status instantly, and the column counts and total value adjust to match.
***
## Moving a single deal from its detail view
For finer control over the specific stage within a pipeline:
1. Open the deal by clicking it
2. At the top, you will see the stage bar with all stages for that pipeline
3. Click the stage you want to move the deal to
The selected stage highlights, and the change is logged in the deal's activity history so your team can see when it moved and who moved it.
***
## Moving deals in the table view
Switch to the **Table** view if you prefer working from a list:
1. Open a deal's stage cell, or use the row's controls
2. Select the new stage
The table view is useful when you want to move several deals quickly without dragging cards around a board.
***
## What moving a deal records
Each time you move a deal, Heffl:
* Updates the deal's stage and status
* Logs the change in the activity timeline with the date and user
* Recalculates pipeline counts and total value
This audit trail means you can always trace how a deal progressed.
***
## Tips for keeping stages accurate
* Move deals as soon as something changes, not in a weekly catch-up, so the pipeline reflects reality
* Use the closing stages (Won or Lost) only when the deal is truly decided
* Record a lost reason when marking a deal Lost, so you can learn from it later
* Avoid skipping stages unless your process genuinely allows it, since stage data feeds your reports
***
## What to do next
1. Convert a won deal into a project
2. Send a [quotation](https://docs.heffl.com/creating-and-sending-quotations) from a deal
3. Review your pipeline totals to forecast revenue
# Numbering and document templates
Source: https://docs.heffl.com/numbering-and-document-templates
Two Organization settings control how your records are numbered and how your client-facing documents look: **Module numbers** and **Document templates**. Both are workspace-wide and usually require admin access. You will find them under **Settings**, in the **Organization** group.
***
### Module numbers
Every record in Heffl gets an automatic identifying number, and **Module numbers** is where you control how those numbers are formatted per module.
You have seen these numbers throughout Heffl, for example:
* Quotations as **QTTS-** numbers
* Proforma invoices as **PINV-** numbers
* Payments as **PAY-** numbers
* Jobs as **OF-** (one-off) and **AMC-** (contract) numbers
* Projects as **P-** numbers
On this screen you can typically set, for each module, the **prefix** (the letters before the number) and the **starting or next number** in the sequence. Heffl then assigns the next number automatically each time a record is created.
### Why it matters
Consistent numbering keeps your records organized and professional. Setting a sensible prefix per module means anyone can tell at a glance whether they are looking at a quotation, an invoice, or a job. If you are migrating from another system, you can set the starting number to continue your existing sequence rather than restarting from one.
Set your numbering early, before you create many records, so the format stays consistent across your whole history.
***
### Document templates
**Document templates** control the design and default content of the documents you send to clients, such as quotations, invoices, proforma invoices, and purchase orders. Managing them centrally here means every document your team sends looks consistent and on-brand.
A template typically controls:
* The **layout and branding** (your logo, colors, and company details)
* **Default text**, such as terms, notes, and payment instructions
* The **fields and columns** shown on the document
### How templates are used
When you create a quotation or invoice, you pick a template as the starting point, and the document inherits that template's design and defaults. You saw this when [creating a quotation](https://docs.heffl.com/creating-and-sending-quotations), where you choose a template before adding line items. Managing templates centrally means a change to a template applies to new documents built from it, so you update your branding or terms in one place rather than on every document.
### Creating and editing templates
From the Document templates screen you can create new templates and edit existing ones, setting up the layout and default content each should carry. Set up a template per document type you send, so your team always starts from the right design.
***
### How the two work together
Numbering and templates are the two halves of a polished client document:
* **Module numbers** give each document a clean, sequential identifier
* **Document templates** give it a consistent, branded appearance
Together they mean a quotation or invoice leaves your workspace looking professional and uniquely identified, without anyone formatting it by hand.
***
### What to do next
1. Set your [organization details](https://docs.heffl.com/workspace-and-organization-settings) so they appear correctly on documents
2. Review your templates before [sending quotations](https://docs.heffl.com/creating-and-sending-quotations) and [invoices](https://docs.heffl.com/invoices-creating-sending-and-statuses)
3. Confirm your numbering format early, before creating many records
# Payments: recording and collecting
Source: https://docs.heffl.com/payments-recording-and-collecting
Recording payments keeps your invoices up to date and shows you who has paid and who still owes. This guide covers recording a payment, applying it to invoices, and understanding excess amounts. You will find **Payments** in the sidebar under Finance.
***
## Recording a payment
Record a payment from the Payments page:
1. Go to **Payments** in the sidebar
2. Click **+ Payment** (or press **C**)
3. Select the **Client** who paid
4. Set the payment details:
* **Date** the payment was received
* **Payment method** (such as Bank Transfer or Credit card)
* **Deposit to account** (such as Undeposited Funds)
* **Currency** and **Amount**
* **Collected by**, the team member who took the payment
* **Ref No**, an optional reference such as a transaction ID
5. Apply the payment to the client's invoices (see below)
6. Click **Add payment** (or press **Ctrl + Enter**)
***
## Applying a payment to invoices
Once you select a client, their outstanding invoices appear in the form. You decide how the payment is applied:
* **Search invoices** to find a specific one
* Enter the **Payment** amount against each invoice, shown alongside its **Amount** and **Pending** balance
* Use **Bulk Apply** to spread the payment across multiple invoices automatically
* Click **Pay Full** to apply the full outstanding amount
As you apply the payment, the form shows a running summary:
* **Amount Received**, the total payment entered
* **Amount used for Payments**, how much has been applied to invoices
* **Amount in Excess**, what remains after applying it to invoices
***
## Understanding excess and unused amounts
If a client pays more than their invoices require, the leftover is the **Amount in Excess**. This appears in the Payments list as the **Unused Amount**, the portion of a payment not yet applied to any invoice.
An unused amount stays as a credit against that client, ready to apply to a future invoice. For example, a payment of AED 400 with nothing yet applied shows AED 400 as the unused amount until you assign it.
***
## The Payments list
The Payments page lists every payment, one per row, with columns:
* **Number** (such as PAY-5071)
* **Date**
* **Client** and **Customer Number**
* **Invoice Numbers** the payment is applied to
* **Mode** (Bank Transfer, Credit card, and so on)
* **Amount** and **Unused Amount**
* **Reference Number**
* **Deposited To** (such as Undeposited Funds)
* **Actions**
The total of all payments shows at the top (for example, "Total: AED 120,447.30"). Use **Filters** to narrow the list and the **search** icon to find a specific payment.
***
## Collecting payments online
Beyond recording payments manually, clients can pay you online:
* Through a **shared invoice link**
* Through the **client portal**, where they see outstanding invoices and a Pay Now option
Online payments can be recorded against the invoice automatically. See [Setting up the client portal](https://docs.heffl.com/setting-up-the-client-portal).
***
## How payments connect to invoices
When a payment is applied to an invoice, the invoice's **Paid** amount rises and its **Balance Due** falls. Once fully paid, the invoice status becomes **Paid**. This keeps your invoice list and outstanding balances accurate without manual updates. See [Invoices: creating, sending, and statuses](https://docs.heffl.com/invoices-creating-sending-and-statuses).
***
## What to do next
1. Review your [invoices](https://docs.heffl.com/invoices-creating-sending-and-statuses) to see updated balances
2. Apply any unused amounts to new invoices as they are raised
3. Set up [recurring invoices](https://docs.heffl.com/recurring-invoices) for clients who pay on a schedule
# Proforma invoices
Source: https://docs.heffl.com/proforma-invoices
A proforma invoice is a preliminary bill you send before the final invoice, often to confirm details or request advance payment. It looks like an invoice but is not yet a demand for payment. In Heffl, proforma invoices work just like regular invoices. You will find **Proforma** in the sidebar under Finance.
***
## What a proforma invoice is for
Use a proforma invoice when you need to give a client a formal document showing what they will be billed, before issuing the actual invoice. Common uses include:
* Requesting an advance or deposit
* Confirming price and scope before work begins
* Providing a document for the client's internal approval or budgeting
Once the work is confirmed or the advance is paid, you raise the final invoice. See [Invoices](https://docs.heffl.com/invoices-creating-sending-and-statuses).
***
## Creating a proforma invoice
1. Go to **Proforma** in the sidebar
2. Click **+ Proforma Invoice** (or press **C**)
3. Choose a template and currency
4. Set the **Date** and **Due date**
5. Select the **Client** and **Contact**
6. Add line items with Qty, Rate, Discount, and Tax
7. Save
The form is the same builder used for invoices and quotations, including Line item, Heading, and Bundle, with automatic Subtotal, Tax, and Total. See [Creating and sending quotations](https://docs.heffl.com/creating-and-sending-quotations) for the full line-item details.
***
## Proforma statuses
Each proforma invoice has a status shown in the list:
* **Draft**, created but not yet sent
* **Sent**, delivered to the client
The list shows columns including Number, Status, Date, Total Amount, Due Date, Due Days, Marked Sent On, Created At, Updated At, and Currency. Your total count appears at the bottom (for example, "12 proforma invoices").
***
## Customizing the list columns
You can choose which columns appear and their order, on this list and other record lists:
1. Click the **three-dot menu** in the top right
2. Select **View settings**
3. In the panel, use the controls beside each column to:
* **Edit** the column (pencil icon)
* **Pin** it so it stays visible while scrolling (pin icon)
* **Remove** it from the view (trash icon)
* **Reorder** columns by dragging the handle on the left
Available columns include Number, Status, Date, Total Amount, Due Date, Due Days, Marked Sent On, Created At, Updated At, Currency, Conversion rate, Subtotal, Total Tax, Total Discount, Link, and Notes.
***
## Exporting proforma invoices
To export your proforma list, click the **three-dot menu** and select **Export**. For a single proforma, use the print or export options within the document, the same as invoices.
***
## What to do next
1. Raise the final [invoice](https://docs.heffl.com/invoices-creating-sending-and-statuses) once the proforma is confirmed
2. [Record and collect payments](https://docs.heffl.com/payments-recording-and-collecting) such as advances
3. Set up [recurring invoices](https://docs.heffl.com/recurring-invoices) for repeat billing
# Recurring invoices
Source: https://docs.heffl.com/recurring-invoices
A recurring invoice automatically generates an invoice on a set schedule, so you do not recreate the same bill each cycle. It is ideal for clients on retainers, subscriptions, or maintenance contracts. You will find **Recurring Invoices** in the sidebar under Finance.
***
## How recurring invoices work
You set up a recurring invoice once, defining the client, line items, and a frequency. On each cycle, Heffl generates a draft invoice from that profile. You review the draft and send it yourself, so you stay in control of what goes out before the client receives it.
This saves you from rebuilding identical invoices while keeping a final check on each one.
***
## Setting up a recurring invoice
1. Go to **Recurring Invoices** in the sidebar
2. Click **+ Recurring Invoice** (or **+ Add Recurring Invoice**)
3. Fill in the setup:
* **Template** and **Profile name** (a label to identify this recurring profile)
* **Frequency**, how often it generates (see below)
* **Start date** and **End date** (leave the end date open for an ongoing profile)
* **Due days**, how many days after generation the invoice is due
* **Client** and **Contact**
* **Sales person** and an optional **Project** link
4. Add line items with Qty, Rate, Discount, and Tax, exactly as on a normal invoice
5. Save
The line-item builder is the same one used for invoices and quotations, with Line item, Heading, and Bundle, plus automatic Subtotal, Tax, and Total. See [Creating and sending quotations](https://docs.heffl.com/creating-and-sending-quotations) for the full details.
***
## Frequency options
The **Frequency** dropdown sets how often the invoice generates:
* Custom
* Daily
* Weekly
* Every 2 weeks
* Monthly
* Every 3 months
* (and longer intervals)
Pick the one that matches your billing cycle. For example, a monthly cleaning retainer would use Monthly.
***
## What happens each cycle
On each scheduled date, Heffl generates a draft invoice from the profile, using the saved client, line items, and amounts. Because it is a draft, you review it and send it yourself rather than it going out automatically. The generated invoice then behaves like any other invoice, with its own status and payment tracking. See [Invoices: creating, sending, and statuses](https://docs.heffl.com/invoices-creating-sending-and-statuses).
***
## The recurring invoices list
The list shows each recurring profile, one per row, with columns:
* **#**, the profile number
* **Name**, the profile name you set
* **Client**
* **Status** (for example, Active)
* **Frequency** (such as Every month)
* **Amount**
* **Sales Person**
An **Active** profile is currently generating invoices on its schedule. Use **Filters** to narrow the list and the **search** icon to find a profile.
***
## Managing a recurring invoice
Open a profile to edit its details, change its frequency, update line items, or adjust the start and end dates. To stop a profile generating new invoices, set an end date or change its status so it is no longer active. Existing invoices it has already generated are not affected.
***
## What to do next
1. Review generated drafts under [Invoices: creating, sending, and statuses](https://docs.heffl.com/invoices-creating-sending-and-statuses) before sending
2. [Payments: recording and collecting](https://docs.heffl.com/payments-recording-and-collecting) against them
3. Link a profile to a [Creating and managing projects](https://docs.heffl.com/creating-and-managing-projects) for retainer-based work
# Security and compliance
Source: https://docs.heffl.com/security-and-compliance
Heffl stores your business data, your contacts, deals, invoices, and client information, so security and compliance matter. This page explains where to find Heffl's official security and legal information. For the authoritative, up-to-date details, always refer to Heffl's official documents rather than this help article.
***
## Data security
Your workspace data is hosted by Heffl and accessed over secure (HTTPS) connections. Within your workspace, access is controlled by the roles and permissions you assign to team members, so people see only what their role allows. See [Inviting your team members](https://docs.heffl.com/getting-started/untitled-page-2) for how roles control access.
For specifics on Heffl's infrastructure, encryption, hosting, and security practices, contact Heffl directly, as these details are maintained by Heffl and may change over time.
***
## Your role in keeping data secure
Much of your workspace's day-to-day security is in your hands:
* Assign each member the **least-privilege role** they need, rather than admin for everyone
* Remove access promptly when someone leaves your team
* Use strong, unique passwords, and keep your API keys secret. See [Using the Heffl API](https://docs.heffl.com/using-the-heffl-api).
* Limit who can access sensitive areas like finance and client data
***
## GDPR and data protection
If you handle personal data of individuals in the EU or UK, data protection regulations such as GDPR may apply to you. Under these rules, individuals have rights over their data, including access, correction, and deletion.
Heffl gives you tools to act on these requests within your workspace, you can edit and delete contact and company records as needed. Note that deleting a record fails if it has linked deals, invoices, or quotations, so you may need to handle those first.
For Heffl's own role as a data processor and its compliance posture, refer to Heffl's official privacy and legal documentation.
***
## Data processing agreement and subprocessors
A **Data Processing Agreement (DPA)** and a list of **subprocessors** (the third-party services Heffl uses to deliver its product) are legal documents issued by Heffl. If your business requires a signed DPA or a current subprocessors list, request these directly from Heffl. Do not rely on this help article for their contents, as only Heffl can provide the accurate, current versions.
***
## Where to get official information
For anything security or compliance related that this page does not cover, contact Heffl through your usual support channel. See [Contacting support](https://docs.heffl.com/support-and-reference). For developer-level data access, see [Using the Heffl API](https://docs.heffl.com/using-the-heffl-api).
***
## What to do next
1. Review your team's [roles and permissions](https://docs.heffl.com/workspace-and-organization-settings)
2. Request a [DPA or subprocessors list](https://heffl.com/) from Heffl if your business needs one
3. Keep passwords and [API keys](https://docs.heffl.com/using-the-heffl-api) secure
# Setting up the client portal
Source: https://docs.heffl.com/setting-up-the-client-portal
The client portal is a secure space where your clients can log in to see their quotes, invoices, jobs, and projects, make payments, and submit requests, without contacting your team. Access is set per company and used by the contacts linked to it. This guide covers enabling the portal, what clients see, file access, and payments.
***
## How the client portal works
When you enable the portal for a client, the contacts linked to that company can log into a branded portal using their email. Because access is tied to the **parent company**, all contacts under that company share the same portal, and each needs a valid email on record to log in.
***
## Enabling the portal for a client
1. Open the company record from **Clients** or **Companies**
2. In the **Client Portal** section on the right, find **Client Portal Access**
3. Toggle it on
Once enabled, the record shows a **Client Portal Enabled** badge, and a portal link (a [portal.raveo.co](http://portal.raveo.co) address) is generated. Copy it with the copy icon to share with your client. For a contact whose access is controlled by its company, enable the portal from the parent company.
***
## How clients log in
Clients log in without a password, using a one-time code:
1. The client opens the portal link
2. They enter their email (the one on their contact record)
3. A 6-digit code is sent to that email
4. They enter it and click **Verify code**
Make sure each contact who needs access has a valid email. See [Adding and managing contacts](https://docs.heffl.com/adding-and-managing-contacts).
***
## What clients see
The portal home greets the client by name and shows:
* **Take Actions**, highlighting urgent items such as overdue invoices, with a **Pay Now** option
* **Pending Invoices**, with amounts, due dates, and status
* **Pending Quotes** to review
* **Active Jobs** in progress
* An **About Us** block with your company information
* A **New request** button to contact your team
The portal sidebar gives access to these sections:
* **Requests**, **Quotes**, **Invoices**, and **Tasks**
* **Projects** and **Jobs**
* **Files** and **Products/Services**
* **About Us** and **Contact**
***
## What clients can do
Through the portal, clients can:
* **View and pay invoices** online
* **View quotes** (quotes are view-only in the portal; acceptance is handled with you directly)
* **Track jobs and projects** in progress
* **View and download files** attached to their records
* **Submit a new request** to your team
This lets clients self-serve the information and payments they need, reducing back-and-forth.
***
## Managing file access
Clients do not browse a general file library. They see only the **files attached to their own jobs and invoices**. To control what a client can access, manage the files attached to their records, anything attached to their job or invoice becomes visible to them in the portal's Files section.
Portal files are **view and download only**; clients cannot upload files through the portal.
***
## Enabling online payments
For clients to pay invoices in the portal, connect a payment provider:
1. Connect **Stripe** or **Telr** under Apps & integrations. See [Integrations and connected apps](https://docs.heffl.com/integrations-and-connected-apps).
2. Once connected, a **Pay Now** option appears on the client's outstanding invoices in the portal
Payments made this way can be recorded against the invoice. See [Payments: recording and collecting](https://docs.heffl.com/payments-recording-and-collecting).
***
## Managing access
* **Enable or disable** the portal any time with the Client Portal Access toggle
* **Add a contact's email** so that person can log in
* **Reshare the link** by copying it from the company record
Disabling the toggle removes access for that company and its contacts without deleting any data.
***
## What to do next
1. [Add contacts with valid emails](https://docs.heffl.com/adding-and-managing-contacts) so clients can log in
2. [Send quotes and invoices](https://docs.heffl.com/creating-and-sending-quotations) for clients to view and pay
3. Connect [Stripe or Telr](https://docs.heffl.com/integrations-and-connected-apps) to enable online payments
# Creating an automation
Source: https://docs.heffl.com/setting-up-your-first-automation
This guide walks you through creating an automation, either from a ready-made template or from scratch. For how automations work overall, see [Introduction to automations](https://docs.heffl.com/introduction-to-automations).
***
## Option 1: Start from a template (recommended)
The fastest way to get going:
1. Go to **Automations** and open the **Templates** tab
2. Browse templates by category (Leads, Deals, Quotations, Invoices, Payments)
3. Click a template to preview its trigger and steps
4. Click **Use this template**
5. Adjust the trigger, steps, and content to fit your business
6. Turn the automation on
Templates are the easiest start because the trigger and steps are already wired together; you only fine-tune them.
***
## Option 2: Start from scratch
To build a custom automation:
1. Go to **Automations** and click **+ Automation** (or **Start from scratch**)
2. In the **Add Automation** dialog, enter a **Name** and an optional **Description**
3. Click **Add Automation**
4. Build the flow in the builder (below)
***
## Building the flow
The automation builder is a visual canvas:
1. **Set the trigger**, the event that starts the automation (such as "Deal Stage Changed" or "Lead Created"). This is the first card.
2. **Add a step**, click the **+** below the trigger to add an action (such as "Send email")
3. **Configure each step**, set the details, for example the email content for a Send email step, or the task details for a Create Task step
4. **Add more steps** as needed, chaining actions together, and insert a **Delay** between steps if you want an action to happen later
You can view the flow as a **Canvas** (visual) or **Linear** (list) using the toggle, and use **Auto Layout** to tidy the canvas.
***
## Turning it on
An automation only runs when it is switched on. Use the on/off toggle at the top of the builder, or on the automation in the list. Toggle it off any time to pause it without losing the setup.
***
## Managing an automation
From the builder you can:
* **Edit** the trigger, steps, and content
* **Duplicate** the automation to create a variation
* Open **Manage** for its settings
* View **Runs** to see each time it has executed
***
## Testing and troubleshooting
After turning an automation on, check the **Runs** tab to confirm it fires as expected. Each run shows its status (such as Completed), and if a run fails, it shows the failed step and the error, so you can find and fix the problem.
Start simple: a single trigger with one or two actions. Once it runs reliably, add more steps.
***
## What to do next
1. Browse [templates](https://docs.heffl.com/introduction-to-automations) for ideas to adapt
2. Check the Runs log to confirm your automation works
3. Connect channels like [WhatsApp or email](https://docs.heffl.com/integrations-and-connected-apps) so message actions can send
# Support and reference
Source: https://docs.heffl.com/support-and-reference
This page brings together the ways to get help with Heffl, keep up with changes, solve common problems, and understand the terms used across the product.
***
## Getting support
If you need help, you can reach Heffl in two ways:
* **Support chat**, click the chat bubble in the bottom-right corner of the app to start a conversation
* **Email**, reach the support team by email for questions that need a longer reply or attachments
You can also open the **help (?) icon** in the app for assistance without leaving what you are working on. When you contact support, describing what you expected, what happened, and the steps you took helps them resolve your issue faster.
***
## What's new (changelog)
Heffl updates regularly with new features and improvements. The **What's new** changelog lists recent releases so you can see what has changed. Check it now and then to discover features that may help your workflow. See [What's new](https://docs.heffl.com/changelog).
***
## Troubleshooting common issues
Most everyday problems fall into a few categories. Here is where to look first.
**I can't see a feature or module** Features like Field Service, Projects, or Finance are enabled per workspace and shown based on your role. If something is missing, check with your workspace admin, or review [Configure features](https://heffl.com/). Your role may also limit what you can see; see [Inviting your team members](https://docs.heffl.com/getting-started/untitled-page-2).
**A client can't log into the portal** Confirm the portal is enabled on the parent company and that the contact has a valid email on record. The client logs in with a one-time code sent to that email. See [Setting up the client portal](https://docs.heffl.com/setting-up-the-client-portal).
**My automation didn't run** Open the automation's **Runs** tab to see whether it fired and whether a step failed. Check that the automation is toggled on and that its trigger matches the event you expected. See [Creating an automation](https://docs.heffl.com/setting-up-your-first-automation).
**A form submission didn't create a record** Linking a form to an entity stores the response but does not automatically create a record. To create a lead or other record from a submission, set up an automation. See [Creating and sharing forms](https://docs.heffl.com/creating-and-sharing-forms).
**Email or WhatsApp messages aren't sending** Check that the relevant channel is connected under Apps & integrations, and reconnect it if needed. See [Integrations and connected apps](https://docs.heffl.com/integrations-and-connected-apps).
**Dates or times look wrong** Confirm your timezone in [Account settings](https://docs.heffl.com/account-settings), since all dates and times display in your personal timezone.
**I can't delete a record** Deletion fails when a record has linked items, for example a contact with linked deals, invoices, or quotations. Remove or reassign the linked items first, then delete.
If none of these match your issue, contact support using the options above.
***
## Glossary of terms
Common terms used across Heffl:
* **Lead**: a potential customer or opportunity in the early stages, before becoming a deal
* **Deal**: a sales opportunity tracked through a pipeline
* **Pipeline**: a series of stages a deal or project moves through, one set per type of work
* **Stage**: a step within a pipeline (for example, Enquired or Completed)
* **Company**: a business record that contacts and deals can link to
* **Contact**: an individual person record
* **Client**: a company or contact you do business with
* **Quotation**: a price proposal sent to a client, which can become an invoice
* **Proforma invoice**: a prealiminary invoice issued before the final one
* **Invoice**: a bill sent to a client for payment
* **Payment**: money received from a client, applied to one or more invoices
* **Unused amount**: the part of a payment not yet applied to an invoice, held as credit
* **Recurring invoice**: a profile that generates invoices automatically on a schedule
* **Project**: a body of work delivered for a client, made up of tasks
* **Task**: an individual to-do, on its own or within a project
* **Timesheet**: a logged record of hours worked, billable or non-billable
* **Job**: a piece of on-site field service work, one-off or contract
* **Contract job**: a field service job that repeats on a schedule (for example, AMC)
* **Schedule**: a planned, assigned field service visit
* **Service report**: a record of what was done during a job visit
* **Automation**: a trigger-and-action rule that does work for you automatically
* **Trigger**: the event that starts an automation
* **Form**: a shareable form that collects responses into Heffl
* **Wiki**: the internal space for notes and documents
* **Inbox**: the unified view of conversations from connected channels
* **Client portal**: the secure space where clients view their quotes, invoices, and jobs
* **Custom field**: an extra field you add to a record type
* **Module numbers**: the automatic numbering format for each record type (such as QTTS-)
* **Tag**: a label used to group and filter records
* **List**: a saved group of records for quick access
***
## What to do next
1. Browse [What's new](https://docs.heffl.com/changelog) to see recent features
2. Reach out via support chat or email if you are stuck
3. Use this [glossary](https://heffl.com/) when a term is unfamiliar
# Switching between list view and Kanban view
Source: https://docs.heffl.com/switching-between-list-view-and-kanban-view
The Leads page offers two ways to view your leads: a list view and a Kanban board. Both show the same leads, just arranged differently. Switch between them depending on whether you want detail or a visual overview of your pipeline.
You switch views using the tabs at the top of the Leads page: **All leads** for the list, and **Kanban** for the board.
***
## List view (All leads)
The list view shows your leads in a table, one row each. This is the best view for scanning detail and editing many leads quickly.
It shows columns such as No, Name, Title, Stage, Mobile, Email, Website, Tags, Notes, and Next Activity. You can:
* Scroll horizontally to see more columns
* Click any cell to edit it inline (stage, tags, contact details, notes)
* Select rows with the checkboxes for bulk actions
* See your total lead count at the bottom (for example, "81 leads")
Use list view when you need to compare leads side by side or update fields in bulk.
***
## Kanban view
The Kanban view shows your leads as cards arranged in columns, one column per stage: New, Followed up, Contacted, Demo Done, Unqualified, Junk, and Converted. Each column header shows how many leads sit in that stage.
Each card shows the lead's name, ID number, next activity date, and assignee. You can:
* See your whole pipeline at a glance
* Spot which stages are crowded or empty
* Drag a card from one column to another to move the lead to a new stage
* Scroll within a column when it holds many leads
Use Kanban view when you want a visual picture of where your leads stand and to move them through stages by dragging.
***
## Controls that work in both views
The toolbar above the leads stays the same whichever view you are in, so your filters and sorting carry over when you switch:
**Sort** Click **Sort** to order your leads by Created at, Name, or Value, in Ascending or Descending order.
**Filters** Click **Filters** to narrow by Created at, List, Assigned to, Owners, Sources, or Lost Reasons.
**Stage** Filter to show only certain stages (New, Followed up, Contacted, Demo Done, Unqualified, Junk, Converted). Tick the stages you want, or click Clear to reset.
**Status** Switch between Active and Archived leads. Active is shown by default.
**Next Activity Date** Focus on leads needing attention soon: Today, Tomorrow, Next 7 Days, Next 30 Days, or a Custom range.
**Search** Use the search icon to find a specific lead by name in either view.
***
## Which view should you use?
Use list view when you want to read and edit lead details, work through many leads, or make bulk changes. Use Kanban view when you want to see your pipeline visually and move leads between stages by dragging.
Your choice of view is remembered, so Heffl opens the same view next time you return to Leads.
# Notification settings
Source: https://docs.heffl.com/untitled-page
Notification settings control what you are alerted about and how those alerts reach you. Tuning them means you hear about what matters without being overwhelmed by noise. You will find these under **Settings > Notifications**, in the **Personal** group, so they apply to you alone.
***
## Where notifications appear
Heffl can notify you in a few places:
* **In-app**, through the **Notifications** item in the main sidebar, where alerts collect as you work
* **Email**, sent to your account email
* **Other channels**, such as Zoho Cliq, if connected as an integration. See [Integrations and connected apps](https://docs.heffl.com/integrations-and-connected-apps).
The Notifications settings screen is where you choose which events trigger an alert and through which of these channels.
***
## What you can be notified about
Notifications are tied to activity across your records and work, such as:
* A record or task being **assigned to you**
* A **task or follow-up** becoming due
* Updates on **deals, quotations, or invoices** you are involved in
* **Mentions or comments** directed at you
* **Field service** schedule changes
* System events relevant to your role
Turn on the events you want to stay on top of, and turn off the ones that are not useful to you.
***
## Choosing your channels
For each type of notification, you can usually choose how you receive it, in-app, by email, or both. A practical approach:
* Keep **in-app** on for most things, since it is low-friction
* Reserve **email** for items you must not miss, such as assignments and due follow-ups
* Use a connected channel like **Zoho Cliq** if your team lives in that tool
***
## Managing notification volume
If you are getting too many alerts, reduce the noise by turning off notifications for events you do not act on, and keeping only the ones that need your attention. If you are missing things, do the opposite, switch on alerts for assignments and due dates so nothing slips.
Because these are personal settings, your choices affect only your own notifications, not your teammates'.
***
## Staying on top of follow-ups
Notifications work hand in hand with the **next activity dates** you set on leads, deals, and tasks. When a follow-up comes due, a notification surfaces it, so the reminders you set actually reach you. See [Logging activities, notes, and follow-ups](https://docs.heffl.com/logging-activities-notes-and-follow-ups).
***
## What to do next
1. Review your [account settings](https://docs.heffl.com/account-settings) and profile
2. Connect a channel like [Zoho Cliq](https://heffl.com/) if you want alerts there
3. Set [next activity dates](https://heffl.com/) so follow-up notifications reach you
# Using the Heffl API
Source: https://docs.heffl.com/using-the-heffl-api
Heffl offers a REST API for developers who want to connect Heffl to their own systems or build custom integrations. This page is a brief orientation; the full technical reference lives in Heffl's developer documentation.
***
## What the API is for
The API gives programmatic access to your workspace data, so developers can read and write records from their own code. It covers core records including:
* Contacts and companies
* Deals
* Quotations
* Tasks
* Document templates
With it, you can do things like pull deals into another system, create quotations automatically, or sync contacts between Heffl and an external app.
***
## Who this is for
This is a technical feature aimed at developers. Most users do not need it. For everyday connections to tools like Gmail, Outlook, Stripe, Telr, or Zoho Books, use the ready-made connectors instead, no code required. See [Integrations and connected apps](https://docs.heffl.com/integrations-and-connected-apps).
Reach for the API only when you need a custom integration that the built-in connectors do not cover.
***
## Getting started
1. Find your **API key** under **Settings > Developers**
2. Include the key in the `x-api-key` header on every request
3. Send requests to the API base URL over HTTPS
A simple request to list contacts looks like this:
`curl "" \\ -H "x-api-key: YOUR_API_KEY"`
Treat your API key like a password. Anyone with it can access your workspace data, so keep it secret and do not share it in public code.
***
## Versions
Heffl has two API versions:
* **API v2** is the current REST API (beta), with resource-based paths like `/contacts`, `/companies`, and `/deals`
* **API v1** (legacy) remains fully supported for existing integrations
New integrations should use v2 where possible.
***
## Full developer reference
For everything else, including authentication, the full list of endpoints, filtering and search, pagination, error codes, custom fields, and code examples, see the official developer documentation:
[**docs.heffl.com/api-v2**](https://docs.heffl.com/api-v2/introduction)
It is kept up to date as the API evolves, so it is the authoritative source for building against Heffl.
***
## What to do next
1. Get your API key from **Settings > Developers**
2. Read the [API v2 reference](https://docs.heffl.com/api-v2/introduction)
3. For non-developer needs, use [the built-in integrations](https://docs.heffl.com/integrations-and-connected-apps) instead
# Wiki: internal notes and documents
Source: https://docs.heffl.com/wiki-internal-notes-and-documents
The Wiki is your workspace's built-in note-taking and document space. Use it to write and store internal documents, meeting notes, guides, and anything your team needs to reference. It works like a lightweight document editor organized into folders. You will find the **Wiki** section in the sidebar.
***
## How the Wiki is organized
The Wiki uses two building blocks:
* **Folders** group related documents together. Folders can be **nested**, so you can put folders inside folders to build a structure (for example, a team folder containing sub-folders per topic).
* **Documents** are the individual pages you write inside a folder.
Folders appear under the Wiki heading in the sidebar, with their documents and sub-folders nested beneath them.
***
## Creating a folder
1. In the sidebar, click the **+** next to Wiki (or next to an existing folder to nest one inside it)
2. In the **Create new folder** panel, enter a **Title**
3. Optionally add a **Description** to note what the folder is for
4. Choose an **icon** and **color** under Appearance to make the folder easy to spot
5. Set the **Visibility**:
* **Open** means everyone on your team can view and edit
* **Private** means only invited people can access it
6. Click **Create folder**
***
## Creating a document
1. Open a folder
2. Click **+ Document** in the top right
3. Give the document a title
4. Start writing in the editor
Documents save automatically as you type. You will see a "Saved" note when your changes are stored. Each folder lists its documents with the author and the date last updated.
***
## Using the editor
You can add content blocks two ways.
**The Insert panel** The panel on the right lists every block. Click one to insert it: Text, Wiki Link, Callout, File Attachment, Image, YouTube, Code Block, and Toggle, plus dividers (Insert Line) and tables (Insert Table).
**The slash command** Type `/` anywhere in the document to open an inline insert menu, then pick a block without leaving the keyboard. The menu includes Text, Heading 1, Heading 2, Heading 3, Bullet List, Numbered List, Task List, Embed, YouTube, Callout, Toggle, and Table. This is the quickest way to build a document as you write.
**Callout types** Callouts come in four styles for highlighting different notes: Info, Warning, Tip, and Note.
The tabs at the top right, **Insert**, **Format**, **Style**, and **Info**, switch between adding content, formatting text, styling the page, and viewing document details.
***
## Linking between documents
Use the **Wiki Link** block to link one Wiki document to another. This lets you connect related notes, for example linking a meeting note to the guide it references. Wiki Links point to other Wiki documents, so the Wiki works as a connected internal knowledge base rather than linking out to records like leads or projects.
***
## Sharing and visibility
Click **Share** in the top right of any document to control who can see it. Sharing follows the folder's visibility setting:
* A document in an **Open** folder can be viewed and edited by everyone on your team
* A document in a **Private** folder is limited to invited people
Set a folder's visibility when you create it, and choose Private for anything sensitive so it stays restricted to the right people.
***
## When to use the Wiki
The Wiki is best for:
* Internal documentation and team guides
* Meeting notes and follow-up action lists
* Standard operating procedures
* Anything your team needs to find and edit later
For documents you send to clients, such as quotes and proposals, use the document editor in [Quotations](https://docs.heffl.com/creating-and-sending-quotations) instead. The Wiki is meant for internal knowledge.
***
## What to do next
1. Create a folder for each major topic or team, nesting sub-folders where helpful
2. Set folder visibility to Open or Private depending on sensitivity
3. Add documents and connect related pages with Wiki Links
# Workspace and organization settings
Source: https://docs.heffl.com/workspace-and-organization-settings
Organization settings affect your whole workspace, not just you. They cover your company details and the configuration that shapes how Heffl works for everyone on your team. These usually require admin or owner access. You will find them under **Settings**, in the **Organization** group. This page gives a brief tour of each, with pointers to fuller guides where they exist.
***
## Organization
The **Organization** screen holds your company-level details: company name, logo, address, contact information, default currency, and timezone. These appear on documents you send to clients, such as quotes and invoices, so keep them accurate. See [Setting up your workspace](https://heffl.com/) for the full setup.
***
## Clients
The **Clients** settings control defaults for how companies and contacts behave, such as client types and related options. Your actual client records live under Companies and Contacts; this screen configures the settings behind them. See [Adding and managing companies](https://docs.heffl.com/adding-and-managing-companies).
***
## Tags
**Tags** are the labels you attach to records to group and filter them (such as VIP or Medical). This screen is where you create, rename, and manage the workspace's tag list, so your team uses a consistent set rather than ad-hoc labels.
***
## Lists
**Lists** are saved groups of records, such as VIP Clients or Hot deals, that appear in your sidebar for quick access. This screen manages those lists at the workspace level.
***
## Zones
**Zones** define geographic areas, useful for field service businesses that organize work or staff by region. Set up your zones here so jobs and scheduling can reference them.
***
## Objects
**Objects** let you extend Heffl with custom record types beyond the built-in ones (leads, deals, and so on). This is where you define custom objects to model data specific to your business.
***
## Custom fields and field mappings
Two related screens control your data structure:
* **Custom fields** add your own fields to records (such as a contract end date or tank size). See [Creating and managing custom fields](https://heffl.com/).
* **Field mappings** control how data carries across when records convert, for example which fields flow from a lead into a deal, so information is not lost in the handoff.
***
## Module configuration
Several Organization items configure a specific module. These are documented in their own sections, so here is just what each one does:
* **CRM** settings configure leads, deals, pipelines, and stages. See [Working with the deals pipeline](https://heffl.com/).
* **Sales** settings configure quotations, invoices, and related defaults. See [Creating and sending quotations](https://docs.heffl.com/creating-and-sending-quotations).
* **Projects** settings configure project workflows and stages. See [Introduction to project management in Heffl](https://docs.heffl.com/introduction-to-project-management-in-heffl).
* **Field service** settings configure jobs, schedules, and field options. See [Introduction to field service](https://heffl.com/).
* **Inbox** settings configure your connected conversation channels. See [Inbox: managing conversations](https://docs.heffl.com/inbox-managing-conversations).
* **Integrations** connect third-party tools. See [Integrations and connected apps](https://docs.heffl.com/integrations-and-connected-apps).
* **Client Portal** settings control the portal your clients log into. See [Setting up the client portal](https://docs.heffl.com/setting-up-the-client-portal).
***
## Numbering and document templates
Two more Organization items, **Module numbers** and **Document templates**, control record numbering and your shared document designs. These are covered together in [Numbering and document templates](https://docs.heffl.com/numbering-and-document-templates).
***
## Developers
The **Developers** screen is where you find your API key for building custom integrations. See [Using the Heffl API](https://docs.heffl.com/using-the-heffl-api).
***
## Roles and team access
Managing who can see and do what, inviting members, assigning roles, and setting permissions, is covered in [Inviting your team members](https://heffl.com/).
***
## What to do next
1. Confirm your [organization details](https://heffl.com/) are accurate
2. Set up [custom fields](https://heffl.com/) and tags for your business
3. Review [numbering and document templates](https://heffl.com/)