# Get account limits Source: https://docs.reachhunt.ai/api-reference/accounts/get-account-limits /openapi.json get /accounts/{accountId}/limits Returns the sending limits of one account, what it used, and how far its warm-up is. LinkedIn and X accounts return different fields. # Get limits summary Source: https://docs.reachhunt.ai/api-reference/accounts/get-limits-summary /openapi.json get /accounts/limits/summary Returns the sending limits and pace of every connected account, and what they can send together. # List accounts Source: https://docs.reachhunt.ai/api-reference/accounts/list-accounts /openapi.json get /accounts Returns the X and LinkedIn accounts connected to your workspace, newest first. Not paged. # Delete agents Source: https://docs.reachhunt.ai/api-reference/agents/delete-agents /openapi.json delete /agents Deletes AI agents. They stop replying right away. # List agents Source: https://docs.reachhunt.ai/api-reference/agents/list-agents /openapi.json get /agents Returns your AI agents, with how many are in each status. # Pause agent Source: https://docs.reachhunt.ai/api-reference/agents/pause-agent /openapi.json post /agents/{agentId}/pause Stops a live agent from replying until you resume it. # Resume agent Source: https://docs.reachhunt.ai/api-reference/agents/resume-agent /openapi.json post /agents/{agentId}/resume Lets a paused agent reply again. # Get activity summary Source: https://docs.reachhunt.ai/api-reference/analytics/get-activity-summary /openapi.json get /dashboard/summary Returns messages sent, people contacted and replies over a time range, with one point per bucket, and the latest conversations. # Create campaign Source: https://docs.reachhunt.ai/api-reference/campaigns/create-campaign /openapi.json post /campaigns Creates a draft campaign. Start it with Start campaign. # Delete campaigns Source: https://docs.reachhunt.ai/api-reference/campaigns/delete-campaigns /openapi.json delete /campaigns Deletes campaigns. A running campaign is stopped first. # Get campaign Source: https://docs.reachhunt.ai/api-reference/campaigns/get-campaign /openapi.json get /campaigns/{campaignId} Returns one campaign. # Get campaign activity Source: https://docs.reachhunt.ai/api-reference/campaigns/get-campaign-activity /openapi.json get /campaigns/{campaignId}/activity Returns messages, replies and connection requests over time. # Get campaigns overview Source: https://docs.reachhunt.ai/api-reference/campaigns/get-campaigns-overview /openapi.json get /campaigns/overview Returns totals across all campaigns. # List campaign targets Source: https://docs.reachhunt.ai/api-reference/campaigns/list-campaign-targets /openapi.json get /campaigns/{campaignId}/targets Returns the people in a campaign and where each one stands. # List campaigns Source: https://docs.reachhunt.ai/api-reference/campaigns/list-campaigns /openapi.json get /campaigns Returns your campaigns, newest first, with how many are in each status. # Pause campaign Source: https://docs.reachhunt.ai/api-reference/campaigns/pause-campaign /openapi.json post /campaigns/{campaignId}/pause Pauses a running campaign. # Remove campaign targets Source: https://docs.reachhunt.ai/api-reference/campaigns/remove-campaign-targets /openapi.json delete /campaigns/{campaignId}/targets Removes people from a campaign. People already messaged are cancelled instead. # Resume campaign Source: https://docs.reachhunt.ai/api-reference/campaigns/resume-campaign /openapi.json post /campaigns/{campaignId}/resume Resumes a paused campaign. # Start campaign Source: https://docs.reachhunt.ai/api-reference/campaigns/start-campaign /openapi.json post /campaigns/{campaignId}/start Starts a draft campaign. Its targets are worked out now. # Stop campaign Source: https://docs.reachhunt.ai/api-reference/campaigns/stop-campaign /openapi.json post /campaigns/{campaignId}/stop Stops a campaign for good. # Update campaign Source: https://docs.reachhunt.ai/api-reference/campaigns/update-campaign /openapi.json patch /campaigns/{campaignId} Changes a campaign. Send only the fields you change. # Add tag Source: https://docs.reachhunt.ai/api-reference/conversation-details/add-tag /openapi.json post /conversations/{conversationId}/tags Puts a tag on the person in a conversation. # Get assignee Source: https://docs.reachhunt.ai/api-reference/conversation-details/get-assignee /openapi.json get /conversations/{conversationId}/assignee Returns who the conversation is assigned to. # Get note Source: https://docs.reachhunt.ai/api-reference/conversation-details/get-note /openapi.json get /conversations/{conversationId}/note Returns the note on the person in a conversation. # Get value Source: https://docs.reachhunt.ai/api-reference/conversation-details/get-value /openapi.json get /conversations/{conversationId}/valuation Returns the deal value of the person in a conversation. # Remove tag Source: https://docs.reachhunt.ai/api-reference/conversation-details/remove-tag /openapi.json delete /conversations/{conversationId}/tags/{tagId} Takes a tag off the person in a conversation. # Set assignee Source: https://docs.reachhunt.ai/api-reference/conversation-details/set-assignee /openapi.json put /conversations/{conversationId}/assignee Assigns the conversation to a teammate from List assignees, or clears it. # Set note Source: https://docs.reachhunt.ai/api-reference/conversation-details/set-note /openapi.json put /conversations/{conversationId}/note Replaces the note. An empty string clears it. # Set status Source: https://docs.reachhunt.ai/api-reference/conversation-details/set-status /openapi.json put /conversations/{conversationId}/status Puts the person in a conversation in a status, or clears it. # Set value Source: https://docs.reachhunt.ai/api-reference/conversation-details/set-value /openapi.json put /conversations/{conversationId}/valuation Sets the deal value. `null` clears it. # Answer request Source: https://docs.reachhunt.ai/api-reference/conversations/answer-request /openapi.json post /requests/{requestId}/action Accepts, ignores, withdraws or deletes a request. Use one of the request's `actions`. # Close conversation Source: https://docs.reachhunt.ai/api-reference/conversations/close-conversation /openapi.json post /conversations/{conversationId}/close Closes a conversation. It leaves the open list. # Delete conversation Source: https://docs.reachhunt.ai/api-reference/conversations/delete-conversation /openapi.json delete /conversations/{conversationId} Deletes a conversation and its messages. # Find or start conversation Source: https://docs.reachhunt.ai/api-reference/conversations/find-or-start-conversation /openapi.json post /conversations/get-or-create Returns the conversation between an account and a person. When there is none yet, a draft is created that becomes a real conversation once you send the first message. # Get conversation Source: https://docs.reachhunt.ai/api-reference/conversations/get-conversation /openapi.json get /conversations/{conversationId} Returns one conversation. # List conversations Source: https://docs.reachhunt.ai/api-reference/conversations/list-conversations /openapi.json get /conversations Returns the one-to-one conversations in your workspace, across every connected account or for one. Open conversations are returned unless you change `scope`. Paged with a cursor. # List requests Source: https://docs.reachhunt.ai/api-reference/conversations/list-requests /openapi.json get /requests Returns message requests and connection invitations waiting for an answer on one account. # Mark as read Source: https://docs.reachhunt.ai/api-reference/conversations/mark-as-read /openapi.json post /conversations/{conversationId}/read Marks a conversation as read. # Mark as unread Source: https://docs.reachhunt.ai/api-reference/conversations/mark-as-unread /openapi.json post /conversations/{conversationId}/unread Marks a conversation as unread. # Reopen conversation Source: https://docs.reachhunt.ai/api-reference/conversations/reopen-conversation /openapi.json post /conversations/{conversationId}/open Reopens a closed conversation. # Get credits Source: https://docs.reachhunt.ai/api-reference/credits/get-credits /openapi.json get /credits/info Returns the AI credits of the workspace: what the plan gives, what you bought and what is used. # List credit usage Source: https://docs.reachhunt.ai/api-reference/credits/list-credit-usage /openapi.json get /credits/operations Returns every use of AI credits, newest first. # Add internal note Source: https://docs.reachhunt.ai/api-reference/internal-notes/add-internal-note /openapi.json post /conversations/{conversationId}/internal-notes Adds a note for your team. # Delete internal note Source: https://docs.reachhunt.ai/api-reference/internal-notes/delete-internal-note /openapi.json delete /conversations/{conversationId}/internal-notes/{noteId} Deletes a note. # List internal notes Source: https://docs.reachhunt.ai/api-reference/internal-notes/list-internal-notes /openapi.json get /conversations/{conversationId}/internal-notes Returns the notes your team left on a conversation. The other person never sees them. # Add leads Source: https://docs.reachhunt.ai/api-reference/lead-lists/add-leads /openapi.json post /leads/{leadListId}/prospects Adds people to a lead list by their network ID. # Create lead list Source: https://docs.reachhunt.ai/api-reference/lead-lists/create-lead-list /openapi.json post /leads Creates an empty lead list. Fill it with Add leads or Start import. # Delete lead lists Source: https://docs.reachhunt.ai/api-reference/lead-lists/delete-lead-lists /openapi.json delete /leads Deletes lead lists and the people in them. # Get lead list Source: https://docs.reachhunt.ai/api-reference/lead-lists/get-lead-list /openapi.json get /leads/{leadListId} Returns one lead list with its imports. # List imports Source: https://docs.reachhunt.ai/api-reference/lead-lists/list-imports /openapi.json get /leads/{leadListId}/jobs Returns the imports of a lead list. # List lead lists Source: https://docs.reachhunt.ai/api-reference/lead-lists/list-lead-lists /openapi.json get /leads Returns the lead lists in your workspace, newest first. The read-only system lists come back in `systemLists` on the first page. # List leads Source: https://docs.reachhunt.ai/api-reference/lead-lists/list-leads /openapi.json get /leads/{leadListId}/prospects Returns the people in a lead list. # Pause import Source: https://docs.reachhunt.ai/api-reference/lead-lists/pause-import /openapi.json post /leads/{leadListId}/jobs/{jobId}/pause Pauses one import. # Remove leads Source: https://docs.reachhunt.ai/api-reference/lead-lists/remove-leads /openapi.json delete /leads/{leadListId}/prospects Removes people from a lead list. # Rename lead list Source: https://docs.reachhunt.ai/api-reference/lead-lists/rename-lead-list /openapi.json patch /leads/{leadListId} Renames a lead list. # Resume import Source: https://docs.reachhunt.ai/api-reference/lead-lists/resume-import /openapi.json post /leads/{leadListId}/jobs/{jobId}/resume Resumes one import. # Start import Source: https://docs.reachhunt.ai/api-reference/lead-lists/start-import /openapi.json post /leads/{leadListId}/import Starts filling a lead list from a source, such as an account's followers, a post's likes or a LinkedIn search. The import runs in the background. # Stop import Source: https://docs.reachhunt.ai/api-reference/lead-lists/stop-import /openapi.json post /leads/{leadListId}/jobs/{jobId}/stop Stops one import. # Get lead note Source: https://docs.reachhunt.ai/api-reference/leads/get-lead-note /openapi.json get /leads/prospects/{prospectId}/note Returns the note on a lead. # Get lead value Source: https://docs.reachhunt.ai/api-reference/leads/get-lead-value /openapi.json get /leads/prospects/{prospectId}/valuation Returns the deal value of a lead. # Set lead note Source: https://docs.reachhunt.ai/api-reference/leads/set-lead-note /openapi.json put /leads/prospects/{prospectId}/note Replaces the note on a lead. An empty string clears it. # Set lead status Source: https://docs.reachhunt.ai/api-reference/leads/set-lead-status /openapi.json post /leads/prospects/status Puts several leads in one status, or clears it. # Set lead value Source: https://docs.reachhunt.ai/api-reference/leads/set-lead-value /openapi.json put /leads/prospects/{prospectId}/valuation Sets the deal value of a lead. `null` clears it. # Update lead tags Source: https://docs.reachhunt.ai/api-reference/leads/update-lead-tags /openapi.json post /leads/prospects/labels Adds and removes tags on several leads. # Add reaction Source: https://docs.reachhunt.ai/api-reference/messages/add-reaction /openapi.json post /conversations/{conversationId}/messages/{messageId}/reactions Reacts to a message with an emoji. # Delete message Source: https://docs.reachhunt.ai/api-reference/messages/delete-message /openapi.json delete /conversations/{conversationId}/messages/{messageId} Deletes a message, for you or for everyone. # Edit message Source: https://docs.reachhunt.ai/api-reference/messages/edit-message /openapi.json patch /conversations/{conversationId}/messages/{messageId} Edits a message you sent. LinkedIn allows it for a short time after sending. # List messages Source: https://docs.reachhunt.ai/api-reference/messages/list-messages /openapi.json get /conversations/{conversationId}/messages Returns the messages of a conversation, newest first. Paged with a cursor. # Remove reaction Source: https://docs.reachhunt.ai/api-reference/messages/remove-reaction /openapi.json delete /conversations/{conversationId}/messages/{messageId}/reactions Removes your reaction from a message. # Send message Source: https://docs.reachhunt.ai/api-reference/messages/send-message /openapi.json post /conversations/{conversationId}/messages Sends a message in a conversation, or the first message of a draft from Find or start conversation. Send text, a file, or both: use JSON for text, or `multipart/form-data` to attach a file. # Cancel scheduled message Source: https://docs.reachhunt.ai/api-reference/scheduled-messages/cancel-scheduled-message /openapi.json delete /scheduled-messages/{scheduledMessageId} Cancels a scheduled message. # List scheduled messages Source: https://docs.reachhunt.ai/api-reference/scheduled-messages/list-scheduled-messages /openapi.json get /conversations/{conversationId}/scheduled-messages Returns the messages set to send later in a conversation. # Schedule message Source: https://docs.reachhunt.ai/api-reference/scheduled-messages/schedule-message /openapi.json post /conversations/{conversationId}/scheduled-messages Sets a message to send later. # Send now Source: https://docs.reachhunt.ai/api-reference/scheduled-messages/send-now /openapi.json post /scheduled-messages/{scheduledMessageId}/send-now Sends a scheduled message right away. # Update scheduled message Source: https://docs.reachhunt.ai/api-reference/scheduled-messages/update-scheduled-message /openapi.json patch /scheduled-messages/{scheduledMessageId} Changes the text or the time. # Create status Source: https://docs.reachhunt.ai/api-reference/statuses/create-status /openapi.json post /statuses Creates a status. Pass `accountId` and `conversationId` to put it on a conversation too. # Delete status Source: https://docs.reachhunt.ai/api-reference/statuses/delete-status /openapi.json delete /statuses/{statusId} Deletes a status and takes it off every conversation. # List statuses Source: https://docs.reachhunt.ai/api-reference/statuses/list-statuses /openapi.json get /statuses Returns every status in your workspace, in the order they were created. Not paged. # Update status Source: https://docs.reachhunt.ai/api-reference/statuses/update-status /openapi.json patch /statuses/{statusId} Renames or recolors a status. Send at least one of `label` and `color`. # Create tag Source: https://docs.reachhunt.ai/api-reference/tags/create-tag /openapi.json post /tags Creates a tag. Pass `accountId` and `conversationId` to put it on a conversation too. # Delete tag Source: https://docs.reachhunt.ai/api-reference/tags/delete-tag /openapi.json delete /tags/{tagId} Deletes a tag and takes it off every conversation. # List tags Source: https://docs.reachhunt.ai/api-reference/tags/list-tags /openapi.json get /tags Returns every tag in your workspace, in the order they were created. Not paged. # Update tag Source: https://docs.reachhunt.ai/api-reference/tags/update-tag /openapi.json patch /tags/{tagId} Renames or recolors a tag. Send at least one of `label` and `color`. # Create template Source: https://docs.reachhunt.ai/api-reference/templates/create-template /openapi.json post /templates Saves a message to reuse. # Delete template Source: https://docs.reachhunt.ai/api-reference/templates/delete-template /openapi.json delete /templates/{id} Deletes a template. # Duplicate template Source: https://docs.reachhunt.ai/api-reference/templates/duplicate-template /openapi.json post /templates/{id}/duplicate Makes a copy of a template. # List templates Source: https://docs.reachhunt.ai/api-reference/templates/list-templates /openapi.json get /templates Returns your saved messages. # Update template Source: https://docs.reachhunt.ai/api-reference/templates/update-template /openapi.json patch /templates/{id} Changes a template. Send only the fields you change. # Get workspace Source: https://docs.reachhunt.ai/api-reference/workspaces/get-workspace /openapi.json get /workspace/info/{workspaceId} Returns one workspace with its plan. # List assignees Source: https://docs.reachhunt.ai/api-reference/workspaces/list-assignees /openapi.json get /workspace/assignees Returns the people a conversation can be assigned to. # List members Source: https://docs.reachhunt.ai/api-reference/workspaces/list-members /openapi.json get /workspace/members Returns the people in the workspace, invited ones included. Not paged. # List workspaces Source: https://docs.reachhunt.ai/api-reference/workspaces/list-workspaces /openapi.json get /workspace/list Returns the workspaces you can reach, with counts. `activeId` is the workspace the API key belongs to. # Authentication Source: https://docs.reachhunt.ai/developer-api/authentication Create an API key and use it to call the API Every request carries an API key. The key belongs to your workspace, so no path or parameter names one. ## Create an API key **1. Open the API settings** In ReachHunt, open [**Settings → API**](https://app.reachhunt.ai/settings/api). **2. Create the key** Select **New API key**, give it a name you will recognize, such as `Zapier production`, and select **Create key**. A name can be up to 40 characters. **3. Copy it now** The key is shown once. Copy it and store it somewhere safe. If you lose it, delete the key and create a new one. You need full access to **Developer** to create, rename or delete keys. ## Use the key Send it in the `Authorization` header of every request: ```txt theme={"system"} Authorization: Bearer YOUR_API_KEY ``` ```bash cURL theme={"system"} curl "https://api.reachhunt.ai/api/v1/tags" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## What a key can do A key belongs to one workspace and acts as the workspace owner, with full access to it. To work with another workspace, create a key in that workspace. A key cannot change who has access, so these are refused: * Creating, renaming or deleting API keys. * Billing and payments. * Your own profile and sign-in. * Creating, renaming, switching or deleting workspaces, and managing members and invites. Reading them is allowed. A refused request returns `status: false` with the error `API keys cannot be used for this request`. ## Failures | Response | Cause | | - | - | | `401` | The header is missing, or the key is not valid or was deleted | | `402` | The workspace has no active plan, or its trial has ended | | `200` with `status: false` | The key cannot be used for this request, or the request itself was refused. Read `error` | All of them come back in the usual [response envelope](/developer-api/response-format) with `status` set to `false`. See [Errors](/developer-api/errors) for every status code. ## Keys made by integrations When you connect an AI app through the [MCP server](/integrations/mcp-server), ReachHunt creates a key for it, named after the app with `(MCP)` after it. Delete that key to disconnect the app. ## Rotate or revoke a key Create a new key, switch your integration to it, then delete the old one in [**Settings → API**](https://app.reachhunt.ai/settings/api). A deleted key stops working right away. Keys are also revoked when the workspace is deleted. # Build with AI coding agents Source: https://docs.reachhunt.ai/developer-api/build-with-ai Connect Claude Code, Cursor, Codex and other coding agents to ReachHunt and its docs Your coding agent can build on ReachHunt for you. Give it two MCP servers: one to work in your workspace, and one to search these docs. Every page is also available as plain markdown, so the agent reads the same docs you do. ## What your agent gets | MCP server | URL | What it does | Sign-in | | - | - | - | - | | ReachHunt | `https://mcp.reachhunt.ai/mcp` | Reads and acts in your workspace: inbox, messages, lead lists, campaigns and agents | ReachHunt sign-in | | ReachHunt docs | `https://docs.reachhunt.ai/mcp` | Searches these docs and reads full pages | None | Both servers use Streamable HTTP over HTTPS. You don't run anything locally. ## Connect your agent **Claude Code** Run these in your terminal: ```bash theme={"system"} claude mcp add --transport http reachhunt https://mcp.reachhunt.ai/mcp claude mcp add --transport http reachhunt-docs https://docs.reachhunt.ai/mcp ``` Start Claude Code, type `/mcp`, choose `reachhunt` and select **Authenticate**. A ReachHunt page opens in your browser. Choose your workspace and select **Connect**. **Cursor** Paste this into `~/.cursor/mcp.json`, or `.cursor/mcp.json` inside one project: ```json mcp.json theme={"system"} { "mcpServers": { "reachhunt": { "url": "https://mcp.reachhunt.ai/mcp" }, "reachhunt-docs": { "url": "https://docs.reachhunt.ai/mcp" } } } ``` In **Cursor Settings**, open **MCP** and select the sign-in button next to `reachhunt`. **VS Code / GitHub Copilot** Paste this into `.vscode/mcp.json` in your project: ```json .vscode/mcp.json theme={"system"} { "servers": { "reachhunt": { "type": "http", "url": "https://mcp.reachhunt.ai/mcp" }, "reachhunt-docs": { "type": "http", "url": "https://docs.reachhunt.ai/mcp" } } } ``` Select **Start** above `reachhunt` in the file, then sign in when VS Code asks. **Codex CLI** Run these in your terminal: ```bash theme={"system"} codex mcp add reachhunt --url https://mcp.reachhunt.ai/mcp codex mcp add reachhunt-docs --url https://docs.reachhunt.ai/mcp codex mcp login reachhunt ``` **Gemini CLI** Run these in your terminal: ```bash theme={"system"} gemini mcp add --transport http reachhunt https://mcp.reachhunt.ai/mcp gemini mcp add --transport http reachhunt-docs https://docs.reachhunt.ai/mcp ``` Start Gemini CLI and type `/mcp auth reachhunt` to sign in. **Windsurf** Paste this into `~/.codeium/windsurf/mcp_config.json`: ```json mcp_config.json theme={"system"} { "mcpServers": { "reachhunt": { "serverUrl": "https://mcp.reachhunt.ai/mcp" }, "reachhunt-docs": { "serverUrl": "https://docs.reachhunt.ai/mcp" } } } ``` For Claude, ChatGPT and other chat apps, follow [MCP server](/integrations/mcp-server). ## Docs built for agents | Resource | What it gives your agent | | - | - | | [`llms.txt`](https://docs.reachhunt.ai/llms.txt) | An index of every page, with a one-line summary and link | | [`llms-full.txt`](https://docs.reachhunt.ai/llms-full.txt) | Every page in one file, ready to paste into a prompt or index | | `.md` on any page | Add `.md` to a page URL to get its markdown, for example [`/developer-api/authentication.md`](https://docs.reachhunt.ai/developer-api/authentication.md) | | Page menu | Open the menu at the top of any page to copy it as markdown, or open it in ChatGPT, Claude, Perplexity, Cursor or VS Code | ## Try this prompt Paste this into your agent after you connect both servers: ```txt theme={"system"} Using the ReachHunt docs MCP, build a small Node.js server that receives ReachHunt webhooks. When a campaign.lead_replied event arrives, check the X-Webhook-Secret header, then post the lead's name and reply to Slack. ``` The agent looks up the event payload and the webhook guide in the docs, writes the handler, and checks the secret header with a constant-time comparison. ## Tell your agent These are the details agents most often get wrong: * **Every response has the same envelope.** Read `data` when `status` is `true`, and `error` when it is `false`. See [Response format](/developer-api/response-format). * **Items carry a `platform`.** It is `x` or `linkedin`. Many fields differ between the two. * **Sending limits apply per account.** The app, campaigns and the API share them. Check them with [Get account limits](/api-reference/accounts/get-account-limits) before you send in bulk. See [Rate limits](/developer-api/rate-limits). * **ReachHunt doesn't sign webhooks.** Add a secret header and compare it in constant time. See [Receive webhooks](/webhooks/receiving). > [!WARNING] > > The ReachHunt MCP server acts as the workspace owner and sends real messages from your connected accounts. Try new agent code on a test workspace first, and never commit an API key. ## Next steps > **[MCP server](/integrations/mcp-server)** > > What the ReachHunt MCP server can do, and its limits. > **[Quickstart](/developer-api/quickstart)** > > Make your first API request. > **[Webhooks](/webhooks/overview)** > > Get events sent to your server as they happen. # Core concepts Source: https://docs.reachhunt.ai/developer-api/core-concepts How your workspace, accounts, conversations, leads and campaigns fit together The API works on one workspace: the one your API key belongs to. Everything in it starts from the X and LinkedIn accounts you connect. ## How it fits together ```txt theme={"system"} Workspace ├── Accounts your connected X and LinkedIn accounts │ ├── Conversations one per account and person │ │ └── Messages │ └── Requests message requests and invitations waiting for an answer ├── Lead lists people you collect from X and LinkedIn │ └── Leads ├── Campaigns message sequences sent from accounts to lead lists ├── AI agents reply in conversations for the accounts they are assigned to ├── Templates saved messages └── Tags and statuses labels and pipeline stages for people ``` ## Workspace Your API key decides the workspace, so no path or parameter names one. To work with another workspace, create a key in that workspace. Your teammates are its members, and the ones you can assign conversations to are its assignees. ## Accounts An account is an X or LinkedIn account connected to your workspace. You connect accounts in the ReachHunt app with the [ReachHunt extension](https://chromewebstore.google.com/detail/reachhunt/fkcjcmlojmeebgpgkmlmmmeakbhdoffe), not through the API. An account's `status` is `connected`, or `needs_reauth` when it must be connected again in ReachHunt before it can send. Each account has its own [sending limits](/developer-api/rate-limits). ## Conversations and messages A conversation is between one connected account and one person. Its ID is `conversationId`, and most conversation and message calls also take the `accountId`. URL-encode the conversation ID in paths, because X IDs contain `:`. [Find or start conversation](/api-reference/conversations/find-or-start-conversation) returns the conversation with a person. When there is none yet, it creates a draft that becomes a real conversation when you send the first message. Each message has `fromMe`, which is `true` when your account sent it. `sentBy` says who on your side sent it: a teammate, a campaign or an AI agent. Requests are message requests and connection invitations waiting for an answer on one account. ## Leads and lead lists A lead list collects people from one network, so it has a `platform`. Imports into a list run as jobs that you can follow, pause or stop. A lead is a person in your lead lists. Request bodies call its ID `prospectId`. A person's tags, status, note and deal value belong to the person, not to one conversation or list. Set them from the conversation or from the lead, and both show the change. ## Campaigns A campaign sends a sequence of messages from one or more accounts to the people in its lead lists. It starts as a `draft`, runs as `running`, can be `paused` and resumed, and ends as `completed` or `stopped`. Each person a campaign reaches is one of its targets. ## AI agents An AI agent replies in conversations for the accounts it is assigned to. Through the API you can list, pause, resume and delete agents. You create and train them in the ReachHunt app. ## Tags and statuses Tags are labels, and a person can have many. Statuses are pipeline stages, and a person is in one at most, shown by `statusId`. Create both in the app or through the API, then set them on people. ## IDs | ID | What it is | | - | - | | `id`, `accountId`, `conversationId`, `prospectId` and the other IDs | ReachHunt's own IDs, always strings. Use them in paths and request bodies | | `platformId` | The ID the network gives a person or an account. It always comes with a `platform` | ## Platforms `platform` is `x` or `linkedin`. Some fields only apply on one network. For example, a profile's `headline` and `connections` are LinkedIn only, and `tweets` is X only. A field that doesn't apply is `null`. See [Response format](/developer-api/response-format) for the conventions every response follows. # Errors Source: https://docs.reachhunt.ai/developer-api/errors Status codes, error messages and what to do about them Every error comes back in the [response envelope](/developer-api/response-format) with `status` set to `false` and a message in `error`. Messages are written for people, so you can show them as they are. ```json theme={"system"} { "status": false, "data": null, "error": "Add at least one lead list" } ``` ## Status codes Errors the API handles itself come back with HTTP `200`. Read `status` on every response, not only the HTTP code. | HTTP | When | What to do | | - | - | - | | `200` with `status: false` | The request was refused: a field is wrong, something wasn't found, or the action doesn't fit the item's current state | Read `error` and fix the request. Sending it again unchanged gives the same error | | `401` | The API key is missing, not valid or was deleted | Check the `Authorization` header, or [create a new key](/developer-api/authentication) | | `402` | The workspace has no active plan, or its trial has ended | Renew the plan in ReachHunt | | `429` | A connected account reached one of its sending limits | Wait for the limit to reset, or send from another account. See [Rate limits](/developer-api/rate-limits) | | `500` | Something failed on our side | Try again after a short wait | ## Common messages | `error` | What it means | | - | - | | `API keys cannot be used for this request` | The endpoint changes access or billing, which keys can't do. See [what a key can do](/developer-api/authentication#what-a-key-can-do) | | `Your free trial has ended. Pick a plan to continue.` | Comes with `402` | | `This workspace has no active plan. Pick a plan to continue.` | Comes with `402` | | `limit must be a whole number from 1 to 100` | A paged list got a `limit` outside its range | | `Conversation not found`, `Lead list not found`, `Lead not found`, `Message not found` | The ID is wrong, or it belongs to another workspace | | `Weekly limit of 100 connection requests reached on @jane-doe` | An example of a `429`. The message names the limit and the account | ## Campaigns ### Starting a campaign [Start campaign](/api-reference/campaigns/start-campaign) checks these in order and stops at the first one that fails: | `error` | Fix | | - | - | | `Add at least one lead list` | Add a lead list to the campaign's audience | | `Write at least one message` | Add a message step to the sequence | | `Every message step needs text` | Fill in each message step | | `Open at least one day on the schedule` | Turn on at least one day in the sending schedule | | `Connect an account for this campaign, or pick one that is still connected` | Pick an account whose `status` is `connected` | | `The selected lists resolved to nobody to message` | Change the audience so it includes at least one person | ### Editing a campaign What you can change depends on the campaign's status: | Status | What you can change | | - | - | | `draft` | Everything | | `running` or `paused` | Everything except the audience, because its people are already queued | | `completed` or `stopped` | Only the name and description | A change that doesn't fit the status is refused with a message that names the status, such as `A running campaign keeps the audience it started with — its people are already queued` or `A completed campaign can only be renamed`. ## Retrying * Retry `500` errors and network failures after a short wait, and wait longer each time. * Don't retry a `200` with `status: false`, a `401` or a `402` until you fix the cause. * For a `429`, wait until the account's limit resets. [Get account limits](/api-reference/accounts/get-account-limits) shows what is left. * Before you retry a message that timed out, list the conversation's messages. The first attempt may have been sent. # Overview Source: https://docs.reachhunt.ai/developer-api/introduction The API for your ReachHunt workspace The ReachHunt API gives your own apps and scripts programmatic access to your workspace: accounts, conversations, messages, lead lists, campaigns, tags and statuses. ReachHunt works on X and LinkedIn, so every item carries a `platform` of `x` or `linkedin`. > [!TIP] > > Working in Claude, ChatGPT or Cursor? Connect the [MCP server](/integrations/mcp-server) and use ReachHunt without writing code. ## What you can build > **[Sync your CRM](/webhooks/overview)** > > Send replies, status changes and deal values to your own CRM as they happen. > **[Alert your team](/webhooks/events/campaign-lead-replied)** > > Post to Slack or email when a lead replies to a campaign. > **[Reply with your own AI](/webhooks/events/message-received)** > > Get each new message as it arrives, and answer it with your own model. > **[Run outreach from your app](/api-reference/campaigns/list-campaigns)** > > Build lead lists and start campaigns from your own product. ## Base URL ```txt theme={"system"} https://api.reachhunt.ai/api/v1 ``` ## Make your first request [Create an API key](/developer-api/authentication), then list your connected accounts: ```bash cURL theme={"system"} curl "https://api.reachhunt.ai/api/v1/accounts" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Every response uses the same envelope: ```json theme={"system"} { "status": true, "data": [ { "id": "4f1c9a2e-6b7d-4c3a-9e51-0a8b7c6d5e4f", "platform": "x", "handle": "acmecorp", "status": "connected" } ], "error": null } ``` The response is shortened here. [List accounts](/api-reference/accounts/list-accounts) shows every field. ## Next steps > **[Quick start](/developer-api/quickstart)** > > Send your first DM in five minutes. > **[Core concepts](/developer-api/core-concepts)** > > How accounts, conversations, leads and campaigns fit together. > **[Webhooks](/webhooks/overview)** > > Get events sent to your server as they happen. > **[Errors](/developer-api/errors)** > > What each status code and message means. ## Endpoints > **[Workspaces](/api-reference/workspaces/list-workspaces)** > > Your workspace, its members and who can be assigned. > **[Accounts](/api-reference/accounts/list-accounts)** > > Connected X and LinkedIn accounts and their sending limits. > **[Campaigns](/api-reference/campaigns/list-campaigns)** > > Create, start and follow outreach campaigns. > **[Lead lists](/api-reference/lead-lists/list-lead-lists)** > > Collect people from X and LinkedIn, and import them. > **[Conversations](/api-reference/conversations/list-conversations)** > > Your inbox, message requests and each person's details. > **[Messages](/api-reference/messages/list-messages)** > > Read, send, edit and react to messages. > **[Templates](/api-reference/templates/list-templates)** > > Saved messages you can reuse. > **[Analytics](/api-reference/analytics/get-activity-summary)** > > Messages, contacts and replies over time. # Quick start Source: https://docs.reachhunt.ai/developer-api/quickstart Send your first DM through the API in five minutes This guide sends a DM from one of your connected accounts to a lead, then reads the reply. ## Before you start * A connected X or LinkedIn account in your workspace. * A lead list with at least one lead. * An API key. See [Authentication](/developer-api/authentication). Save the key in your terminal so the commands below can use it: ```bash theme={"system"} export REACHHUNT_API_KEY="YOUR_API_KEY" ``` ## Send your first DM **1. Pick the account to send from** List your connected accounts: ```bash theme={"system"} curl "https://api.reachhunt.ai/api/v1/accounts" \ -H "Authorization: Bearer $REACHHUNT_API_KEY" ``` Keep the `id` of an account whose `status` is `connected`: ```json theme={"system"} { "status": true, "data": [ { "id": "4f1c9a2e-6b7d-4c3a-9e51-0a8b7c6d5e4f", "platform": "x", "handle": "acmecorp", "status": "connected" } ], "error": null } ``` **2. Pick a lead** List your lead lists, then the leads in one of them: ```bash theme={"system"} curl "https://api.reachhunt.ai/api/v1/leads" \ -H "Authorization: Bearer $REACHHUNT_API_KEY" curl "https://api.reachhunt.ai/api/v1/leads/LEAD_LIST_ID/prospects" \ -H "Authorization: Bearer $REACHHUNT_API_KEY" ``` Keep the `id` of a lead on the same network as your account. **3. Find or start the conversation** ```bash theme={"system"} curl -X POST "https://api.reachhunt.ai/api/v1/conversations/get-or-create" \ -H "Authorization: Bearer $REACHHUNT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"accountId": "ACCOUNT_ID", "prospectId": "LEAD_ID"}' ``` Keep `conversation.conversationId`. If you have never messaged this person, ReachHunt creates a draft that becomes a real conversation when you send the first message. Check `canSend` before you send. When it is `false`, `blockedReason` says why, such as `peer_unreachable`. **4. Send the message** ```bash theme={"system"} curl -X POST "https://api.reachhunt.ai/api/v1/conversations/CONVERSATION_ID/messages" \ -H "Authorization: Bearer $REACHHUNT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"accountId": "ACCOUNT_ID", "text": "Hi Jane, loved your post on outbound. Open to a quick chat?"}' ``` URL-encode the conversation ID in the path. X conversation IDs contain `:`, which becomes `%3A`. The response has the new `messageId`. **5. Read the reply** ```bash theme={"system"} curl "https://api.reachhunt.ai/api/v1/conversations/CONVERSATION_ID/messages?accountId=ACCOUNT_ID" \ -H "Authorization: Bearer $REACHHUNT_API_KEY" ``` Messages come newest first. `fromMe` is `false` on the messages the lead sent. > [!TIP] > > Instead of checking for replies, add a webhook for `message.received`. ReachHunt sends each new message to your server as it arrives. ## Next steps > **[Core concepts](/developer-api/core-concepts)** > > How accounts, conversations, leads and campaigns fit together. > **[Receiving webhooks](/webhooks/receiving)** > > Get replies and other events on your server. > **[Errors](/developer-api/errors)** > > What each status code and message means. > **[Rate limits](/developer-api/rate-limits)** > > How much each account can send. # Rate limits Source: https://docs.reachhunt.ai/developer-api/rate-limits The sending limits that keep your X and LinkedIn accounts safe ReachHunt limits what each connected account does, so it stays within what X and LinkedIn allow. The limits apply per account, not per API key. Campaigns, the app and the API all count toward the same limits. ## What counts The limits cover actions that reach people, such as direct messages, message requests, InMails and connection requests. | Network | Limits | | - | - | | LinkedIn | A weekly limit for each of connection requests, message requests, InMails and direct messages, spread over the week as a daily allowance | | X | A daily limit on direct messages | ## Warm-up A newly connected account starts with lower limits that rise step by step. The account's `warmup` shows how far it is: `day` of `totalDays`, and `progressPercent`. The warm-up `speed` is `fast`, `medium` or `slow`. ## Pauses ReachHunt pauses an account when X or LinkedIn pushes back, for example when LinkedIn rate-limits it or shows a security challenge, or when X blocks sending. The account's `throttledUntil` shows when sending starts again. It is `null` when the account isn't paused. On LinkedIn, the connection request limit also follows your acceptance rate. When few people accept, the limit shrinks. `acceptance.limitPercent` shows how much of the limit is in use, from 0 to 100. ## Check an account's limits [Get account limits](/api-reference/accounts/get-account-limits) returns an account's limits, what it used and what is left: ```bash theme={"system"} curl "https://api.reachhunt.ai/api/v1/accounts/ACCOUNT_ID/limits" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ```json theme={"system"} { "status": true, "data": { "accountId": "4f1c9a2e-6b7d-4c3a-9e51-0a8b7c6d5e4f", "handle": "jane-doe", "platform": "linkedin", "effective": { "connection_request": { "weekly": 80, "dailyAllowance": 16, "usedToday": 4, "usedWeek": 31, "remainingToday": 12, "remainingWeek": 49 } }, "throttle": null, "acceptance": { "invited": 120, "accepted": 42, "ratePercent": 35, "limitPercent": 100 } }, "error": null } ``` The response is shortened here. LinkedIn and X accounts return different fields. To see every account at once, with what they can send together, use [Get limits summary](/api-reference/accounts/get-limits-summary). ## When an account reaches a limit The request returns HTTP `429` with `status: false`. The message names the limit and the account: ```json theme={"system"} { "status": false, "data": null, "error": "Weekly limit of 100 connection requests reached on @jane-doe" } ``` A daily allowance reads the same way, for example `Today's allowance of 16 connection requests reached on @jane-doe`. Wait until the limit resets, or send from another account. Campaigns don't need any action: they wait and carry on when the account has room again. # Response format Source: https://docs.reachhunt.ai/developer-api/response-format The envelope, conventions and pagination used by every endpoint ## The envelope Every response is JSON with the same three fields. ```json Success theme={"system"} { "status": true, "data": { "tags": [] }, "error": null } ``` ```json Error theme={"system"} { "status": false, "data": null, "error": "Key name is required" } ``` | Field | Meaning | | - | - | | `status` | `true` when the request worked, `false` when it did not | | `data` | The result, or `null` on an error | | `error` | A message you can show to a person, or `null` on success | ## Check `status`, not only the HTTP code Errors the API handles itself, such as an invalid parameter or something that was not found, come back with HTTP `200` and `status` set to `false`. Read `status` on every response. See [Errors](/developer-api/errors) for every status code and the messages you'll see. ## Conventions * Field names are camelCase and IDs are strings. * Timestamps are ISO 8601 in UTC, such as `2026-10-17T14:05:00.000Z`. * A value that does not apply is `null`. Every documented field is always present. * `platform` is `x` or `linkedin`. A `platformId` is the ID the network gives the person and always comes with a `platform`. ## Pagination Lists that can grow long are paged in one of two ways. Both take `limit`, from 1 to 100, and return 50 items when you leave it out. A `limit` outside that range is an error. **Cursor** Used for conversations, messages and requests. The response has `items` and `nextCursor`, and conversations and requests also return `total`. Pass `nextCursor` back as `cursor`, with the same filters, to read the next page. `nextCursor` is `null` on the last page. A cursor only works with the filters it was issued for. If you change a filter, start again without a cursor. **Page** Used for lead lists, leads, campaigns, campaign targets and templates. The response has `items`, `page`, `limit`, `total` and `totalPages`. Pass `page`, starting at 1, to read another page. Short lists, such as tags and statuses, are not paged. They return everything. # Your first campaign Source: https://docs.reachhunt.ai/get-started/first-campaign Send your first DM campaign in a few minutes You need a connected X or LinkedIn account. See [Set up ReachHunt](/get-started/set-up). 1. Build a lead list. Open [**Leads**](https://app.reachhunt.ai/leads), select **New list**, name it and pick X or LinkedIn. Then add the people you want to message, for example someone's followers. 2. Open [**Campaigns**](https://app.reachhunt.ai/campaigns) and select **New campaign**. Enter a campaign name and pick the network. 3. Choose your lead list. 4. Write your first DM and any follow-ups. 5. Pick the days and hours to send. 6. Choose the accounts to send from, then select [**Launch campaign**](https://app.reachhunt.ai/campaigns). Replies land in [**Messages**](https://app.reachhunt.ai/chat), your inbox for every connected account. Next: [Plans and credits](/get-started/plans). # Plans and credits Source: https://docs.reachhunt.ai/get-started/plans What each plan costs and includes, and how credits work ReachHunt has three plans. You pay per connected account, not per seat, and every plan includes both networks, unlimited campaigns and unlimited teammates. * **Growth: \$35 per account a month**, or \$28 per account a month when you pay yearly. For founders and sales teams. It includes LinkedIn and X in one workspace, unlimited campaigns and campaign DMs, the unified inbox, pipeline and tags, unlimited LinkedIn lead imports, 10M credits per account each month, and the API and webhooks. * **Agency: \$699 a month for 25 accounts**, or \$559 a month when you pay yearly (\$6,708 a year). For agencies running clients' accounts. It adds 250M credits a month shared by the whole team, white-label, priority support with a Slack channel, and done-for-you onboarding. * **Enterprise: custom pricing.** For large teams and custom volume. It adds custom account volume, a dedicated account manager, custom integrations and feature priorities, and done-for-you migration. Paying yearly saves 20%. Pick your plan and number of accounts in [**Settings → Billing**](https://app.reachhunt.ai/settings/billing). For Enterprise, select **Talk to us** there. Have a promo code? Select **Verify & apply discount** before you upgrade. Your first workspace starts with a 14-day free trial of Growth, for one connected account. Unlimited campaign DMs means ReachHunt adds no cap of its own. Sending is paced to stay inside X's and LinkedIn's limits. ## Credits Credits pay for AI replies, AI-written messages and X lead imports. They reset every month, and you can buy more at any time. Growth includes 10M credits per connected account each month. Agency pools them for the whole team, so 25 accounts share 250M a month and any account can use them. LinkedIn lead imports never spend credits, because they run on your own connected account. ## When a plan ends If your trial or plan ends, your campaigns, inbox and leads are saved. Pick a plan in [**Settings → Billing**](https://app.reachhunt.ai/settings/billing) to keep using ReachHunt. # Set up ReachHunt Source: https://docs.reachhunt.ai/get-started/set-up Create your account and connect your X and LinkedIn accounts in a few minutes You need Google Chrome on a computer, signed in to the X or LinkedIn accounts you want to connect. 1. Create an account at [app.reachhunt.ai](https://app.reachhunt.ai). 2. Follow the setup steps. When asked, install the [ReachHunt extension](https://chromewebstore.google.com/detail/reachhunt/fkcjcmlojmeebgpgkmlmmmeakbhdoffe), then come back to ReachHunt. 3. Pick the accounts to connect. Your DMs start syncing right away. Installed the extension but ReachHunt doesn't see it? Refresh the page. Next: [Your first campaign](/get-started/first-campaign). # Build a campaign Source: https://docs.reachhunt.ai/help-center/campaigns/build-a-campaign Choose your audience, write the sequence, set the schedule and pick accounts Open [**Campaigns**](https://app.reachhunt.ai/campaigns) and select **New campaign**. Setting it up takes five steps. ## 1. Details Enter a campaign name and pick the network. The network decides which lists and accounts the campaign can use. Leads never see the name. ## 2. Leads Pick one or more lead lists. Use the whole list, or open it to filter and tick only the people you want. ## 3. Sequence Add steps in the order they should happen: * **Send a message**: a DM. You can start from a [template](/help-center/inbox/templates). * **Wait if no reply**: a pause of some hours or days before the next step. * **View Profile and Send Connection Request**: a LinkedIn connection request. * **Send a free InMail**: a LinkedIn message to Premium and Open Profile members, with no connection needed. Your paid InMails are never used. Anyone who replies drops out of the sequence. The rest carry on to the next step. To make each message personal: * Insert variables such as first name, company or location. * Select any word to give it other wordings, or select **Generate with AI**. Each lead gets one version. * Select **Preview** to see the message for a random lead from your list. Under **Exclusions**, you can skip people another running campaign is messaging, people an earlier campaign already wrote to, people you've already messaged, and profiles with no photo. Turn on **Automatic translation** to translate messages into each recipient's language. ## 4. Schedule Pick the time zone, and the days and hours the campaign may send. It only sends inside these windows. Each account's daily limit is set in [**Connected accounts**](https://app.reachhunt.ai/accounts). ## 5. Account Pick the connected accounts to send from. New people are messaged from these. Anyone already mid-conversation keeps hearing from the account that wrote to them first. You can also pick a **Reply agent** to answer when a lead from this campaign replies. Select **Launch campaign** to start. # Pause, edit and stop a campaign Source: https://docs.reachhunt.ai/help-center/campaigns/pause-edit-stop Change a running campaign, or pause, stop or delete it ## Pause and resume Select **Pause** to stop queued messages from going out. Select **Resume** to carry on. ## Edit Open the campaign's **Settings** to change its configuration, message sequence or schedule. * While a campaign is **Running** or **Paused**, you can change everything except its audience. You can still remove people it hasn't written to yet in **Audience**. * Once it's **Completed** or **Stopped**, only the name and reply agent can change. ## Stop Select **Stop** to cancel everything still queued. This can't be undone. ## When a campaign pauses itself A campaign pauses itself when it can't send, for example when none of its accounts is still connected, or when your plan ends. The campaign shows the reason. Fix it, for example by reconnecting the account, then select **Resume**. ## Delete In the campaign's settings, select **Delete campaign**. This deletes the campaign and everything still queued. Messages already sent can't be taken back. # Track results Source: https://docs.reachhunt.ai/help-center/campaigns/track-results See what a campaign sent, who replied and what's left Open a campaign to see how it's doing. | Number | What it counts | | - | - | | **Messages sent** | First messages and follow-ups | | **Replies** | Leads who wrote back | | **Reply rate** | The share of contacted leads who replied | | **Invites sent** | LinkedIn connection requests, and how many were accepted | | **InMails** | Free InMails sent to Open Profiles | **Progress** shows how many leads are done and how many failed, and when the campaign should finish. * **Campaign activity** charts messages, replies and invites over time. * **Recipients** lists everyone messaged so far. Open a conversation from there. * **Audience** shows everyone the campaign will message. You can remove anyone it hasn't written to yet. Replies land in [**Messages**](https://app.reachhunt.ai/chat). Each conversation shows the campaign that first messaged the person. # Campaign troubleshooting Source: https://docs.reachhunt.ai/help-center/campaigns/troubleshooting Fix a campaign that won't start, isn't sending, or has failed messages ## The campaign won't start ReachHunt checks these before a campaign starts, and shows the first one that fails: | Message | Fix | | - | - | | Add at least one lead list | Pick a lead list in the Leads step | | Write at least one message | Add a **Send a message** step | | Every message step needs text | Fill in each message step | | Open at least one day on the schedule | Turn on at least one day in the Schedule step | | Connect an account for this campaign, or pick one that is still connected | Pick an account that is connected, or [reconnect it](/help-center/getting-set-up/connect-accounts#reconnect-an-account) | | The selected lists resolved to nobody to message | Your lists, selection or exclusions left nobody. Add people or loosen the exclusions | ## It's running, but nothing goes out * Check the schedule. The campaign only sends inside its sending windows, in its own time zone. * Check the accounts. An account that reached its daily or weekly limit, or that X or LinkedIn paused for a while, waits until it has room again. * Check that the accounts are still connected in [**Connected accounts**](https://app.reachhunt.ai/accounts). ## Some messages failed A send can fail, for example when the person's DMs are closed. Failed leads show in the campaign's **Progress**. To message only people you can reach, filter your lead list by **Can DM** before you build the campaign. # FAQ Source: https://docs.reachhunt.ai/help-center/faq Quick answers about ReachHunt > **Is it safe for my accounts?** > > Every account warms up over 7, 14 or 30 days and stays inside weekly limits that all its campaigns share. Campaigns only send inside the hours you set. On LinkedIn, invitations nobody accepts can be withdrawn automatically. > **Do I have to share my password?** > > No. You connect with the ReachHunt extension, which uses the account you're already signed in to in your browser. To connect a client's account, send them a one-time invite link and they connect it themselves. > **Which networks does ReachHunt support?** > > X and LinkedIn, both in one workspace. > **What does the AI agent do?** > > It replies to DMs on the accounts you deploy it to, using the knowledge, goals and guardrails you give it. You can take over any conversation with **Assign to you**. > **What are credits?** > > Credits pay for AI replies, AI-written messages and X lead imports. Every plan includes a monthly allowance, and you can buy more at any time. LinkedIn imports never use credits. > **Can my whole team use it?** > > Yes. Invite as many teammates as you like, choose which pages each one can use, and assign conversations. You pay per connected account, not per seat. > **Is there a free trial?** > > Yes. Your first workspace gets 14 days of Growth for one connected account, and you don't need a card to start. > **Which tools does ReachHunt connect to?** > > HubSpot, Pipedrive, Smartlead, n8n, and AI apps through the MCP server. See [Integrations](/integrations/overview). # Connect your accounts Source: https://docs.reachhunt.ai/help-center/getting-set-up/connect-accounts Connect X and LinkedIn accounts, reconnect them, and connect someone else's account with an invite link Messages, leads, campaigns and agents all run through a connected X or LinkedIn account. ## Connect an account 1. Open [**Connected accounts**](https://app.reachhunt.ai/accounts) and select **Connect account**. 2. If you're asked, install the [ReachHunt extension](https://chromewebstore.google.com/detail/reachhunt/fkcjcmlojmeebgpgkmlmmmeakbhdoffe), then refresh the page. 3. Pick the account to connect. The extension uses the account you're signed in to in your browser, so you never type your password into ReachHunt. Each connected account takes one seat on your plan. When your seats are full, pick a bigger plan in [**Settings → Billing**](https://app.reachhunt.ai/settings/billing) to connect another. ## Connect someone else's account To connect a client's or teammate's account without their password, send them an invite link. 1. Open [**Connected accounts**](https://app.reachhunt.ai/accounts) and select **Invite link**. 2. Copy the link and send it. Anyone with the link can connect their account to your workspace. Each link works once. ## Reconnect an account When an account shows **Needs re-auth**, ReachHunt can't send from it until you connect it again. Open the account's menu and select **Reconnect**. ## Remove an account Open the account's menu and select **Delete**. ReachHunt stops sending from it, and you can connect it again later. # Invite your team Source: https://docs.reachhunt.ai/help-center/getting-set-up/invite-your-team Invite teammates and choose which pages each one can use Invite as many teammates as you like. You pay per connected account, not per seat. ## Invite a teammate 1. Open [**Settings → Members**](https://app.reachhunt.ai/settings/members) and select **Invite teammate**. 2. Enter their name and email, then select **Next**. 3. Choose what they can use, then select **Invite**. They get an email with a link to join. Until they accept, the invite shows as **Invite sent**. You can resend or revoke it from its menu. ## Permissions For each page, a teammate gets **No access**, **Limited access** or **Full access**. Use **Set all permissions** to set every page at once. | Page | Limited access lets them | | - | - | | Campaigns | View campaigns, but not create or change them | | Leads | Import, add and organize leads, but not delete or export them | | Templates | View templates, but not create or edit them | | Accounts | View connected accounts, but not connect or disconnect one | | Members | View members, but not invite or remove them | Dashboard, Pipeline, Inbox, Agents and Billing have no limited level: a teammate has either no access or full access. **Developer** covers Integrations, webhooks and API keys: a teammate has either no access or full access. To change a teammate's access later, open their menu in [**Settings → Members**](https://app.reachhunt.ai/settings/members) and select **Edit permissions**. ## Remove a teammate Open their menu and select **Remove member**. To leave a workspace yourself, open the menu on your own row and select **Leave workspace**. You lose access to its accounts, campaigns and conversations, and the owner has to invite you again to come back. # Personalize ReachHunt Source: https://docs.reachhunt.ai/help-center/getting-set-up/personalize Set up statuses, tags, notifications, translation and inbox settings All of these live in [**Settings**](https://app.reachhunt.ai/settings). | Setting | What it does | | - | - | | [**Statuses**](https://app.reachhunt.ai/settings/statuses) | The stages you move people through in your pipeline | | [**Tags**](https://app.reachhunt.ai/settings/tags) | Labels for conversations, shared with your whole team | | [**Notifications**](https://app.reachhunt.ai/settings/notifications) | A sound when a new message arrives in a chat you don't have open: Chime, Ding, Pop, or your own sound up to 1 MB | | [**Translation**](https://app.reachhunt.ai/settings/translation) | The language messages are translated into when you translate them | | [**Conversations**](https://app.reachhunt.ai/settings/conversations) | Typing indicators, marking your sent messages as read for the team, and bulk archiving old conversations | | [**Prospects**](https://app.reachhunt.ai/settings/prospects) | The currency for deal values | You can also create tags and statuses straight from a conversation. See [Organize conversations](/help-center/inbox/organize-conversations). # Workspaces Source: https://docs.reachhunt.ai/help-center/getting-set-up/workspaces Create, switch, rename and delete workspaces A workspace holds your connected accounts, inbox, leads, campaigns and team. Each workspace has its own plan. Only your first workspace starts with a free trial. ## Create a workspace Open the workspace menu in the sidebar, select **New workspace**, enter a name and select **Create**. ## Switch workspaces Open the workspace menu and select **Switch workspace**, or select **View all workspaces** to see every workspace you own or were invited to. ## Rename a workspace Open [**Settings → General**](https://app.reachhunt.ai/settings/general) to change the workspace picture and name. The owner, or a member with full access to Members, can change them. ## Delete a workspace In [**Settings → General**](https://app.reachhunt.ai/settings/general), select **Delete workspace**. You can delete a workspace once it has no connected accounts and no running plan. Deleting removes the workspace for every member, stops its campaigns, and loses any credits left in it. It can't be undone. # Message requests Source: https://docs.reachhunt.ai/help-center/inbox/message-requests Answer DMs and invitations from people you haven't talked to yet New message requests and invitations land in [**Messages → Requests**](https://app.reachhunt.ai/chat/requests) first. Each connected account has its own requests. * **Message request**: someone wrote to you before you'd talked. Accept it to start the conversation. * **Invitation**: someone wants to connect with you on LinkedIn. Accept it to connect. Pick a request to read it, then select **Accept** or **Ignore**. To accept LinkedIn connection requests automatically, open the account's menu in [**Connected accounts**](https://app.reachhunt.ai/accounts), select **Limits & warm-up** and turn on **Auto accept connections**. ReachHunt then accepts them every couple of hours. # Organize conversations Source: https://docs.reachhunt.ai/help-center/inbox/organize-conversations Use tags, statuses, deal values, assignees and notes to keep track of every lead Open a conversation's contact details to organize it. What you set belongs to the person, so your whole team sees it in the inbox, the pipeline and lead lists. | Tool | Use it to | | - | - | | **Tags** | Label people, for example by interest or source. A person can have many tags | | **Status** | Put the person in a pipeline stage. A person has one status at most | | **Deal value** | Record what the person is worth to you. It adds up in the stage total on the pipeline | | **Assignee** | Give the conversation to a teammate | | **Notes** | Keep details about the person in their contact details | | **Private note** | Write a note inside the conversation for your team. The lead never sees it | To create a tag or status from a conversation, type its name and select **Create**. Manage them all in [**Settings → Tags**](https://app.reachhunt.ai/settings/tags) and [**Settings → Statuses**](https://app.reachhunt.ai/settings/statuses). To let an AI agent answer a conversation, select **Assign to agent**. Select **Assign to you** to take it back. # Pipeline Source: https://docs.reachhunt.ai/help-center/inbox/pipeline Track every lead through your stages on one board [**Pipeline**](https://app.reachhunt.ai/pipeline) shows your conversations on one board. Each stage is a status, and you drag a card to move the person to another stage. * **Kanban** shows each stage as a column, with the total deal value of the people in it. * **Table** lists everyone, with filters for stage, tags, network, account, deal value, reply state, and whether you've messaged them yet. The board shows people **In pipeline**: the ones who have a status. Switch to **All threads** to see everyone, then set a stage to bring a conversation in. To add, rename or delete stages, select **Manage statuses** or open [**Settings → Statuses**](https://app.reachhunt.ai/settings/statuses). You can reorder and collapse stages on the board too. People from a disconnected account are locked until you reconnect it. # Templates Source: https://docs.reachhunt.ai/help-center/inbox/templates Save messages once and reuse them in campaigns A template is a saved message you can reuse across campaigns. 1. Open [**Templates**](https://app.reachhunt.ai/templates) and select **Create template**. 2. Name it and write the message. Insert variables such as first name, full name, handle, company or location. They fill in for each lead. 3. Vary the wording with spintax, so not every lead gets the same text. For example, `{Hi|Hey} {{firstName}}` sends either "Hi Jane" or "Hey Jane". 4. If you like, add an AI prompt, which writes those lines for each lead, or attach a file. 5. Check the preview, then select **Save template**. To use a template, select **Start from a template** on a message step in a campaign. Deleting a template doesn't change the campaigns that already use its text. AI-written lines use credits. # Using the inbox Source: https://docs.reachhunt.ai/help-center/inbox/using-the-inbox Read and answer the DMs of every connected account in one place [**Messages**](https://app.reachhunt.ai/chat) shows the conversations of every connected X and LinkedIn account in one inbox. Under it, you also find **Assigned to me**, [**Requests**](https://app.reachhunt.ai/chat/requests) and **Archived**. ## Find a conversation Switch between **All Inbox**, **Unread**, **Needs reply**, **Waiting** and **Closed**. Filter by tags or status, and sort by newest or oldest first. ## Reply Type your message and send it. You can also: * Attach files, and add emoji and GIFs. * Translate your message before you send it. Pick the language in [**Settings → Translation**](https://app.reachhunt.ai/settings/translation). * Write or improve the message with AI: write a reply, summarize the chat, make it more persuasive, fix the grammar, shorten it or change the tone. Writing with AI uses credits. * Schedule it for later: **In 1 hour**, **Tomorrow morning**, **Tomorrow afternoon**, **Monday morning**, or a date and time you pick. A scheduled message can still be edited or sent right away. ## Keep the inbox tidy From a conversation's menu, you can mark it unread, close it, or reopen it later. To clear out old conversations, open [**Settings → Conversations**](https://app.reachhunt.ai/settings/conversations) and use **Bulk archive**. Archived conversations move to **Archived**, and a new message brings one straight back. # Import leads from LinkedIn Source: https://docs.reachhunt.ai/help-center/leads/import-from-linkedin Fill a LinkedIn lead list from searches, your network, posts and groups Open a LinkedIn lead list and select **Add leads**. These sources only show for LinkedIn lists: | Section | Source | Adds | | - | - | - | | Top of the panel | **Import from a search** | Everyone a LinkedIn people search finds | | From a profile | **Import connections** | Your account's 1st-degree connections | | | **Import following** | Everyone your account follows | | | **Import followers** | Everyone who follows your account | | From a post | **Import post likes** | Everyone who liked a LinkedIn post | | | **Import comments** | Everyone who commented on a LinkedIn post | | From a group | **Import from a group** | The members of a LinkedIn group | | From messages | **Import chat contacts** | Everyone your account has a LinkedIn conversation with | ## Search LinkedIn In **Import from a search**, add up to six keywords and choose what each one matches: general, title, company, first name or last name. Narrow the search by location, industry, current or past company, followers of someone, school, profile language and connection degree. You can also paste a LinkedIn search link. The preview shows who the search finds before you import. LinkedIn imports run on your own connected account, so they never use credits. The same panel also has **Quick add**, files, and imports from your other lists and campaigns. See [Other ways to add leads](/help-center/leads/other-ways-to-add-leads). # Import leads from X Source: https://docs.reachhunt.ai/help-center/leads/import-from-x Fill an X lead list from followers, posts, lists and chats Open an X lead list and select **Add leads**. These sources only show for X lists: | Section | Source | Adds | | - | - | - | | From a profile | **Import from followers** | Everyone who follows an account you pick | | | **Import from following** | Everyone an account you pick follows | | From a post | **Import retweets** | Everyone who retweeted a post | | | **Import comments** | Everyone who commented on a post | | | **Import post likes** | Everyone who liked one of your posts | | From an X list | **Import list members** | Every account on an X list | | | **Import list followers** | Everyone who follows an X list | | From messages | **Import chat contacts** | Everyone your account has an X conversation with | An import runs in the background. The list shows **Syncing** while it runs and **Completed** when it's done. X imports use credits. The same panel also has **Quick add**, files, and imports from your other lists and campaigns. See [Other ways to add leads](/help-center/leads/other-ways-to-add-leads). # Lead lists Source: https://docs.reachhunt.ai/help-center/leads/lead-lists Collect the people you want to message into lists A lead list holds the people you want to message. Build it once and reuse it across campaigns. ## Create a list 1. Open [**Leads**](https://app.reachhunt.ai/leads) and select **New list**. 2. Name it and pick the platform: X or LinkedIn. A list stays on one platform, and you can't change it later. 3. Select **Create list**, then select **Add leads** to fill it. See [Import from X](/help-center/leads/import-from-x), [Import from LinkedIn](/help-center/leads/import-from-linkedin) and [Other ways to add leads](/help-center/leads/other-ways-to-add-leads). ## Work with a list * The **Reachable** column counts the people you can DM. Filter a list by **Can DM** or **DMs closed**. * Select people to add them to another list, send them to your CRM or Smartlead through an [integration](/integrations/overview), or remove them. * Select **Export list** to download a list. * Star a list to keep it in **Favorites**. ## X Database **X Database** is a read-only list of public X profiles you can search. You can browse it even before you connect an account. # Other ways to add leads Source: https://docs.reachhunt.ai/help-center/leads/other-ways-to-add-leads Add leads by hand, from a file, from another list or campaign, or from Smartlead These sources show for both X and LinkedIn lists. Open a lead list and select **Add leads**. | Section | Source | Adds | | - | - | - | | Top of the panel | **Quick add** | One person, by name or username | | From ReachHunt | **Import from a list** | People from one of your other lists | | | **Import from a campaign** | People from one of your campaigns | | From a file | **Upload a CSV** | Everyone in a CSV file with an `id`, `user_id` or `username` column | | | **Upload plain text** | Everyone in a file with one user ID or username per line | | From an integration | **Smartlead campaign** | The X or LinkedIn profiles of the leads in a Smartlead campaign. It shows once [Smartlead is connected](/integrations/smartlead) | To copy people you already have, select them in a list and add them to another list. # ReachHunt Help Center Source: https://docs.reachhunt.ai/help-center/overview Guides and answers for your accounts, inbox, leads, campaigns and team Find step-by-step guides for everything you do in ReachHunt, from connecting your first account to running campaigns and answering replies. Pick a topic below, or use the search at the top to jump straight to an answer. ## Browse by topic > **[Getting set up](/help-center/getting-set-up/connect-accounts)** > > Connect accounts, invite your team and set up your workspace. > **[Inbox](/help-center/inbox/using-the-inbox)** > > Answer DMs, handle requests and organize conversations. > **[Leads](/help-center/leads/lead-lists)** > > Build lead lists from X and LinkedIn. > **[Campaigns](/help-center/campaigns/build-a-campaign)** > > Send DM sequences and follow the results. ## Popular guides * [Connect your accounts](/help-center/getting-set-up/connect-accounts): connect X and LinkedIn, or send an invite link to a client. * [Import leads from LinkedIn](/help-center/leads/import-from-linkedin): fill a list from a search, your network, posts or groups. * [Build a campaign](/help-center/campaigns/build-a-campaign): pick the audience, write the sequence, set the schedule and choose accounts. * [Organize conversations](/help-center/inbox/organize-conversations): use tags, statuses, deal values and notes. * [Campaign troubleshooting](/help-center/campaigns/troubleshooting): fix a campaign that won't start or isn't sending. ## Need more help? New to ReachHunt? Start with [Set up ReachHunt](/get-started/set-up). Looking for a quick answer? See the [FAQ](/help-center/faq). Connecting your own tools? See [Integrations](/integrations/overview) and the [Developer API](/developer-api/introduction). # Welcome to ReachHunt Source: https://docs.reachhunt.ai/index One place for your DM outreach on X and LinkedIn ReachHunt is one place to manage your outreach on X and LinkedIn: one inbox for every conversation, lead lists, campaigns and a shared pipeline for your team. ## What you can do * [**Messages**](https://app.reachhunt.ai/chat): read and answer the DMs of every connected account in one inbox. * [**Leads**](https://app.reachhunt.ai/leads): collect people from X and LinkedIn into lead lists. * [**Campaigns**](https://app.reachhunt.ai/campaigns): send DM sequences on a schedule, from one or more accounts. * [**Agents**](https://app.reachhunt.ai/agents): let an AI agent reply to your leads for you. * [**Pipeline**](https://app.reachhunt.ai/pipeline): track every lead with statuses, tags and deal values. ## Start here > **[Set up ReachHunt](/get-started/set-up)** > > Create your account and connect X and LinkedIn. > **[Your first campaign](/get-started/first-campaign)** > > Send your first DM campaign. > **[Plans and credits](/get-started/plans)** > > What you pay for and how credits work. > **[Integrations](/integrations/overview)** > > Connect your CRM, n8n and AI apps. Building your own tools? See the [Developer API](/developer-api/introduction). # HubSpot Source: https://docs.reachhunt.ai/integrations/hubspot Send leads, conversations and deals to HubSpot Connect HubSpot and ReachHunt sends the leads who reply, their conversations and their deals to your HubSpot CRM. ## What you can do * Add leads to HubSpot as contacts when they reply, or when a campaign contacts them. * Keep each contact's ReachHunt status, tags, deal value, assignee, campaigns and replies up to date. * Log conversations, LinkedIn messages, notes and activity on the contact. * Create deals from statuses and tags, and move them as leads progress. * Send profiles from any lead list to HubSpot by hand. ## Before you start * A HubSpot account. * Full access to every section of the ReachHunt workspace. * For deals, a deal pipeline in HubSpot. ## Connect HubSpot **1. Open HubSpot** In ReachHunt, open [**Settings → Integrations**](https://app.reachhunt.ai/settings/integrations) and select **HubSpot**. **2. Connect** Select **Connect HubSpot**. Sign in to HubSpot and approve the access ReachHunt asks for. ReachHunt gets access to your contacts, companies and deals, and reads your users to set contact owners. Once it's connected, the page shows your HubSpot account ID and the date you connected. If the page shows **Needs attention**, ReachHunt can no longer use the connection. Select **Reconnect** and approve again. You also select **Reconnect** when the page asks you to, for example to sync contact owners and companies. ## Choose when to add a contact | Setting | Default | | - | - | | **Send leads to HubSpot** | On | | **A lead replies** | On | | **A campaign contacts a lead** | Off | Leads already in HubSpot keep updating either way. Turn off **Send leads to HubSpot** to pause sending. Nothing already in HubSpot is removed. ## Choose what to send Contacts get their profile details, such as email, phone, LinkedIn URL, job, location and bio. They also get a **ReachHunt** group of properties with status, tags, deal value, assignee, campaigns and replies. | Option | Default | | - | - | | The conversation as a note | On | | LinkedIn messages on the contact timeline | On | | Your notes and internal notes | On | | Companies, linked to their contacts and deals | On | Each contact also gets an activity note. Choose what it includes: | Activity | Default | | - | - | | Campaign steps | On | | Connection requests | On | | Lead list adds | Off | | Status changes | On | | Tag changes | On | | Assignee and deal value changes | On | ## Create deals from statuses and tags Deals are off by default. Create your statuses and tags first, in [**Settings → Statuses**](https://app.reachhunt.ai/settings/statuses) and [**Settings → Tags**](https://app.reachhunt.ai/settings/tags). **1. Turn on deals** Turn on **Create deals from statuses and tags**. **2. Pick a pipeline** Under **Pipeline**, pick the HubSpot deal pipeline to use. **3. Map statuses and tags** Under **Status → deal stage**, pick a stage for each status. Do the same under **Tag → deal stage**. Choose **No deal** for any status or tag that shouldn't create a deal. When you set a mapped status or tag on a lead, ReachHunt creates its deal or moves it to that stage. The deal amount is the lead's deal value. ## Send leads by hand Open a lead list, select profiles, choose **Send to**, then pick HubSpot. The profiles show up in HubSpot within a few minutes. In the **Send to** list, HubSpot shows **Reconnect** when the connection needs attention, and **Sync off** when you turned sending off. ReachHunt sends nothing until you fix either one. ## Disconnect HubSpot Select **Disconnect** on the HubSpot page. ReachHunt stops sending leads. Contacts already in HubSpot stay there. # MCP server Source: https://docs.reachhunt.ai/integrations/mcp-server Use ReachHunt inside Claude, ChatGPT, Cursor and other AI apps The ReachHunt MCP server lets an AI app work in your workspace. Ask it to read your conversations, reply to a lead, build a lead list or start a campaign, and it does the work through your connected X and LinkedIn accounts. You connect by signing in to ReachHunt from your AI app. You don't copy a key. ## Server URL Paste this URL into your AI app: ```txt Server URL icon="link" theme={"system"} https://mcp.reachhunt.ai/mcp ``` ## What your AI app can do | Area | What it can do | | - | - | | Workspace | See which workspace you're connected to, your connected accounts and their sending limits, your credits, and an activity summary | | Inbox | List and read conversations and message requests, mark them read, close and reopen them, and answer requests | | Messages | Read, send and react to messages, and schedule or cancel scheduled messages | | Conversation details | Set tags, status, notes, assignee and deal value, and add internal notes | | Leads and lead lists | Search people on X and LinkedIn, create lead lists, add and import leads, and update a lead's tags, status, note and value | | Campaigns | Create and edit campaigns, start, pause, resume and stop them, and follow their targets and activity | | AI agents | Create, train and publish agents, assign them to accounts, pause and resume them, and test them | | Pipeline, templates, tags and statuses | Read your pipeline, and list and create templates, tags and statuses | An AI app can't delete anything. Conversations, messages, lead lists, campaigns, agents, templates, tags and statuses stay in place. It can stop a campaign and cancel a scheduled message. ## Before you start * An AI app that supports MCP, such as Claude, ChatGPT, Cursor or Claude Code. * Full access to **Developer** in the ReachHunt workspace. * A workspace with an active plan. ## Connect your AI app **Claude** **1. Open connectors** In Claude, on claude.ai or the desktop app, open **Customize**, then **Connectors**. **2. Add a custom connector** Select **+ Add**, then **Add custom connector**. **3. Enter the details** Enter `ReachHunt` as the name, paste `https://mcp.reachhunt.ai/mcp` and select **Continue**. **4. Keep the sign-in settings** Keep the sign-in settings Claude suggests, select **Continue**, then select **Add**. **5. Connect** Select **Connect** next to ReachHunt. A ReachHunt page opens in your browser. Choose your workspace and select **Connect**. **6. Turn it on in a chat** In a chat, select **+**, open **Connectors** and turn on ReachHunt. > [!NOTE] > > On a Team or Enterprise plan, an owner first adds ReachHunt in **Organization settings → Connectors**. Then each member selects **Connect** in **Customize → Connectors**. **ChatGPT** **1. Open settings** In ChatGPT, select your profile at the bottom left and open **Settings**. **2. Turn on developer mode** Open **Apps**, then **Advanced settings**, and turn on **Developer mode**. **3. Create an app** Go back to **Apps** and select **Create app**. **4. Enter the details** Enter `ReachHunt` as the name, paste `https://mcp.reachhunt.ai/mcp` as the MCP server URL, choose **OAuth** and select **Create**. **5. Connect** A ReachHunt page opens in your browser. Choose your workspace and select **Connect**. **Cursor** **1. Open your MCP file** Open `~/.cursor/mcp.json` to connect every project, or `.cursor/mcp.json` inside one project. Create the file if it doesn't exist. **2. Add ReachHunt** Paste this into the file and save it: ```json mcp.json theme={"system"} { "mcpServers": { "reachhunt": { "url": "https://mcp.reachhunt.ai/mcp" } } } ``` **3. Sign in** In **Cursor Settings**, open **MCP** and select the sign-in button next to `reachhunt`. A ReachHunt page opens in your browser. Choose your workspace and select **Connect**. **Claude Code** **1. Add the server** Run this in your terminal: ```bash theme={"system"} claude mcp add --transport http reachhunt https://mcp.reachhunt.ai/mcp ``` **2. Authenticate** Start Claude Code, type `/mcp`, choose `reachhunt` and select **Authenticate**. **3. Connect** A ReachHunt page opens in your browser. Choose your workspace and select **Connect**. **Other apps** **1. Open the config file** Open your app's MCP config file. For Claude Desktop, it is here: | System | Path | | - | - | | macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` | | Windows | `%APPDATA%\Claude\claude_desktop_config.json` | **2. Add ReachHunt** Paste this into the file and save it. It needs Node.js on your computer: ```json claude_desktop_config.json theme={"system"} { "mcpServers": { "reachhunt": { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.reachhunt.ai/mcp"] } } } ``` **3. Restart and connect** Restart the app. A ReachHunt page opens in your browser. Choose your workspace and select **Connect**. ## What happens when you connect The ReachHunt page that opens shows the app's name and a workspace picker. Select **Connect** to approve. The app can then read and act in that workspace, including sending messages from its accounts. Each app you connect gets its own API key, named after the app with `(MCP)` after it. You can see it in [**Settings → API**](https://app.reachhunt.ai/settings/api). To check that it works, ask your AI app: "Which ReachHunt workspace am I connected to?" ## Limits * Tools that only read data are marked read-only, so your AI app can run them without asking. Tools that change data, send messages or reach real people are marked as such, so your AI app can ask you first. * List tools return 20 items unless your AI app asks for more. * A result longer than 60,000 characters is cut off. * The connection acts as the workspace owner, with full access to the workspace. ## Disconnect an app Delete the app's key in [**Settings → API**](https://app.reachhunt.ai/settings/api). The app loses access right away, and its tools answer that access was removed. If you connect the same app again, ReachHunt replaces its earlier connection and revokes the old key. ## Troubleshooting | You see | What to do | | - | - | | You need full Developer access to this workspace to connect an app | Choose another workspace, or ask its owner for full access to **Developer** | | This workspace has no active plan | Choose another workspace, or renew the plan | | This request has expired | Go back to your AI app and start connecting again | | Your session ended | Log in to ReachHunt again, then connect | | You are not in a workspace yet | Create a workspace in ReachHunt, then connect again | # n8n Source: https://docs.reachhunt.ai/integrations/n8n Run ReachHunt actions and start workflows from ReachHunt events The ReachHunt nodes for n8n let you send DMs, manage leads and campaigns, and start workflows from ReachHunt events, all inside n8n. ## What you can do * Run ReachHunt actions in any workflow with the **ReachHunt** node: send messages, manage leads and lead lists, and run campaigns and AI agents. * Start a workflow when something happens in ReachHunt with the **ReachHunt Trigger**, such as a reply or a finished campaign. * Give the n8n AI Agent ReachHunt actions as tools. ## Before you start * n8n Cloud, or your own n8n server reachable over `https`. * Full access to **Developer** in the ReachHunt workspace, to create an API key. ## Set up Setup takes about five minutes. **1. Create an API key** In ReachHunt, open [**Settings → API**](https://app.reachhunt.ai/settings/api) and create a key. n8n uses it to work in this workspace. **2. Install the nodes** In n8n, open **Settings → Community nodes → Install**, enter `n8n-nodes-reachhunt` and install it. On your own server without that screen, run this there instead: ```bash theme={"system"} cd ~/.n8n/nodes && npm install n8n-nodes-reachhunt ``` **3. Add the credential** In n8n, open **Credentials → Add credential**, search for **ReachHunt API**, paste your API key and save. Leave **Base URL** as it is. **4. Build a workflow** Add a **ReachHunt** node to any workflow, or start a workflow with the **ReachHunt Trigger**. ## Start workflows from ReachHunt Pick the events you want in the ReachHunt Trigger. While the workflow is on, ReachHunt sends each event to it. You can see it in [**Settings → Webhooks**](https://app.reachhunt.ai/settings/webhooks) as `n8n: `. Turning the workflow off removes it. Each event arrives as ReachHunt sends it, with `id`, `type`, `apiVersion`, `createdAt`, `workspaceId` and `data`. See [Webhooks overview](/webhooks/overview) for every event type. ReachHunt sends events only to public `https://` addresses. n8n Cloud works as it is. A self-hosted n8n must be reachable over `https`, and needs `WEBHOOK_URL` set if it runs behind a proxy. To send a sample event, open the webhook in [**Settings → Webhooks**](https://app.reachhunt.ai/settings/webhooks) and select **Send test event**. ## Available actions | Resource | Actions | | - | - | | Account | Get Many, Get Limits | | AI Agent | Get, Get Many, Pause, Resume, Assign Account, Unassign Account, Set Conversation Mode | | Campaign | Create, Get, Get Many, Update, Start, Pause, Resume, Stop, Get Targets, Get Activity | | Conversation | Get, Get Many, Find or Start, Get Profile, Mark as Read, Mark as Unread, Close, Reopen, Add Tag, Remove Tag, Set Status, Set Assignee, Set Note, Set Deal Value | | Internal Note | Create, Get Many | | Lead | Search, Find People, Look Up X Profile, Update Tags, Set Status, Set Note, Set Deal Value | | Lead List | Create, Get, Get Many, Get Leads, Add Leads, Copy Leads, Start Import, Stop Import, Get Imports | | Message | Send, Get Many, React | | Request | Get Many, Answer | | Scheduled Message | Create, Get Many, Cancel | | Status | Create, Get Many | | Tag | Create, Get Many | | Template | Create, Get Many | | Workspace | Get Activity Summary, Get Credits | > [!WARNING] > > Actions that send messages, react, answer requests or start campaigns reach real people from your connected accounts. ## Workflow ideas | Idea | Flow | | - | - | | Ping Slack when a lead replies | `ReachHunt Trigger (Campaign Lead Replied)` → `Slack (Send Message)` | | Add leads from a Google Sheet | `Google Sheets Trigger (Row Added)` → `ReachHunt (Lead List: Add Leads)` | | Send booked meetings to your CRM | `ReachHunt Trigger (Lead Status Changed)` → `IF (status is Meeting booked)` → `HubSpot (Create Deal)` | | Reply with your own AI | `ReachHunt Trigger (Message Received)` → `OpenAI (Message a Model)` → `ReachHunt (Message: Send)` | ## Tips * Accounts, lead lists, campaigns, AI agents, tags, statuses and teammates come with a searchable list. Switch to **By ID**, or use an expression instead. * Turn on **Return All** to page through everything, or set **Limit**. It is 50 by default. * Most conversation actions need the account and the conversation. Map them from the trigger, for example `{{ $json.data.account.id }}` and `{{ $json.data.message.conversationId }}`. * **Send At** on a scheduled message uses the time zone of the workflow. * Leave **Status** or **Assignee** empty to clear it. * When an action fails, the node shows ReachHunt's own message, such as `Campaign not found`. With **On Error → Continue**, the error goes to the output instead of stopping the workflow. ## Disconnect n8n n8n works through its API key. Delete that key in [**Settings → API**](https://app.reachhunt.ai/settings/api) to disconnect n8n. # Integrations Source: https://docs.reachhunt.ai/integrations/overview Connect ReachHunt to your AI apps, automations, CRM and email tools ReachHunt integrations send your leads, conversations and deals to the tools you already use, and let those tools work inside ReachHunt. You manage them in [**Settings → Integrations**](https://app.reachhunt.ai/settings/integrations). > **[MCP server](/integrations/mcp-server)** > > Use ReachHunt inside Claude, ChatGPT, Cursor and other AI apps. > **[n8n](/integrations/n8n)** > > Run ReachHunt actions and start workflows from ReachHunt events. > **[HubSpot](/integrations/hubspot)** > > Send leads, conversations and deals to HubSpot. > **[Pipedrive](/integrations/pipedrive)** > > Send leads, conversations and deals to Pipedrive. > **[Smartlead](/integrations/smartlead)** > > Add the leads you DM to your Smartlead email campaigns. > **Clay** > > Bring enriched leads from Clay into ReachHunt. Coming soon. ## Which one to use | Integration | Category | Use it to | You connect with | | - | - | - | - | | [MCP server](/integrations/mcp-server) | AI assistants | Let an AI app read and act in your workspace | Sign-in from the AI app | | [n8n](/integrations/n8n) | Automation | Build workflows around ReachHunt actions and events | An API key | | [HubSpot](/integrations/hubspot) | CRM | Keep contacts, notes and deals up to date in HubSpot | HubSpot sign-in | | [Pipedrive](/integrations/pipedrive) | CRM | Keep persons, notes and deals up to date in Pipedrive | Pipedrive sign-in | | [Smartlead](/integrations/smartlead) | Email outreach | Email the leads you reach on X and LinkedIn | A Smartlead Admin API key | ## Build your own The API and webhooks power these integrations. Use them to connect a tool that isn't listed. > **[Developer API](/developer-api/introduction)** > > Read and change your workspace data from your own apps and scripts. > **[Webhooks](/webhooks/overview)** > > Get events sent to your server as they happen. ## FAQ > **Who can connect an integration?** > > Members with full access to **Developer**. Ask a workspace admin if you don't have it. > **What happens when I disconnect one?** > > ReachHunt stops sending to it. What it already sent stays there: contacts in HubSpot, persons in Pipedrive and leads in Smartlead campaigns. For the MCP server and n8n, deleting their API key in [**Settings → API**](https://app.reachhunt.ai/settings/api) ends their access. > **Can I connect HubSpot and Pipedrive at the same time?** > > Yes. Each has its own settings, and **Send to** in a lead list shows every CRM you connected. # Pipedrive Source: https://docs.reachhunt.ai/integrations/pipedrive Send leads, conversations and deals to Pipedrive Connect Pipedrive and ReachHunt sends the leads who reply, their conversations and their deals to your Pipedrive CRM. ## What you can do * Add leads to Pipedrive as persons when they reply, or when a campaign contacts them. * Keep each person's ReachHunt status, tags, deal value, assignee, campaigns and replies up to date, with a pinned summary. * Log conversations, messages, notes and activity on the person. * Create deals from statuses and tags, and move them as leads progress. * Send profiles from any lead list to Pipedrive by hand. ## Before you start * A Pipedrive account. * Full access to every section of the ReachHunt workspace. * For deals, a pipeline in Pipedrive. ## Connect Pipedrive **1. Open Pipedrive** In ReachHunt, open [**Settings → Integrations**](https://app.reachhunt.ai/settings/integrations) and select **Pipedrive**. **2. Connect** Select **Connect Pipedrive**. Sign in to Pipedrive and approve the access ReachHunt asks for. ReachHunt gets access to your persons, organizations, deals and activities. It adds its own person fields, and reads your users to set owners. Once it's connected, the page shows your Pipedrive company ID and the date you connected. If the page shows **Needs attention**, ReachHunt can no longer use the connection. Select **Reconnect** and approve again. You also select **Reconnect** when the page asks you to, to give ReachHunt the access it needs. This is also what you see if you uninstall the ReachHunt app in Pipedrive. ## Choose when to add a person | Setting | Default | | - | - | | **Send leads to Pipedrive** | On | | **A lead replies** | On | | **A campaign contacts a lead** | Off | Leads already in Pipedrive keep updating either way. Turn off **Send leads to Pipedrive** to pause sending. Nothing already in Pipedrive is removed. ## Choose what to send Persons get their name, job title, email, phone, address and photo. They also get ReachHunt fields for status, tags, deal value, assignee, campaigns and replies. | Option | Default | | - | - | | A pinned ReachHunt summary on each person | On | | The conversation as a note | On | | Each message as a done activity | On | | Your notes and internal notes | On | | Organizations, linked to their persons and deals | On | | Profile photos | On | Each person also gets an activity note. Choose what it includes: | Activity | Default | | - | - | | Campaign steps | On | | Connection requests | On | | Lead list adds | Off | | Status changes | On | | Tag changes | On | | Assignee and deal value changes | On | ## Create deals from statuses and tags Deals are off by default. Create your statuses and tags first, in [**Settings → Statuses**](https://app.reachhunt.ai/settings/statuses) and [**Settings → Tags**](https://app.reachhunt.ai/settings/tags). **1. Turn on deals** Turn on **Create deals from statuses and tags**. **2. Pick a pipeline** Under **Pipeline**, pick the Pipedrive pipeline to use. **3. Map statuses and tags** Under **Status → deal stage**, pick a stage for each status. Do the same under **Tag → deal stage**. Choose **No deal** for any status or tag that shouldn't create a deal. When you set a mapped status or tag on a lead, ReachHunt creates its deal or moves it to that stage. The deal value is the lead's deal value. ## Send leads by hand Open a lead list, select profiles, choose **Send to**, then pick Pipedrive. The profiles show up in Pipedrive within a few minutes. In the **Send to** list, Pipedrive shows **Reconnect** when the connection needs attention, and **Sync off** when you turned sending off. ReachHunt sends nothing until you fix either one. ## Disconnect Pipedrive Select **Disconnect** on the Pipedrive page. ReachHunt stops sending leads. Persons already in Pipedrive stay there. # Smartlead Source: https://docs.reachhunt.ai/integrations/smartlead Send leads to Smartlead email campaigns Connect Smartlead to send the leads you reach on X and LinkedIn to your Smartlead email campaigns. ## What you can do * Send leads to a Smartlead campaign, by hand or when a ReachHunt campaign messages them. * Pause a lead in Smartlead when they reply to your DMs. * Import the LinkedIn or X profiles of a Smartlead campaign's leads into a lead list. ## Before you start * A Smartlead account with at least one campaign. * Your Smartlead Admin API key, from **Settings → API Key Management** in Smartlead. * Full access to every section of the ReachHunt workspace. ## Connect Smartlead **1. Copy your API key** In Smartlead, open **Settings → API Key Management** and copy your Admin API key. **2. Open Smartlead** In ReachHunt, open [**Settings → Integrations**](https://app.reachhunt.ai/settings/integrations) and select **Smartlead**. **3. Connect** Paste the key and select **Connect Smartlead**. If the page shows **Needs attention**, ReachHunt can no longer use the key. Paste a working API key and select **Reconnect**. ## Choose a campaign Pick the Smartlead campaign that leads go to. You can pick another campaign when you send leads. If you have no campaigns yet, create one in Smartlead, then open the list again. Smartlead only takes leads that have an email. ## Automate sending | Setting | What it does | Default | | - | - | - | | **Send a lead to Smartlead when a campaign messages them** | Keeps your emails and DMs in step without sending leads by hand | Off | | **Pause a lead in Smartlead when they reply to your DMs** | Stops Smartlead emailing someone who already replied | On | ## Send leads by hand **1. Select profiles** Open a lead list and select the profiles you want to send. **2. Pick a campaign** Choose **Send to Smartlead** and pick a Smartlead campaign. **3. Send** Select **Send**. ReachHunt shows how many profiles were added, and why any were skipped. Only profiles with an email go to Smartlead. ReachHunt knows the emails of LinkedIn connections who share theirs, so pick those. The result lists each profile as one of these: | Result | Meaning | | - | - | | Added to Smartlead | The lead is now in the campaign | | Already in this campaign | The lead was already there | | In another Smartlead campaign | The lead is in a different campaign | | No email | The profile has no email | | Invalid email | The email isn't valid | | Unsubscribed or blocked | The person unsubscribed or is blocked in Smartlead | ## Import from Smartlead You can add the LinkedIn or X profiles of leads in a Smartlead campaign to a ReachHunt lead list. Open the lead list, add leads from a **Smartlead campaign**, pick the campaign and select **Import**. ReachHunt adds the profile links to the list. ## Disconnect Smartlead Select **Disconnect** on the Smartlead page. ReachHunt stops sending leads. Leads already in Smartlead stay in their campaigns. # Account connected Source: https://docs.reachhunt.ai/webhooks/events/account-connected /openapi.json webhook account.connected An X or LinkedIn account was connected or reconnected. Also fires when an account that needed reconnecting is connected again. # Account disconnected Source: https://docs.reachhunt.ai/webhooks/events/account-disconnected /openapi.json webhook account.disconnected An account needs to be reconnected, or was removed from the workspace. # Campaign completed Source: https://docs.reachhunt.ai/webhooks/events/campaign-completed /openapi.json webhook campaign.completed A campaign reached every lead and finished. # Campaign created Source: https://docs.reachhunt.ai/webhooks/events/campaign-created /openapi.json webhook campaign.created A campaign was created. # Campaign follow up sent Source: https://docs.reachhunt.ai/webhooks/events/campaign-follow-up-sent /openapi.json webhook campaign.follow_up_sent A campaign sent a follow-up message to a lead, as a DM or an InMail. # Campaign lead contacted Source: https://docs.reachhunt.ai/webhooks/events/campaign-lead-contacted /openapi.json webhook campaign.lead_contacted A campaign sent its first message to a lead, as a DM or an InMail. # Campaign lead failed Source: https://docs.reachhunt.ai/webhooks/events/campaign-lead-failed /openapi.json webhook campaign.lead_failed A campaign could not reach a lead and stopped trying. The lead gets nothing more from this campaign. # Campaign lead replied Source: https://docs.reachhunt.ai/webhooks/events/campaign-lead-replied /openapi.json webhook campaign.lead_replied A lead replied to a campaign for the first time. Fires for the first reply only. Every message they send also fires `message.received`. # Campaign paused Source: https://docs.reachhunt.ai/webhooks/events/campaign-paused /openapi.json webhook campaign.paused A campaign was paused, by a member or because it could not keep sending. `campaign.pauseReason` says why when ReachHunt paused it itself, for example when no connected account is left to send from. # Campaign resumed Source: https://docs.reachhunt.ai/webhooks/events/campaign-resumed /openapi.json webhook campaign.resumed A paused campaign started sending again. # Campaign started Source: https://docs.reachhunt.ai/webhooks/events/campaign-started /openapi.json webhook campaign.started A campaign started sending for the first time. # Campaign stopped Source: https://docs.reachhunt.ai/webhooks/events/campaign-stopped /openapi.json webhook campaign.stopped A campaign was stopped before it finished. Deleting a running or paused campaign stops it first, so that fires this too. # Connection request accepted Source: https://docs.reachhunt.ai/webhooks/events/connection-request-accepted /openapi.json webhook connection_request.accepted A lead accepted a LinkedIn connection request sent by a campaign. ReachHunt checks pending requests from time to time, so this can arrive a while after the lead accepted. # Connection request sent Source: https://docs.reachhunt.ai/webhooks/events/connection-request-sent /openapi.json webhook connection_request.sent A campaign sent a LinkedIn connection request. # Connection request withdrawn Source: https://docs.reachhunt.ai/webhooks/events/connection-request-withdrawn /openapi.json webhook connection_request.withdrawn A connection request that was never accepted was withdrawn. ReachHunt withdraws a request still pending after 14 days. The lead then fails in the campaign, which fires `campaign.lead_failed`. # Conversation archived Source: https://docs.reachhunt.ai/webhooks/events/conversation-archived /openapi.json webhook conversation.archived A conversation was archived, by a member or by auto-archive. # Conversation created Source: https://docs.reachhunt.ai/webhooks/events/conversation-created /openapi.json webhook conversation.created A new conversation showed up in the inbox. Fires when the first message of a new conversation is sent or received, including conversations you start from ReachHunt. Older conversations found while syncing an inbox do not fire it. # Conversation deleted Source: https://docs.reachhunt.ai/webhooks/events/conversation-deleted /openapi.json webhook conversation.deleted A conversation was deleted, from ReachHunt or on the platform. # Conversation unarchived Source: https://docs.reachhunt.ai/webhooks/events/conversation-unarchived /openapi.json webhook conversation.unarchived An archived conversation came back to the inbox, by a member or because a new message arrived. # Import completed Source: https://docs.reachhunt.ai/webhooks/events/import-completed /openapi.json webhook import.completed A lead import finished. # Import failed Source: https://docs.reachhunt.ai/webhooks/events/import-failed /openapi.json webhook import.failed A lead import failed. # Import paused Source: https://docs.reachhunt.ai/webhooks/events/import-paused /openapi.json webhook import.paused A lead import was paused, by a member or because it could not go on, for example when credits ran out or the account needs reconnecting. # Lead added to list Source: https://docs.reachhunt.ai/webhooks/events/lead-added-to-list /openapi.json webhook lead.added_to_list A lead was added to a lead list, by an import or a copy. Fires once per lead, so an import that adds 500 leads sends 500 events. # Lead assignee changed Source: https://docs.reachhunt.ai/webhooks/events/lead-assignee-changed /openapi.json webhook lead.assignee_changed A lead was assigned to a member, reassigned or unassigned. Removing a member from the workspace unassigns their leads, and fires this once for each of them. # Lead note changed Source: https://docs.reachhunt.ai/webhooks/events/lead-note-changed /openapi.json webhook lead.note_changed A lead's note was written, edited or cleared. # Lead status changed Source: https://docs.reachhunt.ai/webhooks/events/lead-status-changed /openapi.json webhook lead.status_changed A lead's pipeline status was set, changed or cleared. # Lead tag added Source: https://docs.reachhunt.ai/webhooks/events/lead-tag-added /openapi.json webhook lead.tag_added A tag was added to a lead. # Lead tag removed Source: https://docs.reachhunt.ai/webhooks/events/lead-tag-removed /openapi.json webhook lead.tag_removed A tag was removed from a lead. # Lead valuation changed Source: https://docs.reachhunt.ai/webhooks/events/lead-valuation-changed /openapi.json webhook lead.valuation_changed A lead's deal value was set, changed or cleared. # Message deleted Source: https://docs.reachhunt.ai/webhooks/events/message-deleted /openapi.json webhook message.deleted A DM was deleted, from ReachHunt or on the platform. On X, a message deleted on X itself, by you or by the lead, fires the next time ReachHunt syncs that conversation, for example when someone opens it or a message is sent in it. X does not report these deletes as they happen. # Message edited Source: https://docs.reachhunt.ai/webhooks/events/message-edited /openapi.json webhook message.edited A DM was edited, from ReachHunt or on the platform. # Message reaction added Source: https://docs.reachhunt.ai/webhooks/events/message-reaction-added /openapi.json webhook message.reaction_added Someone reacted to a DM. Fires for reactions from either side. Two people adding the same emoji fire two events. # Message reaction removed Source: https://docs.reachhunt.ai/webhooks/events/message-reaction-removed /openapi.json webhook message.reaction_removed A reaction was taken off a DM. # Message received Source: https://docs.reachhunt.ai/webhooks/events/message-received /openapi.json webhook message.received A lead sent a DM to one of your connected accounts. Fires for messages that are less than 10 minutes old when ReachHunt picks them up, so syncing an inbox for the first time does not replay its history. # Message seen Source: https://docs.reachhunt.ai/webhooks/events/message-seen /openapi.json webhook message.seen A lead read a DM sent from a connected account. Sent once, for the newest DM they had not read yet. When a lead reads several of your messages at once, you get one event, for the newest. Opening the conversation again fires nothing. The network has to report the read: a lead who turned read receipts off never fires it, and a read reported more than 10 minutes late is skipped. # Message sent Source: https://docs.reachhunt.ai/webhooks/events/message-sent /openapi.json webhook message.sent A DM was sent from a connected account: by a campaign, an AI agent, a member, or on the platform itself. Fires for messages that are less than 10 minutes old when ReachHunt picks them up. # Status created Source: https://docs.reachhunt.ai/webhooks/events/status-created /openapi.json webhook status.created A pipeline status was created. # Status deleted Source: https://docs.reachhunt.ai/webhooks/events/status-deleted /openapi.json webhook status.deleted A pipeline status was deleted and cleared from every lead. # Status updated Source: https://docs.reachhunt.ai/webhooks/events/status-updated /openapi.json webhook status.updated A pipeline status was renamed or recoloured. # Tag created Source: https://docs.reachhunt.ai/webhooks/events/tag-created /openapi.json webhook tag.created A tag was created. # Tag deleted Source: https://docs.reachhunt.ai/webhooks/events/tag-deleted /openapi.json webhook tag.deleted A tag was deleted and removed from every lead. # Tag updated Source: https://docs.reachhunt.ai/webhooks/events/tag-updated /openapi.json webhook tag.updated A tag was renamed or recoloured. # Webhooks overview Source: https://docs.reachhunt.ai/webhooks/overview Get notified when something changes in your workspace A webhook is an HTTPS `POST` ReachHunt sends to your server when something changes: a lead replies, a campaign finishes, a tag is added. ## Add a webhook **1. Open webhooks** In ReachHunt, open [**Settings → Webhooks**](https://app.reachhunt.ai/settings/webhooks) and select **Add webhook**. **2. Set it up** Enter a name and your `https://` URL, and pick the events it receives. Add a secret header so your server can [check each request](/webhooks/receiving#check-that-a-request-came-from-reachhunt). **3. Test it** Open the webhook's menu and select **Send test event**. A workspace can have up to 10 webhooks, and you need full access to **Developer** to manage them. ## The event Every event has the same envelope: ```json theme={"system"} { "id": "evt_9f1c3b7a-2d4e-4c6a-8b1f-0e3d5c7a9b21", "type": "tag.created", "apiVersion": "1", "createdAt": "2026-10-19T10:32:00.000Z", "workspaceId": "c2a9e1f4-7b3d-4e8a-9f1c-5d6e7a8b9c01", "data": { "tag": { "id": "0c9e7a52-4d1b-4f3e-8a6c-2b5d9e1f7a30", "name": "Hot lead", "color": "#f97316" } } } ``` | Field | Notes | | - | - | | `id` | Unique per event. Every webhook that gets it sees the same `id`, and retries keep it. Deduplicate on it | | `type` | `resource.action`, such as `message.received` | | `apiVersion` | The payload version, now `1` | | `createdAt` | When it happened | | `workspaceId` | Your workspace | | `data` | What happened. Each event type has its own fields | ### Headers | Header | Value | | - | - | | `Content-Type` | `application/json` | | `User-Agent` | `ReachHunt-Webhooks/1.0` | | `X-ReachHunt-Event` | The event type | | `X-ReachHunt-Delivery` | The delivery ID. Retries keep it | Every request also carries the headers you added to the webhook. > [!NOTE] > > ReachHunt does not sign requests. Add a secret header to the webhook and reject any request without it, see [Receiving webhooks](/webhooks/receiving#check-that-a-request-came-from-reachhunt). ## Event types | Resource | Events | `data` | | - | - | - | | Message | [`message.received`](/webhooks/events/message-received), [`message.sent`](/webhooks/events/message-sent) | `{ account, contact, message, sentBy }` | | | [`message.seen`](/webhooks/events/message-seen) | `{ account, contact, message, sentBy, seenAt }` | | | [`message.edited`](/webhooks/events/message-edited) | `{ account, contact, message, previousText }` | | | [`message.deleted`](/webhooks/events/message-deleted) | `{ account, contact, message }` | | | [`message.reaction_added`](/webhooks/events/message-reaction-added), [`message.reaction_removed`](/webhooks/events/message-reaction-removed) | `{ account, contact, message, reaction }` | | Conversation | [`conversation.created`](/webhooks/events/conversation-created), [`conversation.deleted`](/webhooks/events/conversation-deleted), [`conversation.archived`](/webhooks/events/conversation-archived), [`conversation.unarchived`](/webhooks/events/conversation-unarchived) | `{ account, conversation, contact }` | | Lead | [`lead.added_to_list`](/webhooks/events/lead-added-to-list) | `{ list, lead }` | | | [`lead.status_changed`](/webhooks/events/lead-status-changed) | `{ lead, previousStatus, status }` | | | [`lead.tag_added`](/webhooks/events/lead-tag-added), [`lead.tag_removed`](/webhooks/events/lead-tag-removed) | `{ lead, tag }` | | | [`lead.note_changed`](/webhooks/events/lead-note-changed) | `{ lead, note }` | | | [`lead.valuation_changed`](/webhooks/events/lead-valuation-changed) | `{ lead, previousValuation, valuation }` | | | [`lead.assignee_changed`](/webhooks/events/lead-assignee-changed) | `{ lead, previousAssignee, assignee }` | | Campaign | [`campaign.created`](/webhooks/events/campaign-created), [`campaign.started`](/webhooks/events/campaign-started), [`campaign.paused`](/webhooks/events/campaign-paused), [`campaign.resumed`](/webhooks/events/campaign-resumed), [`campaign.completed`](/webhooks/events/campaign-completed), [`campaign.stopped`](/webhooks/events/campaign-stopped) | `{ campaign }` | | Campaign lead | [`campaign.lead_contacted`](/webhooks/events/campaign-lead-contacted), [`campaign.follow_up_sent`](/webhooks/events/campaign-follow-up-sent) | `{ campaign, account, lead, messagesSent, stepType }` | | | [`campaign.lead_replied`](/webhooks/events/campaign-lead-replied) | `{ campaign, account, lead, repliedAt }` | | | [`campaign.lead_failed`](/webhooks/events/campaign-lead-failed) | `{ campaign, account, lead, stepType, error }` | | | [`connection_request.sent`](/webhooks/events/connection-request-sent) | `{ campaign, account, lead, withNote }` | | | [`connection_request.accepted`](/webhooks/events/connection-request-accepted), [`connection_request.withdrawn`](/webhooks/events/connection-request-withdrawn) | `{ campaign, account, lead }` | | Account | [`account.connected`](/webhooks/events/account-connected) | `{ account }` | | | [`account.disconnected`](/webhooks/events/account-disconnected) | `{ account, reason, detail }` | | Import | [`import.completed`](/webhooks/events/import-completed), [`import.paused`](/webhooks/events/import-paused), [`import.failed`](/webhooks/events/import-failed) | `{ import }` | | Tag | [`tag.created`](/webhooks/events/tag-created), [`tag.updated`](/webhooks/events/tag-updated), [`tag.deleted`](/webhooks/events/tag-deleted) | `{ tag }` | | Status | [`status.created`](/webhooks/events/status-created), [`status.updated`](/webhooks/events/status-updated), [`status.deleted`](/webhooks/events/status-deleted) | `{ status }` | Each event type has its own page under **Event types** with its full schema. * New event types are not added to existing webhooks. Edit a webhook to start receiving them. * Payloads follow the API's [conventions](/developer-api/response-format#conventions): camelCase names, timestamps in ISO 8601 UTC, and `null` for a value that does not apply. * New event types and `data` fields can be added within version `1`. Ignore what you don't know. ## Limits * Up to 10 webhooks in a workspace. * Up to 5 custom headers on a webhook. * The URL must start with `https://`, point to a public address, and be at most 2048 characters. * Your server has 10 seconds to answer. > **[Receiving webhooks](/webhooks/receiving)** > > Answer deliveries, check they came from ReachHunt, and handle retries. # Receiving webhooks Source: https://docs.reachhunt.ai/webhooks/receiving Answer deliveries, check they came from ReachHunt, and handle retries Your server gets each event as an HTTPS `POST` with a JSON body. This page covers how to answer it, check that it came from ReachHunt, and handle retries. ## Answer quickly Answer with any `2xx` status within 10 seconds. Redirects are not followed: a `3xx` counts as a failure. 1. Answer with `2xx` first, then do the work. 2. Skip an `id` you already handled. The same event can arrive more than once, for example when your server worked but answered too late. 3. Compare `createdAt` when order matters. Events can arrive out of order, for example when one is retried. ## Check that a request came from ReachHunt ReachHunt doesn't sign requests. Add a secret header to the webhook instead, then reject any request that doesn't carry it. **1. Add a secret header** In [**Settings → Webhooks**](https://app.reachhunt.ai/settings/webhooks), select **Add a secret header** when you add or edit a webhook. For example, use `X-Webhook-Secret` with a long random value. **2. Check it on your server** Compare the header with the value you saved, using a constant-time comparison. Answer `401` when it doesn't match. The header is sent with every request, including retries and test events. Keep its value only on your server. ## Example handler ```js Node.js theme={"system"} import crypto from 'node:crypto'; import express from 'express'; const app = express(); const secret = Buffer.from(process.env.REACHHUNT_WEBHOOK_SECRET); const handled = new Set(); const fromReachHunt = (value = '') => { const received = Buffer.from(value); return received.length === secret.length && crypto.timingSafeEqual(received, secret); }; app.post('/webhooks/reachhunt', express.json(), (req, res) => { if (!fromReachHunt(req.get('X-Webhook-Secret'))) return res.sendStatus(401); res.sendStatus(200); const event = req.body; if (handled.has(event.id)) return; handled.add(event.id); if (event.type === 'message.received') { console.log('New message:', event.data.message.text); } }); app.listen(3000); ``` ```python Python theme={"system"} import hmac import os from flask import Flask, request app = Flask(__name__) SECRET = os.environ["REACHHUNT_WEBHOOK_SECRET"] handled = set() @app.post("/webhooks/reachhunt") def reachhunt_webhook(): if not hmac.compare_digest(request.headers.get("X-Webhook-Secret", ""), SECRET): return "", 401 event = request.get_json() if event["id"] not in handled: handled.add(event["id"]) if event["type"] == "message.received": print("New message:", event["data"]["message"]["text"]) return "", 200 ``` In production, store handled IDs in your database, and hand slow work to a queue so you still answer within 10 seconds. ## Retries ReachHunt tries a delivery again when your server: * does not answer within 10 seconds, or cannot be reached * answers `408`, `429` or any `5xx` It retries 6 times, after 1 minute, 5 minutes, 30 minutes, 1 hour, 6 hours and 24 hours. Any other answer, such as `400` or `401`, fails the delivery at once, without retries. ## Turning off ReachHunt turns a webhook off when: * your server answers `404` or `410`, or the URL points to an address ReachHunt does not send to * an event fails all its retries and nothing else reached your server since that event happened The webhook shows as **Off** in [**Settings → Webhooks**](https://app.reachhunt.ai/settings/webhooks), with the reason. While it is off it gets no events, and events from that time are not sent later. Fix your server, then turn the webhook back on from its menu in [**Settings → Webhooks**](https://app.reachhunt.ai/settings/webhooks). ## Testing Open the menu on your webhook in [**Settings → Webhooks**](https://app.reachhunt.ai/settings/webhooks) and select **Send test event**. It sends a sample of the event you pick, with your headers, and shows how your server answered. A test event's `id` starts with `test_`. ## Common mistakes | Mistake | Do this instead | | - | - | | Doing the work before answering | Answer `2xx` first, then do the work or queue it | | Comparing the secret with `==` | Use a constant-time comparison, such as `crypto.timingSafeEqual` or `hmac.compare_digest` | | Handling the same event twice | Store each event `id` and skip the ones you've seen | | Expecting events in order | Compare `createdAt` | | Pointing the webhook at a URL that redirects | Use the final URL. A `3xx` counts as a failure | | Answering `404` while you deploy | Answer `503` instead. ReachHunt retries `5xx`, but turns the webhook off on `404` or `410` |