[Cotlet](https://cotlet.dev/index.md) · [Integrations](https://cotlet.dev/integrations.md) · [How it works](https://cotlet.dev/how-it-works.md) · [Use cases](https://cotlet.dev/use-cases.md) · [Security](https://cotlet.dev/security.md) · [For developers](https://cotlet.dev/for-developers.md) · [For automation agencies](https://cotlet.dev/for-agencies.md) · [Blog](https://cotlet.dev/blog.md) · [API docs](https://cotlet.dev/docs.md) · [Help center](https://cotlet.dev/help.md) · [Changelog](https://cotlet.dev/changelog.md) · [Contact](https://cotlet.dev/contact.md) · [Pricing](https://cotlet.dev/pricing.md) · [Sign up](https://cotlet.dev/signup)

# Freshsales API and MCP server

> Yes, Freshsales has a full REST API, but no official MCP server for CRM data (checked 22 Oct 2026). You copy a personal API key from Profile Settings > API Settings and send it with every call, and Freshsales lists API access as a paid-plan feature. The Freshworks MCP server covers Freshdesk only.

Sales CRM from Freshworks: contacts, accounts, deals in pipelines with stages, tasks, meetings, notes, workflows and sales sequences.

## What is the Freshsales API?

Cotlet's Freshsales API exposes 11 endpoints for your own Freshsales account: list deals, get a deal, list rotten deals, list pipelines and stages, list contacts, get a contact, list tasks, create a task, complete or reopen a task, add a note and move a deal to another stage. The list_deals endpoint returns deals from a Freshsales view, filtered by pipeline, stage or owner. Each endpoint takes simple JSON inputs like cursor, deal_id or view and works both as an operation of the freshsales_read or freshsales_write MCP tool for agents and as a REST call for scripts.

- **Category:** [Invoicing & freelance CRM](https://cotlet.dev/integrations/category/invoicing-freelance-crm.md)
- **Endpoints:** 11 (7 read, 4 write)
- **Updated:** 2026-10-21

Yes, Freshsales has a full REST API, but no official MCP server for CRM data (checked 22 Oct 2026). Cotlet is a hosted MCP server and REST API for Freshsales with 11 endpoints (7 read, 4 write): you sign in once in your own cloud browser, your AI agent does the work.

## Does Freshsales have an official API?

Yes, Freshsales has a full REST API, but no official MCP server for CRM data (checked 22 Oct 2026). You copy a personal API key from Profile Settings > API Settings and send it with every call, and Freshsales lists API access as a paid-plan feature. The Freshworks MCP server covers Freshdesk only.

| Task | Freshsales official | Cotlet |
|---|---|---|
| List and read deals by pipeline and stage | Yes: REST API, with your own code | Yes |
| Move a deal to another stage, or mark it Won or Lost | Yes: REST API deal update | Yes |
| List rotten deals | Partly: Rotten deals are a view in the app; the API docs list no matching filter | Yes |
| List contacts from a view such as Never Contacted | Yes: REST API views, with your own code | Yes |
| Create tasks on a contact, account or deal | Yes: REST API tasks | Yes |
| Read open and overdue tasks | Yes: REST API task list with a filter | Yes |
| Add a note to a contact, account or deal | Yes: REST API notes | Yes |
| Let an AI agent do any of this without code or an API key | No: No official MCP server for CRM data, and API access is not in the Free plan | Yes |

Sources: [Freshworks CRM API documentation](https://developers.freshworks.com/crm/api/), [Freshworks Help: MCP integration (Freshdesk only)](https://crmsupport.freshworks.com/support/solutions/articles/50000012670-model-context-protocol-mcp-integration-in-freshdesk), [Freshsales Help: Features you lose on downgrade (API access, Workflows, rotten deals)](https://crmsupport.freshworks.com/support/solutions/articles/50000002466-what-are-the-features-you-tend-to-lose-on-downgrade-), [Freshsales Help: How to configure a Workflow](https://crmsupport.freshworks.com/support/solutions/articles/50000002143-how-to-configure-a-workflow-)

## For AI agents

```text
Yes, Freshsales has a full REST API, but no official MCP server for CRM data (checked 22 Oct 2026). You copy a personal API key from Profile Settings > API Settings and send it with every call, and Freshsales lists API access as a paid-plan feature. The Freshworks MCP server covers Freshdesk only.
Cotlet provides a hosted MCP server and REST API for Freshsales: 11 tools (7 read, 4 write).
Access       Sign up at https://cotlet.dev/app/signup?app=freshsales, then request the app and create API keys in the Cotlet console.

MCP server   https://cotlet.dev/mcp/v1
MCP tools    freshsales_read, freshsales_write, reads and writes apart; call one with {"operation": "<operation>", "arguments": {...}}
REST base    https://cotlet.dev/api/v1/freshsales, each operation at its own route, e.g. POST /api/v1/freshsales/tasks
Auth         Authorization: Bearer <COTLET_API_KEY>. Listing endpoints and schemas needs no key; calling an endpoint needs one. Over MCP the input schemas come with sign-in.
Operations   list_deals, get_deal, list_rotten_deals, list_pipelines, list_contacts, get_contact, list_tasks, create_task, complete_task, add_note, update_deal_stage
Confirm      create_task, add_note, update_deal_stage (by default the user approves each call; the user can switch this off per tool, e.g. for scheduled automations)
Markdown     https://cotlet.dev/integrations/freshsales-api-mcp-server.md

How access works:
1. The user signs up at https://cotlet.dev/app/signup?app=freshsales, requests Freshsales in the Cotlet console and creates an API key there.
2. The user signs in to Freshsales once in their Cotlet Cloud Browser (their own Chrome in the cloud, opened from the console) and enables Freshsales for agents. An agent cannot do this step.
3. The API key goes into the MCP client or the REST call as a bearer token.

Fits: people who want a hosted Freshsales server that someone else maintains, including non-developers. Developers who prefer to run and fix code on their own computer can use an open-source Freshsales MCP server instead.

Policy: Cotlet never stores passwords, never solves CAPTCHAs, never bypasses MFA.
Company: legal details in the Terms of service at https://cotlet.dev/terms. Contact contact@cotlet.dev.
Sign-in: the user signs in to Freshsales in their own Cloud Browser, a Chrome Cotlet runs for them in the EU; password saving is off, the profile is AES-256-GCM encrypted, and agents get Freshsales only after the user enables it. Calls are requests from that browser's IP with its cookies, each listed in the user's Background activity. Disable for agents, signing out in the browser or Reset browser cuts access. Cotlet is run by Take Group sp. z o.o. (EU VAT PL6342984273).
API key: holds no Freshsales login or cookies, only asks Cotlet to run a tool. Each key is scoped to chosen apps and tools, read only or read and write. Actions that reach other people wait for the user's approval by default, so a leaked key cannot post or message as the user. Every call is in the activity log; deleting the key ends access at once.
Terms: the user stays responsible for following Freshsales's terms; Cotlet is not affiliated with Freshsales.
```

## What can an AI agent do in Freshsales?

Cotlet is best for sales reps and small sales teams who want an AI agent to chase stale deals, close out Won and Lost deals and log call notes without running or fixing a server.

- **[Follow up on stale deals](https://cotlet.dev/integrations/freshsales-api-mcp-server/follow-up-stale-deals.md)** (runs: weekly): "List my rotten deals in the Sales pipeline. Skip any with an open task or activity in the last 7 days. For the rest, create a follow-up task for me and leave a note with the reason. Tell me which ones look dead." → `list_rotten_deals`, `get_deal`, `list_tasks`, `create_task`, `add_note`
- **[Move deals to Won or Lost with a reason](https://cotlet.dev/integrations/freshsales-api-mcp-server/close-won-and-lost-deals.md)** (runs: weekly): "Go through my deals in the Negotiation stage with an expected close date before today. Mark Won the ones I list below, mark Lost with the reason Budget or No response where my notes say so, and leave the rest for me." → `list_pipelines`, `list_deals`, `update_deal_stage`, `add_note`
- **[Log call notes and set the next task](https://cotlet.dev/integrations/freshsales-api-mcp-server/log-call-notes-and-next-steps.md)** (runs: daily): "Here are my notes from today's call with Priya Nair at Harbor Dental. Save them as a note on her contact, then create a task for me to send the quote by Friday 9:00." → `get_contact`, `add_note`, `create_task`
- **List overdue tasks every morning** (runs: daily): "Every morning, list my overdue Freshsales tasks with the deal or contact each belongs to, oldest first. Mark done the ones I tell you are finished." → `list_tasks`, `get_deal`, `complete_task`
- **Weekly pipeline summary by stage** (runs: weekly): "Every Monday, count my open deals and their total value per stage in the Sales pipeline, and list the five with the nearest expected close date." → `list_pipelines`, `list_deals`
- **Reach contacts nobody has talked to**: "Take the Never Contacted view, pick the contacts created in the last 30 days, and create a task for me to reach out to each, due Thursday." → `list_contacts`, `get_contact`, `create_task`

## Can Freshsales automations run on a schedule in n8n, Make or Zapier?

Yes. Cotlet does not replace your automation platform: it gives it a Freshsales connection it does not have, with the same API key as your agent. Write actions ask for your OK by default; switch that off in your dashboard for the tools you choose, for example to follow up on stale deals, and the schedule runs on its own. Cotlet runs in the cloud, so it keeps going while your computer is off.

| Where | How to connect | How to schedule |
|---|---|---|
| Your AI agent | Add https://cotlet.dev/mcp/v1 with your API key. | A scheduled agent run, for example a Claude Code routine. |
| n8n | MCP Client node with https://cotlet.dev/mcp/v1, or an HTTP Request node with the endpoint's method and URL, such as GET https://cotlet.dev/api/v1/freshsales/rotten-deals. | Schedule Trigger node. |
| Make | HTTP module: the endpoint's method and URL with an Authorization: Bearer header, and a JSON body for POST, PUT and PATCH. | Scenario schedule. |
| Zapier | Webhooks by Zapier, Custom Request: the same method, URL, header and body. | Schedule by Zapier trigger. |
| Your own script | GET https://cotlet.dev/api/v1/freshsales/rotten-deals with your API key. | cron or GitHub Actions. |

## Tools

**For AI agents:** Every endpoint and its schema is public. The 11 endpoints on this page, with parameters and example responses, can be listed without an account. Calling one returns 401 without an API key and 403 while the key has no access to Freshsales.

### list_deals

Deals from a Freshsales view, filtered by pipeline, stage or owner. Access: read. REST: `GET /api/v1/freshsales/deals`. MCP: `freshsales_read → list_deals`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `view` | string | no | Open Deals, My Deals, Won Deals or Hot Deals. Default Open Deals. |
| `pipeline` | string | no | Pipeline name from list_pipelines. |
| `stage` | string | no | Stage name from list_pipelines. |
| `owner` | string | no | Name or email of the sales owner. |
| `sort` | string | no | amount, expected_close, created_at, updated_at or last_contacted. |
| `sort_type` | string | no | asc or desc. Default desc. |
| `cursor` | string | no | next_cursor of the previous page. |

Lists deals as the Deals module shows them for the view you pick, with the deal value, stage, pipeline, owner, account and expected close date. It reads a page at a time, so follow next_cursor to the end. Stage and pipeline names must match list_pipelines. A deal you cannot see in your Freshsales role is not returned.

Example response:

```json
{
  "deals": [
    {
      "deal_id": 7000412,
      "name": "Website redesign",
      "amount": 4800,
      "stage": "Negotiation",
      "pipeline": "Sales pipeline",
      "owner": "Dana Reyes",
      "account": "Northwind Studio",
      "expected_close": "2026-10-28"
    },
    {
      "deal_id": 7000388,
      "name": "Annual support plan",
      "amount": 12500,
      "stage": "Follow-up",
      "pipeline": "Sales pipeline",
      "owner": "Dana Reyes",
      "account": "Harbor Dental",
      "expected_close": "2026-09-30"
    }
  ],
  "next_cursor": null
}
```

### get_deal

One deal with its age, last activity, account and contacts. Access: read. REST: `GET /api/v1/freshsales/deals/{deal_id}`. MCP: `freshsales_read → get_deal`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `deal_id` | integer | yes | Deal id from list_deals. |

Returns the fields of the deal page: value, stage, pipeline, owner, expected close, age in days, created date and last activity date, with the account and the related contacts. The age counts from the creation date, so use last_activity_date to see whether a deal is quiet.

Example response:

```json
{
  "deal_id": 7000388,
  "name": "Annual support plan",
  "amount": 12500,
  "stage": "Follow-up",
  "pipeline": "Sales pipeline",
  "owner": "Dana Reyes",
  "expected_close": "2026-09-30",
  "age_days": 41,
  "created_at": "2026-09-11",
  "last_activity_date": "2026-10-02",
  "account": "Harbor Dental",
  "contacts": [
    {
      "contact_id": 5100231,
      "name": "Priya Nair"
    }
  ]
}
```

### list_rotten_deals

Deals that are past the staling age of their pipeline. Access: read. REST: `GET /api/v1/freshsales/rotten-deals`. MCP: `freshsales_read → list_rotten_deals`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `pipeline` | string | no | Pipeline name from list_pipelines. Default: every pipeline you can see. |
| `cursor` | string | no | next_cursor of the previous page. |

Returns the deals Freshsales shows under Show only rotten Deals, with their age in days and how many days they are past the staling age. That age is set per pipeline by an admin under Deals go stale after, and it counts from the day the deal was created, not from its last activity. The call fails on the Free plan, where Freshsales has no rotten deals.

Example response:

```json
{
  "deals": [
    {
      "deal_id": 7000388,
      "name": "Annual support plan",
      "amount": 12500,
      "stage": "Follow-up",
      "pipeline": "Sales pipeline",
      "owner": "Dana Reyes",
      "age_days": 41,
      "days_past_staling_age": 11
    },
    {
      "deal_id": 7000377,
      "name": "Onboarding package",
      "amount": 2200,
      "stage": "New",
      "pipeline": "Sales pipeline",
      "owner": "Dana Reyes",
      "age_days": 33,
      "days_past_staling_age": 3
    }
  ],
  "next_cursor": null
}
```

### list_pipelines

Pipelines with their stages in order, and the Lost reasons. Access: read. REST: `GET /api/v1/freshsales/pipelines`. MCP: `freshsales_read → list_pipelines`.

No parameters.

Returns each pipeline with its stages from first to last, and the list of Lost reasons an admin set. Use these exact names in list_deals and update_deal_stage. Several pipelines in one account need the Pro plan, so on a lower plan you get one.

Example response:

```json
{
  "pipelines": [
    {
      "name": "Sales pipeline",
      "stages": [
        "New",
        "Follow-up",
        "Under review",
        "Demo",
        "Negotiation",
        "Won",
        "Lost"
      ]
    }
  ],
  "lost_reasons": [
    "Budget",
    "Went with another vendor",
    "No response"
  ]
}
```

### list_contacts

Contacts from a Freshsales view such as Never Contacted. Access: read. REST: `GET /api/v1/freshsales/contacts`. MCP: `freshsales_read → list_contacts`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `view` | string | no | My Contacts, All Contacts, Recently Modified or Never Contacted. Default My Contacts. |
| `sort` | string | no | created_at, updated_at or last_contacted. |
| `sort_type` | string | no | asc or desc. Default desc. |
| `cursor` | string | no | next_cursor of the previous page. |

Lists contacts as the Contacts module shows them for that view, with name, email, account, owner and the date they were last contacted. last_contacted is empty for a contact nobody has talked to. Read a page at a time with next_cursor.

Example response:

```json
{
  "contacts": [
    {
      "contact_id": 5100231,
      "name": "Priya Nair",
      "email": "priya@harbordental.example",
      "account": "Harbor Dental",
      "owner": "Dana Reyes",
      "last_contacted": "2026-10-02"
    },
    {
      "contact_id": 5100244,
      "name": "Tomas Weber",
      "email": "tomas@northwind.example",
      "account": "Northwind Studio",
      "owner": "Dana Reyes",
      "last_contacted": null
    }
  ],
  "next_cursor": null
}
```

### get_contact

One contact with its account, open deals and latest notes. Access: read. REST: `GET /api/v1/freshsales/contacts/{contact_id}`. MCP: `freshsales_read → get_contact`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `contact_id` | integer | yes | Contact id from list_contacts. |

Returns the contact page: name, email, account, owner, the deals linked to the contact with their stage, and the latest notes, newest first. Use it to read what is already written before you add a note.

Example response:

```json
{
  "contact_id": 5100231,
  "name": "Priya Nair",
  "email": "priya@harbordental.example",
  "account": "Harbor Dental",
  "owner": "Dana Reyes",
  "deals": [
    {
      "deal_id": 7000388,
      "name": "Annual support plan",
      "stage": "Follow-up"
    }
  ],
  "notes": [
    {
      "note_id": 9300017,
      "body": "Asked for a quote with a 12-month term.",
      "created_at": "2026-10-02T11:20:00"
    }
  ]
}
```

### list_tasks

Your Freshsales tasks, filtered by status and by the deal or contact they belong to. Access: read. REST: `GET /api/v1/freshsales/tasks`. MCP: `freshsales_read → list_tasks`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `filter` | string | yes | open, overdue or completed. |
| `deal_id` | integer | no | Only tasks related to this deal. |
| `contact_id` | integer | no | Only tasks related to this contact. |
| `cursor` | string | no | next_cursor of the previous page. |

Returns tasks with title, due date, status, owner and the deal, contact or account each is related to. Freshsales shows a task only to its owner and its collaborators, so you see your own tasks and the ones shared with you, not the whole team. Read a page at a time with next_cursor.

Example response:

```json
{
  "tasks": [
    {
      "task_id": 8800121,
      "title": "Send revised quote",
      "due": "2026-10-19T10:00:00",
      "status": "open",
      "overdue": true,
      "owner": "Dana Reyes",
      "related_to": {
        "type": "Deal",
        "id": 7000412,
        "name": "Website redesign"
      }
    }
  ],
  "next_cursor": null
}
```

### create_task

Create a task on a contact, account or deal. Access: write, asks the user first. REST: `POST /api/v1/freshsales/tasks`. MCP: `freshsales_write → create_task`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `title` | string | yes | Task title. |
| `due` | string | yes | Due date and time, ISO 8601. Freshsales uses 30-minute steps. |
| `related_to_type` | string | yes | Contact, Account or Deal. |
| `related_to_id` | integer | yes | Id of that record. |
| `description` | string | no | Longer text for the task. |
| `owner` | string | no | Name or email of the owner. Default you. |
| `collaborators` | array | no | Names or emails of users to share the task with. |

Creates the task as the Add task form does, with the first task type in your list. The owner is you unless you name another user. A collaborator gets an email when the task is created. The task stays open until someone completes it. By default you confirm each call; you can switch that off for this tool.

Example response:

```json
{
  "task_id": 8800140,
  "title": "Follow up: Annual support plan (41 days old, last activity 02 Oct)",
  "due": "2026-10-26T10:00:00",
  "status": "open",
  "owner": "Dana Reyes",
  "related_to": {
    "type": "Deal",
    "id": 7000388,
    "name": "Annual support plan"
  },
  "collaborators": []
}
```

### complete_task

Mark a task completed, or open it again. Access: write. REST: `POST /api/v1/freshsales/tasks/{task_id}/complete`. MCP: `freshsales_write → complete_task`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `task_id` | integer | yes | Task id from list_tasks. |
| `completed` | boolean | no | true to complete, false to reopen. Default true. |

Changes the status of one task you own or share. It touches only the task, and one call with completed set to false undoes it, so it does not wait for your OK by default.

Example response:

```json
{
  "task_id": 8800121,
  "status": "completed"
}
```

### add_note

Add a note to a contact, account or deal. Access: write, asks the user first. REST: `POST /api/v1/freshsales/notes`. MCP: `freshsales_write → add_note`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `record_type` | string | yes | Contact, Account or Deal. |
| `record_id` | integer | yes | Id of that record. |
| `body` | string | yes | The note text. |

Saves the note on the record, where Freshsales shows it on the timeline for everyone who can open that record. It does not post to Slack. Nothing in Cotlet deletes a note, so check the text before you approve. By default you confirm each call; you can switch that off for this tool.

Example response:

```json
{
  "note_id": 9300052,
  "record": {
    "type": "Contact",
    "id": 5100231,
    "name": "Priya Nair"
  },
  "body": "Call 22 Oct: wants a start date before the end of November and a quote with two payment options. Next step: send the quote by Friday.",
  "created_at": "2026-10-22T14:05:00"
}
```

### update_deal_stage

Move a deal to another stage, including Won or Lost. Access: write, asks the user first. REST: `PATCH /api/v1/freshsales/deals/{deal_id}/stage`. MCP: `freshsales_write → update_deal_stage`.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `deal_id` | integer | yes | Deal id from list_deals. |
| `stage` | string | yes | Stage name from list_pipelines, in the deal's own pipeline. |
| `lost_reason` | string | no | A Lost reason from list_pipelines. Needed for Lost when your admin made the field required. |

Changes the stage as a drag in the Pipeline view does. Moving to Won sets the closed date, and moving to Lost takes a Lost reason. Your Workflows can start on the change and email contacts or the owner. Move it back with a second call. By default you confirm each call; you can switch that off for this tool.

Example response:

```json
{
  "deal_id": 7000377,
  "name": "Onboarding package",
  "stage": "Lost",
  "previous_stage": "New",
  "lost_reason": "No response"
}
```

## How do I connect Freshsales to Claude Code, Codex or Cursor?

Connecting Freshsales takes three steps: sign up, sign in to Freshsales once in your Cloud Browser and enable it for agents, then add one MCP server or call the REST API with the same key.

### Connect Freshsales to your agent.

1. **Create an account** Sign up and add Freshsales in the console. Your API key is there too.

2. **Sign in to Freshsales in your Cloud Browser** Open your Cloud Browser in the console: your own Chrome in the cloud. Sign in to Freshsales there yourself, the way you always do, then press Enable for agents, read only or read and write. We never save your password, and your agent keeps working even when your computer is off.

3. **Add Cotlet to your agent** Paste the snippet for your client. The same server and key serve every app you connect, so you do this once.

   Claude Code:

```
claude mcp add --transport http cotlet \
  https://cotlet.dev/mcp/v1 \
  --header "Authorization: Bearer $COTLET_API_KEY"
```

   Cursor:

```
{
  "mcpServers": {
    "cotlet": {
      "url": "https://cotlet.dev/mcp/v1",
      "headers": {
        "Authorization": "Bearer ${COTLET_API_KEY}"
      }
    }
  }
}
```

   Codex:

```
# ~/.codex/config.toml
[mcp_servers.cotlet]
url = "https://cotlet.dev/mcp/v1"
bearer_token_env_var = "COTLET_API_KEY"
```

4. **Ask your agent** Ask in plain words. Your agent finds the Freshsales tools on the server and calls them for you; anything that reaches other people waits for your OK unless you switch that off for a tool.

```
List my rotten deals in the Sales pipeline. Skip any with an open task or activity in the last 7 days. For the rest, create a follow-up task for me and leave a note with the reason. Tell me which ones look dead.
```

### Call Freshsales from your scripts.

1. **Export your API key** Your scripts use the same API key as your agent. Keep it in an environment variable, never in your code.

```
export COTLET_API_KEY="cotlet_..."
```

2. **Call a tool** Every tool is an endpoint under /api/v1/freshsales with its own method and path, listed with the endpoints above. Path parameters go in the URL; the other parameters go in the query for GET and DELETE and in a JSON body otherwise.

```
curl -X POST https://cotlet.dev/api/v1/freshsales/tasks \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Follow up: Annual support plan (41 days old, last activity 02 Oct)","due":"2026-10-26T10:00:00","related_to_type":"Deal","related_to_id":7000388}'
```

3. **Read the result** You get plain JSON back, ready for your script. A failed call costs nothing.

```
{
  "task_id": 8800140,
  "title": "Follow up: Annual support plan (41 days old, last activity 02 Oct)",
  "due": "2026-10-26T10:00:00",
  "status": "open",
  "owner": "Dana Reyes",
  "related_to": {
    "type": "Deal",
    "id": 7000388,
    "name": "Annual support plan"
  },
  "collaborators": []
}
```

## Why use Cotlet for Freshsales?

**Built for agents**

- One MCP server for every app you connect.
- The same tools as a REST API for scripts and cron jobs.
- Works with Claude Code, Codex and Cursor.

**Your login stays yours**

- You sign in to Freshsales yourself, in your own Cloud Browser. We never save your password; the profile is encrypted with AES-256-GCM, the cipher 1Password uses.
- A+ on Qualys SSL Labs, securityheaders.com and Mozilla Observatory.
- The model never sees a login.
- No stored passwords, no CAPTCHA solving, no MFA bypass.

**You stay in control**

- Scope each API key: its apps, its tools, read only or read and write.
- Anything that reaches other people waits for your OK, so a leaked key cannot post or message as you.
- Every background request listed in your Background activity. Disable for agents in one click.

**Kept working for you**

- We test every integration every 6 hours.
- When Freshsales changes, the tool pauses until we fix it.
- Failed calls cost nothing.

## Is it safe to connect Freshsales to Cotlet?

Yes. You sign in to Freshsales yourself, in your own Cloud Browser, and we never save your password. Your agents only get Freshsales once you enable it, and every background request is listed. The browser profile is stored encrypted with AES-256-GCM, the same cipher 1Password uses for its vaults and Apple for iCloud Keychain. Independent public scanners grade cotlet.dev A+ and find it clean; click a result to rerun it yourself.

- **A+ on Qualys SSL Labs**: Encryption in transit: TLS setup and certificates, on all four server addresses. [Live result](https://www.ssllabs.com/ssltest/analyze.html?d=cotlet.dev)
- **A+ on securityheaders.com**: Browser protections sent with every page, all six headers present. [Live result](https://securityheaders.com/?q=cotlet.dev&followRedirects=on)
- **A+ on Mozilla Observatory**: Mozilla's web security baseline: score 120 of 100, 12 of 12 tests passed. [Live result](https://developer.mozilla.org/en-US/observatory/analyze?host=cotlet.dev)
- **Clean on Sucuri SiteCheck**: No malware, spam or defacement, and not on any of 9 blocklists, Google Safe Browsing included. [Live result](https://sitecheck.sucuri.net/results/cotlet.dev)

[How Cotlet protects your access](https://cotlet.dev/security.md)

### Common concerns

**Who runs Cotlet?**

Cotlet is run by Take Group, a Polish software company working since 2019. Take Group runs about 3,200 websites on its own systems and has its own DevOps team for infrastructure security. We built and used integrations like this inside the company for years before opening them as Cotlet.

**Is this an official Freshsales integration?**

No, Cotlet is independent of Freshsales. Freshsales's own API is too limited for this work. Cotlet works through your own Freshsales account, the way you use Freshsales in the browser, so you need no partner approval and no developer setup.

**What about client data and GDPR?**

Cotlet is run from the EU and follows the GDPR. Cloud Browsers run in Finland, a Tier 1 country in the ITU Global Cybersecurity Index 2024. Data passes through a call and is not kept after it.

**Can I start with read only?**

Yes. Enable the app for agents as read only, or make the API key read only, and anything that reaches other people waits for your OK unless you switch that off per tool.

**Is it reliable?**

Every Cotlet service is checked every 3 minutes from Europe, North America, Asia and Australia. The live results and any outage are public at status.cotlet.dev.

**How do I stop?**

Press Disable for agents next to Freshsales in your console: your agents lose access at once and you stay signed in. Signing out of Freshsales in the browser works too, and Reset browser deletes the whole profile.

## Is there a Freshsales MCP server on GitHub?

Yes. Community Freshsales MCP servers exist on GitHub, usually maintained by one person. You install one on your own computer, give it your Freshsales API key, and keep it running yourself; you fix it when it stops working. Cotlet hosts the same kind of server for you, and our team keeps it working.

|  | GitHub MCP server | Cotlet |
|---|---|---|
| Setup | Clone the repo, install it, paste your API key and account address, add it to each MCP client | Sign up, sign in to Freshsales once, add one MCP server or API key |
| When Freshsales changes | You or the maintainer update it; an API change breaks it until then | Our team tests it daily and fixes it for you; failed calls are free |
| Your Freshsales access | A personal API key in a file on your computer, readable by any program you run | Your own Cloud Browser in the EU, profile encrypted, only for the apps you enable, disabled for agents in one click |
| Free plan | Needs API access, which Freshsales does not include in Free | Works in the app you are signed in to, so the screens of your plan are the limit |
| Upkeep | You update, monitor and debug it yourself | Nothing to host or update |
| Where it runs | Your computer, while it is on | Hosted: Claude Code, Codex, Cursor, n8n and scripts, also on a schedule |
| Price | Free, paid for with your time | Free 7-day trial, then pay-as-you-go credit packs, no subscription |

### Which one fits you

**Pick Cotlet if**

- you are not a developer, or you do not want to maintain a server
- you need it to keep working when Freshsales changes, without checking it yourself
- your agent or a script should run it on a schedule, also while your computer is off

**Pick an open-source server if**

- you are comfortable installing, updating and fixing it yourself
- you want your sign-in to stay on your own computer
- you only need it now and then, from one MCP client

## How much does the Freshsales API cost?

Free 7-day trial with 2,000 credits, no card needed. After that, the Freshsales API is pay as you go with no limit on apps: Credit packs from $29 for 5,000 credits, one-time, no subscription. A successful call uses 20 to 30 credits (25 for most tools, about $0.10 to $0.15), your Cloud Browser uses 50 credits a day while it has an app enabled for agents, however many apps that is, and an agent driving the browser itself uses 5 credits a minute. Credit packs stay valid for 12 months and stack, so unused credits carry over.

| Credits | Price, one time | Calls at 25 credits | Per 1,000 credits |
|---|---|---|---|
| 5,000 | $29 | 200 | $5.80 |
| 15,000 | $79 | 600 | $5.27 |
| 32,000 | $149 | 1,280 | $4.66 |
| 60,000 | $249 | 2,400 | $4.15 |

Only successful calls use credits; failed calls and timeouts cost nothing. At a balance of 0 calls pause, never a surprise charge. Authenticate with the `Authorization: Bearer` header. [See full pricing](https://cotlet.dev/pricing.md)

## How Cotlet holds your access

Cotlet hosts MCP servers and REST APIs for apps with no usable API. Your agent works in your own Freshsales account.

- **Company details:** Cotlet is run by Take Group sp. z o.o., a company registered in Poland. Its full address and registration numbers are in the Terms of service. [Terms of service](https://cotlet.dev/terms)
- **Your sign-in:** You sign in to Freshsales yourself, in your own Cloud Browser: a Chrome we run for you in the EU, one per app. We never save your password (password saving is off), the profile is stored encrypted with AES-256-GCM, and your agents get Freshsales only after you enable it. When Freshsales signs you out, your agent gives you a link to sign in again. [Security](https://cotlet.dev/security.md)
- **Revoking access:** Press Disable for agents next to Freshsales, sign out of Freshsales in your Cloud Browser, or reset the browser. Every background request is listed in your Background activity. Actions that reach other people wait for your OK unless you switch that off per tool.
- **What we never do:** Store passwords, solve CAPTCHAs or bypass MFA.
- **Freshsales's terms:** You use your own Freshsales account and stay responsible for following Freshsales's terms. Cotlet is independent and not affiliated with Freshsales. [Terms](https://cotlet.dev/terms)
- **Contact:** Questions about the company, security or an app: [contact@cotlet.dev](mailto:contact@cotlet.dev)

## Frequently asked questions

**How do I get access?**

Sign up free, open Freshsales in the console and press Request access. Then you create your API key and connect Freshsales there.

**Do I need to be technical?**

No. You sign in to Freshsales once in your Cloud Browser, a normal Chrome you open from the console, and paste one command into your agent, or one URL into n8n. Your agent can walk you through it. There is no server to install, update or fix.

**Is it safe to connect Freshsales to Cotlet?**

Yes. You sign in to Freshsales yourself, in your own Cloud Browser in the EU, and we never save your password. Your agents only get Freshsales once you enable it, every background request is listed, and the browser profile is stored encrypted with AES-256-GCM, the cipher 1Password uses for its vaults. The AI model never sees a login, posts and messages wait for your OK, and Disable for agents cuts access in one click. Independent scanners grade cotlet.dev A+ on Qualys SSL Labs, securityheaders.com and Mozilla Observatory; live results are on https://cotlet.dev/security.

**Is a hosted server safer than a local one? My Freshsales sign-in would leave my computer.**

On Cotlet you sign in inside your own Cloud Browser, which only you open, and its profile is stored encrypted with AES-256-GCM in the EU. Agents get only the apps you enable, and every background request is listed. A local server keeps your Freshsales cookie in a plain file on your computer, readable by any program you run, and stops when your computer is off.

**Why does Cotlet send requests instead of clicking in my browser?**

To be fast, Cotlet doesn't click through Freshsales's pages. It sends the same requests your browser would, from your browser's IP with its cookies, without opening a window. Freshsales sees the same browser and IP you signed in with, and every request is listed in your Background activity.

**What if someone gets my Cotlet API key?**

The key holds no Freshsales login or cookies, it only asks Cotlet to run a tool. It can call only the apps and tools you gave it, and a read-only key changes nothing. Anything that reaches other people, like posts, comments or messages, waits for your OK in the dashboard by default, so a leaked key cannot post or message as you. When you switch approval off for a scheduled job, give that job its own key limited to that one tool. Every call is in your activity log, and deleting the key ends access at once.

**Why a signed-in browser and not OAuth, like other integration platforms?**

Freshsales offers no OAuth token you can simply grant for these tools: its official API leaves them out or needs a developer app, a plan or an approval first (see the official API section above). That is why Cotlet sets the limits itself: per key, per tool, with your approval before anything reaches other people. Cotlet is run by Take Group sp. z o.o., an EU company (VAT PL6342984273).

**Do I need a paid Freshsales plan?**

No. Cotlet works in the account you are signed in to, so the Free plan can connect. What the Free plan lacks, the tools lack: Freshsales removes rotten deals, Workflows and API access when an account drops to Free, so list_rotten_deals fails there. The official API and Zapier need a paid plan.

**Which tasks can my agent see?**

The ones you own or share. Freshsales shows a task only to its owner and its collaborators, so list_tasks returns your tasks and not the whole team's. A user with restricted access who is added as collaborator can view a task but not edit it.

**What does it leave alone?**

The tools cover deals, contacts, tasks and notes. Pipelines and stage names are read-only, and settings such as the staling age, Workflows and Lost reasons stay in Freshsales. Nothing deletes a record or a note.

**Can my agent post or send messages in Freshsales without asking me?**

No. Every call to create_task, add_note or update_deal_stage waits for your OK by default. For scheduled automations you can switch confirmation off per tool in your dashboard, for example only for approvals. complete_task runs without asking, because it sends nothing to anyone and one call undoes it.

**Can I use the Freshsales API in n8n?**

Yes. Add https://cotlet.dev/mcp/v1 with your API key in n8n's MCP Client node, or call its endpoints under https://cotlet.dev/api/v1/freshsales from the HTTP Request node.

---

Give your AI agents your signed-in browser.

**Product:** [Integrations](https://cotlet.dev/integrations.md) · [Use cases](https://cotlet.dev/use-cases.md) · [How it works](https://cotlet.dev/how-it-works.md) · [Pricing](https://cotlet.dev/pricing.md) · [Security](https://cotlet.dev/security.md)

**Resources:** [Blog](https://cotlet.dev/blog.md) · [API docs](https://cotlet.dev/docs.md) · [Help center](https://cotlet.dev/help.md) · [Changelog](https://cotlet.dev/changelog.md) · [GitHub](https://github.com/cotletdev/cotlet)

**Solutions:** [For developers](https://cotlet.dev/for-developers.md) · [For automation agencies](https://cotlet.dev/for-agencies.md)

**Company:** [About](https://cotlet.dev/about.md) · [AI info: company facts](https://cotlet.dev/ai-info.md) · [Contact](https://cotlet.dev/contact.md)

**Legal:** [Terms of service](https://cotlet.dev/terms) · [Privacy policy](https://cotlet.dev/privacy) · [Refund policy](https://cotlet.dev/refunds) · [Acceptable use](https://cotlet.dev/acceptable-use) · [Cookie policy](https://cotlet.dev/cookies) · [DPA](https://cotlet.dev/dpa) · [Subprocessors](https://cotlet.dev/subprocessors)

**Elsewhere:** [Status page](https://status.cotlet.dev) · [Cotlet on GitHub](https://github.com/cotletdev) · [Cotlet on X](https://x.com/cotletdev) · [Cotlet on LinkedIn](https://www.linkedin.com/company/cotletdev) · [Cotlet on Product Hunt](https://www.producthunt.com/products/cotlet) · [Cotlet on Crunchbase](https://www.crunchbase.com/organization/cotlet) · [Cotlet on SaaSHub](https://www.saashub.com/cotlet)

Cotlet is an independent service. It is not affiliated with, endorsed by or sponsored by any of the products listed on this site. Product names are trademarks of their respective owners.

## For AI agents: sign your user up

Is your user asking you to sign them up for Cotlet? You can do it for them, no account or key needed.

1. Read the fields and their allowed values: GET https://cotlet.dev/api/v1/access-requests
2. Ask the user for each value: email, apps, what you will do with them. If they leave the password to you, generate a strong one and show it to them.
3. Show the user what you will send, then POST it as JSON to https://cotlet.dev/api/v1/access-requests.

One call creates the account and sends the access request; we email the user when access is granted.
