# Prospy documentation Everything about Prospy in one file: using the app, the MCP server, the REST API and webhooks. # Start here What Prospy does, how to set up your first project and what each plan includes. Prospy watches X, Reddit, Hacker News, Bluesky, YouTube, LinkedIn, Threads, TikTok, Quora, Product Hunt, GitHub and Medium for your keywords, every source on by default. Every match is scored by AI, so you see the people already asking for what you sell. ## Set up in 4 steps 1. **Create a project.** [Sign in](/auth) and add your project’s name and website. Describe your product and who it helps; Prospy uses this to judge relevance. 2. **Add keywords.** Open Settings → Keywords. Start with your brand, a few competitors and the phrases people use when they look for a solution. See [Keywords](/docs/keywords). 3. **Review your feed.** Open [Home](/home). Sources are scanned periodically, so new matches arrive over the next scans, not the second you save. See [Your feed](/docs/feed). 4. **Turn on alerts.** Get the best conversations in email, Slack or Discord. See [Alerts](/docs/alerts). ## Plans and limits The project owner’s plan sets the project’s allowance. Manage your subscription in [Billing](/billing). | Allowance | Explorer Pass | Basic | Pro | | --- | --- | --- | --- | | Mentions per month | 500 | 1000 | 10000 | | Alert rules | 3 | 5 | 25 | | Webhook endpoints | 1 | 2 | 10 | | API keys | 1 | 2 | 10 | | Team seats | 1 | 1 | 5 | | API requests per minute | 30 | 60 | 120 | A limit is a cap, not a promise that sources will find that many posts. API and MCP access need an active subscription. --- # Keywords Choose keywords, exclusions, groups and sources, and understand how often Prospy scans. A keyword is a phrase Prospy searches for. Manage them in Settings → Keywords. ## Pick good keywords Use specific phrases: your brand, competitor names and the problem your product solves (“alternative to Brand24”, “track Reddit mentions”). Avoid broad single words that mean many things. - **Aliases** catch other names and spellings. - **Exclusions** drop common false positives. Add one at a time and compare the next scan. - **Exact match** keeps short or common words from matching loosely. - **Disable** a keyword to pause it without deleting it. Changing a keyword does not remove mentions you already have. ## Group keywords Groups keep brand, competitor and custom searches apart, so you can filter the feed or point an alert at a whole group. Built-in groups can’t be deleted; custom groups can. ## Choose sources New keywords watch every source: X, Reddit, Hacker News, Bluesky, YouTube, LinkedIn, Threads, TikTok captions, Quora, Product Hunt, GitHub issues and Medium. Turn sources off per keyword in settings. In the API, `platforms: null` means every source, including ones added later; pass a list to limit a keyword to those sources. Coverage differs by source. Threads and Quora show a small window of recent posts, and TikTok, Product Hunt and Medium rank by relevance, so older posts can fall outside the lookback window. ## Freshness Sources are scanned periodically. A post’s date is when it was published; Prospy may find an older post later. A quiet feed doesn’t prove nobody talked about the topic. If you expect results and see none, check the project, whether the keyword is enabled, its sources and exclusions, and your monthly usage. --- # Your feed Read AI scores, triage mentions, filter and save views, organize with categories and find leads. Every post that matches your keywords lands in your feed on [Home](/home), scored by AI. ## Read a mention Each mention shows the post, its author, source and date. Open the original link before you reply; engagement may have changed since Prospy collected it. - **Intent**: buyer, switching, question, complaint, praise or none. - **Sentiment**: positive, neutral or negative. - **Lead score**: 0 to 100. Higher means more worth your time. These are model judgments, not facts. A high score doesn’t confirm budget or that someone wants to be contacted, and a negative post can still be a good opportunity. If matches are often off-topic, improve your project description and keywords. ## Triage | Status | Use it when | | --- | --- | | Open | You haven’t dealt with it yet. | | Follow-up | You replied or plan to, and want it in your queue. | | Done | Nothing left to do. | **Mark irrelevant** when a match doesn’t belong. It removes the mention and stops the same post from coming back. You can also block its author. Changing status needs editor or owner access. ## Filter and save views Filter by platform, status, sentiment, intent, category, keyword, keyword group, author, minimum lead score, date or text. Sort by newest, oldest, lead score, engagement or Google rank. Save a combination as a view; it stores the filters, so its results update as new mentions arrive. ## Ranking on Google Once a day, Prospy checks where the Reddit, Hacker News and YouTube threads it finds rank on Google (US, top 20) for their keyword. Threads that rank get a “Ranks #N on Google” badge, and the **Ranking on Google** tab lists them best position first. A helpful reply on one of them keeps getting read for months, by people searching and often by the AI assistants that quote these pages. Positions change, so treat them as a guide. To work through them with Claude, ChatGPT or another assistant, see [Connect your AI](/docs/mcp). ## Categories Create categories in Settings → Categories, then assign them to mentions and filter by them. Deleting a category keeps its mentions. ## Leads and analytics [Leads](/leads) lists the people and conversations worth a closer look. [Analytics](/analytics) shows mention volume and sentiment over time. A change can come from keyword edits or scan timing, not only from the conversation itself. --- # Alerts Send the conversations that matter to email, Slack, Discord or your own webhook, and get a daily digest. ## Create an alert Open [Alerts](/alerts) and click **New alert**. Pick the project (or several) and either all keywords or just the ones you care about, then a destination: email, Slack, Discord or a webhook. Narrow it with a minimum lead score, categories or sentiment, then send a test before relying on it. Alerts count toward your plan’s alert rules. If a notification is missing, check the destination and the delivery status. A rule matching a mention and the destination accepting it are separate steps. ## Webhook payload A webhook alert sends a JSON `POST` to any public HTTPS URL, such as a Zapier, Make or n8n hook or your own server. Any 2xx response counts as delivered; anything else, including a timeout, is retried for about 20 minutes. Every request has a `webhook-id` header that stays the same across retries, so you can skip duplicates. ```json { "type": "alert.mentions", "timestamp": "2026-11-09T12:00:00.000Z", "data": { "alert": { "name": "meal planning app → Webhook" }, "project": { "id": "c08dcbee-…", "name": "PantryAI" }, "mentionCount": 1, "mentions": [ { "id": "…", "platform": "reddit", "author": "5pinktoes", "title": "What are your top five most expensive items on your grocery list?", "content": "…", "url": "https://www.reddit.com/r/…", "leadScore": 82, "category": "Looking for a tool", "sentiment": "neutral", "subreddit": "Frugal", "prospyUrl": "https://prospy.io/home?projectId=…&mentionId=…" } ] } } ``` The daily digest can go to a webhook too. Its `type` is `digest.daily` and `data` holds the counts and the top mentions. For signed, event-based deliveries (new mention, status changes), use [Integrations → Webhooks](/integrations/webhooks) instead. ## Daily digest In project settings, turn on the daily digest and choose the hour. Set the project timezone so the hour means what you expect. Use alerts for urgent conversations and the digest for the rest. --- # Team Invite teammates with the right role and publish a read-only public dashboard. ## Invite your team Open [Team](/team) in the right project. Owners invite members within the plan’s seats and set their roles. | Role | Can | | --- | --- | | Viewer | Read the project, mentions and analytics. | | Editor | Also change keywords, mentions and integrations. | | Owner | Also manage members, billing, the public page and deletion. | API keys never raise a user’s role. A full-scope key can only do what its owner’s role allows. ## Public dashboard Owners can publish a read-only page at `/mentions/{slug}` from [Integrations → Public page](/integrations/public). Slugs are 3–40 lowercase letters, numbers or hyphens, and start and end with a letter or number. The page shows public mention text, links, authors, dates and sentiment totals. Private notes and internal scoring stay private. Turn publishing off to take it down. --- # Connect your AI Connect Claude, ChatGPT, Grok or Cursor to Prospy over MCP, and let your agent research threads and draft replies you post yourself. Prospy has a remote MCP server, so the AI assistant you already use can read your scored, ranked threads, research them and draft replies in your voice. You review every reply and post it from your own account: Prospy has no tool that posts, comments, votes or sends messages. ## The workflow 1. **Prospy finds, scores and ranks.** New posts from your keywords, scored for relevance and buying intent, with the Google position of threads that rank. See [Your feed](/docs/feed). 2. **Your agent reads and drafts.** It calls `find_reply_opportunities`, reads the threads and drafts replies that answer the question first and disclose that you work on your product. 3. **You review and post.** Edit the words, check the community’s self-promotion rules and post as yourself. ## Add the server Server URL: `https://prospy.io/api/mcp` (Streamable HTTP). - **Claude Code**: `claude mcp add --transport http prospy https://prospy.io/api/mcp`. Run in your terminal, then sign in when asked. - **Claude**: `https://prospy.io/api/mcp`. Settings → Connectors → Add custom connector, then paste the URL. - **ChatGPT**: `https://prospy.io/api/mcp`. Settings → Connectors → Create, then paste the URL. - **Cursor**: `{ "mcpServers": { "prospy": { "url": "https://prospy.io/api/mcp" } } }`. Add to .cursor/mcp.json. - **Grok and others**: `https://prospy.io/api/mcp`. Any client that supports remote MCP servers: paste the URL and sign in, or send an API key as a bearer token. Your client opens a Prospy sign-in and asks you to approve access (OAuth 2.1 with PKCE). Prefer a key? Create one in [Integrations → API & MCP](/integrations/api) and send `Authorization: Bearer `. Never paste a key into a shared chat. Signed in, [Integrations → AI agent](/integrations/agent) has the setup for each client and ready-to-paste prompts. ## Prompts The server ships prompts that run the workflow. Clients that support MCP prompts list them; in Claude Code they are slash commands such as `/mcp__prospy__reply-plan`. | Prompt | Arguments | What it does | | --- | --- | --- | | `reply-plan` | `projectId`, `days`, `limit` (all optional) | Pulls high-intent threads and threads ranking on Google, summarises each question, outlines a helpful, disclosed reply, flags community rules and writes the top 3 in your voice. | | `daily-brief` | `projectId` (optional) | What is new since yesterday, the five threads to act on, threads ranking on Google and anything negative. | | `reply-to-thread` | `mentionId` | One thread: what they ask, whether a reply would help, and a reply in your voice. The robot button on a post in your feed copies the same prompt. | ## Try asking - “Plan my replies for this week.” - “Which threads rank on Google for my keywords, and what could a reply add?” - “Which mentions this week show buying intent?” - “Add ‘alternative to Brand24’ as a keyword on Reddit and X.” ## Tools Each tool has the same name and arguments as an [API](/docs/api) operation, plus `find_reply_opportunities`, which exists only on MCP. Start with `list_projects` (or `create_project` if you have none), then `find_reply_opportunities` or `list_mentions` with a `projectId`. Path and query values are top-level arguments; fields for writes go inside `input`. `find_reply_opportunities` takes `projectId`, `days` (default 7), `limit` (default 10) and `minLeadScore` (default 40). It returns `highIntent` and `rankingOnGoogle`: open and follow-up threads with their URL, platform, community, lead score, intent, matched keyword and `google.position` when they rank. ```json {"name":"list_mentions","arguments":{"projectId":"00000000-0000-4000-8000-000000000001","limit":25,"ranksOnGoogle":true,"sort":"google_rank"}} ``` Results are JSON under `result`. Errors set `isError` with a code and message. Read-scope keys only see read tools; writes need a full-scope credential and the editor role. --- # API Authenticate, page through mentions, handle errors, and every REST endpoint on one page. Base URL: `https://prospy.io/api/v1`. The full schema is the [OpenAPI 3.1 spec](/api/v1/openapi.json). ## Authenticate Create a key in [Integrations → API & MCP](/integrations/api) and keep it server-side. Keys start with `psy_live_` and are shown once. Read keys allow GET requests; full keys also allow writes within your project role. An active subscription is required. ```bash curl https://prospy.io/api/v1/projects \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` ## Paginate List mentions returns `data` and `nextCursor`. `limit` is 1–100 (default 25). Pass `nextCursor` back as `cursor` with the same filters and sort, and stop when it is null. Arrays accept repeated or comma-separated values: `platforms=Twitter,Reddit`. Dates are ISO 8601; `from` is inclusive and `to` exclusive. ## Handle errors Errors look like `{"error":{"code":"validation_error","message":"Invalid request"}}`. | Status | What to do | | --- | --- | | 400 | Fix parameter types, required fields or JSON. | | 401 | Check the key and whether it was revoked. | | 403 | Check subscription, key scope and project role. | | 404 | Check the path and resource ID. | | 409 | Resolve the conflict or idempotency-key mismatch. | | 429 | Wait for `Retry-After`. Limits are per user across all keys and MCP. | | 500 | Retry with backoff. | Send an `Idempotency-Key` on POST to retry safely. Responses replay for 24 hours; reusing a key for a different request returns 409. ## Projects endpoints ### GET /me Get the API key's user identifier and actor context. MCP tool: `get_me`. Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/me' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"get_me","arguments":{}}` ### GET /projects List projects the actor can access, including their role. MCP tool: `list_projects`. Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_projects","arguments":{}}` ### POST /projects Create a project owned by the actor, with optional starting brand and competitor keywords, within plan limits, and start its first scan. MCP tool: `create_project`. JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | Yes | string | Minimum length: 1. Maximum length: 200. | | `url` | No | string | Format: uri. | | `timezone` | No | string | Minimum length: 1. Maximum length: 100. | | `brandKeywords` | No | string[] | Brand and product keywords, added to the Brand group. Maximum items: 100. | | `competitorKeywords` | No | string[] | Competitor names, added to the Competitors group. Maximum items: 100. | | `platforms` | No | ("Twitter" \| "Reddit" \| "HackerNews" \| "Bluesky" \| "YouTube" \| "LinkedIn" \| "Threads" \| "TikTok" \| "Quora" \| "ProductHunt" \| "GitHub" \| "Medium")[] | Platforms the starting keywords watch. Omit to watch every platform. Maximum items: 12. | | `categories` | No | object[] | Replaces the default mention categories. Maximum items: 50. | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/projects' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example"}' ``` MCP: `{"name":"create_project","arguments":{"input":{"name":"Example"}}}` ### GET /projects/{projectId} Get a project. Requires viewer access. MCP tool: `get_project`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"get_project","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### PATCH /projects/{projectId} Update project settings; public settings require owner access. MCP tool: `update_project`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | No | string | Minimum length: 1. Maximum length: 200. | | `url` | No | string | Format: uri. | | `timezone` | No | string | Minimum length: 1. Maximum length: 100. | | `digestEnabled` | No | boolean | | | `digestHour` | No | integer | Minimum: 0. Maximum: 23. | | `isPublic` | No | boolean | | | `publicSlug` | No | string \| null | | | `publicDescription` | No | string \| null | | Scope: full. Needs editor role or higher. ```bash curl -X PATCH 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example"}' ``` MCP: `{"name":"update_project","arguments":{"projectId":"00000000-0000-4000-8000-000000000001","input":{"name":"Example"}}}` ### GET /projects/{projectId}/usage Get current monthly usage against the project owner's plan. MCP tool: `get_usage`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/usage' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"get_usage","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### GET /projects/{projectId}/analytics Aggregate mentions over an ISO date range; defaults to the last 30 days. MCP tool: `get_analytics`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | | `from` | query | No | string | Format: date-time. | | `to` | query | No | string | Format: date-time. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/analytics' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"get_analytics","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ## Mentions endpoints ### GET /projects/{projectId}/mentions Search mentions by dates, platforms, statuses, sentiments, intents, categories, keywords, groups, author, lead score, text and Google ranking (ranksOnGoogle, sort google_rank), with cursor pagination. MCP tool: `list_mentions`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | | `from` | query | No | string | Format: date-time. | | `to` | query | No | string | Format: date-time. | | `platforms` | query | No | ("Twitter" \| "Reddit" \| "HackerNews" \| "Bluesky" \| "YouTube" \| "LinkedIn" \| "Threads" \| "TikTok" \| "Quora" \| "ProductHunt" \| "GitHub" \| "Medium")[] | Maximum items: 12. | | `statuses` | query | No | ("open" \| "done" \| "follow_up")[] | Maximum items: 3. | | `sentiments` | query | No | ("positive" \| "neutral" \| "negative")[] | Maximum items: 3. | | `intents` | query | No | ("buyer" \| "switching" \| "question" \| "complaint" \| "praise" \| "none")[] | Maximum items: 6. | | `categoryIds` | query | No | string[] | Maximum items: 100. | | `keywordIds` | query | No | string[] | Maximum items: 100. | | `keywordGroupIds` | query | No | string[] | Maximum items: 100. | | `author` | query | No | string | Minimum length: 1. Maximum length: 100. | | `minLeadScore` | query | No | integer | Minimum: 0. Maximum: 100. | | `search` | query | No | string | Minimum length: 1. Maximum length: 200. | | `ranksOnGoogle` | query | No | boolean | | | `sort` | query | No | "newest" \| "oldest" \| "lead_score" \| "engagement" \| "google_rank" | | | `limit` | query | No | integer | Minimum: 1. Maximum: 100. Default: 25. | | `cursor` | query | No | string | Maximum length: 500. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/mentions' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_mentions","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### GET /mentions/{id} Get one mention. Requires viewer access. MCP tool: `get_mention`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/mentions/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"get_mention","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ### PATCH /mentions/{id} Update a mention's status or category. Requires editor access. MCP tool: `update_mention_status`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `status` | No | "open" \| "done" \| "follow_up" | | | `feedback` | No | "good" \| "bad" \| null | | | `categoryId` | No | string \| null | | Scope: full. Needs editor role or higher. ```bash curl -X PATCH 'https://prospy.io/api/v1/mentions/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"status":"open"}' ``` MCP: `{"name":"update_mention_status","arguments":{"id":"00000000-0000-4000-8000-000000000001","input":{"status":"open"}}}` ### POST /mentions/{id}/irrelevant Delete and block re-ingestion of an irrelevant mention, optionally blocking its author. Requires editor access. MCP tool: `mark_mention_irrelevant`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `blockAuthor` | No | boolean | | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/mentions/00000000-0000-4000-8000-000000000001/irrelevant' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"blockAuthor":true}' ``` MCP: `{"name":"mark_mention_irrelevant","arguments":{"id":"00000000-0000-4000-8000-000000000001","input":{"blockAuthor":true}}}` ### POST /mentions/{id}/translate Translate a mention to English and return it. Requires editor access. MCP tool: `translate_mention`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/mentions/00000000-0000-4000-8000-000000000001/translate' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"translate_mention","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ## Keywords endpoints ### GET /projects/{projectId}/keyword-groups List a project's keyword groups. MCP tool: `list_keyword_groups`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/keyword-groups' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_keyword_groups","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### POST /projects/{projectId}/keyword-groups Create a keyword group. Requires editor access. MCP tool: `create_keyword_group`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | Yes | string | Minimum length: 1. Maximum length: 200. | | `kind` | No | "brand" \| "competitors" \| "custom" | | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/keyword-groups' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example"}' ``` MCP: `{"name":"create_keyword_group","arguments":{"projectId":"00000000-0000-4000-8000-000000000001","input":{"name":"Example"}}}` ### PATCH /keyword-groups/{id} Rename or reorder a keyword group. MCP tool: `update_keyword_group`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | No | string | Minimum length: 1. Maximum length: 200. | | `position` | No | integer | Minimum: 0. Maximum: 10000. | Scope: full. Needs editor role or higher. ```bash curl -X PATCH 'https://prospy.io/api/v1/keyword-groups/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example"}' ``` MCP: `{"name":"update_keyword_group","arguments":{"id":"00000000-0000-4000-8000-000000000001","input":{"name":"Example"}}}` ### DELETE /keyword-groups/{id} Delete a custom keyword group; built-in groups are protected. MCP tool: `delete_keyword_group`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X DELETE 'https://prospy.io/api/v1/keyword-groups/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"delete_keyword_group","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ### GET /projects/{projectId}/keywords List a project's keywords and matching settings. MCP tool: `list_keywords`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/keywords' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_keywords","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### POST /projects/{projectId}/keywords Create a keyword within plan limits. Requires editor access. MCP tool: `create_keyword`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `keyword` | Yes | string | Minimum length: 1. Maximum length: 200. | | `groupId` | No | string \| null | | | `platforms` | No | ("Twitter" \| "Reddit" \| "HackerNews" \| "Bluesky" \| "YouTube" \| "LinkedIn" \| "Threads" \| "TikTok" \| "Quora" \| "ProductHunt" \| "GitHub" \| "Medium")[] \| null | | | `aliases` | No | string[] | Maximum items: 100. | | `excludeTerms` | No | string[] | Maximum items: 100. | | `exactMatch` | No | boolean | | | `enabled` | No | boolean | | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/keywords' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"keyword":"social listening"}' ``` MCP: `{"name":"create_keyword","arguments":{"projectId":"00000000-0000-4000-8000-000000000001","input":{"keyword":"social listening"}}}` ### PATCH /keywords/{id} Update keyword matching settings. Requires editor access. MCP tool: `update_keyword`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `keyword` | No | string | Minimum length: 1. Maximum length: 200. | | `groupId` | No | string \| null | | | `platforms` | No | ("Twitter" \| "Reddit" \| "HackerNews" \| "Bluesky" \| "YouTube" \| "LinkedIn" \| "Threads" \| "TikTok" \| "Quora" \| "ProductHunt" \| "GitHub" \| "Medium")[] \| null | | | `aliases` | No | string[] | Maximum items: 100. | | `excludeTerms` | No | string[] | Maximum items: 100. | | `exactMatch` | No | boolean | | | `enabled` | No | boolean | | Scope: full. Needs editor role or higher. ```bash curl -X PATCH 'https://prospy.io/api/v1/keywords/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"keyword":"social listening"}' ``` MCP: `{"name":"update_keyword","arguments":{"id":"00000000-0000-4000-8000-000000000001","input":{"keyword":"social listening"}}}` ### DELETE /keywords/{id} Delete a keyword. Requires editor access. MCP tool: `delete_keyword`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X DELETE 'https://prospy.io/api/v1/keywords/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"delete_keyword","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ## Categories and views endpoints ### GET /projects/{projectId}/categories List a project's categories. MCP tool: `list_categories`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/categories' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_categories","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### POST /projects/{projectId}/categories Create a mention category. Requires editor access. MCP tool: `create_category`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | Yes | string | Minimum length: 1. Maximum length: 200. | | `description` | No | string | Maximum length: 2000. | | `color` | No | string | Minimum length: 1. Maximum length: 40. | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/categories' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example"}' ``` MCP: `{"name":"create_category","arguments":{"projectId":"00000000-0000-4000-8000-000000000001","input":{"name":"Example"}}}` ### PATCH /categories/{id} Update a category's name, description, color or position. MCP tool: `update_category`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | No | string | Minimum length: 1. Maximum length: 200. | | `description` | No | string | Maximum length: 2000. | | `color` | No | string | Minimum length: 1. Maximum length: 40. | | `position` | No | integer | Minimum: 0. Maximum: 10000. | Scope: full. Needs editor role or higher. ```bash curl -X PATCH 'https://prospy.io/api/v1/categories/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example"}' ``` MCP: `{"name":"update_category","arguments":{"id":"00000000-0000-4000-8000-000000000001","input":{"name":"Example"}}}` ### DELETE /categories/{id} Delete a category, preserving its mentions without that category. MCP tool: `delete_category`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X DELETE 'https://prospy.io/api/v1/categories/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"delete_category","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ### GET /projects/{projectId}/saved-views List saved mention filters. MCP tool: `list_saved_views`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/saved-views' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_saved_views","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### POST /projects/{projectId}/saved-views Save a named set of mention filters. MCP tool: `create_saved_view`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | Yes | string | Minimum length: 1. Maximum length: 200. | | `filters` | Yes | object | | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/saved-views' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example","filters":{"from":"2026-10-01T00:00:00Z"}}' ``` MCP: `{"name":"create_saved_view","arguments":{"projectId":"00000000-0000-4000-8000-000000000001","input":{"name":"Example","filters":{"from":"2026-10-01T00:00:00Z"}}}}` ### PATCH /saved-views/{id} Update a saved view's name, filters or position. MCP tool: `update_saved_view`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | No | string | Minimum length: 1. Maximum length: 200. | | `filters` | No | object | | | `position` | No | integer | Minimum: 0. Maximum: 10000. | Scope: full. Needs editor role or higher. ```bash curl -X PATCH 'https://prospy.io/api/v1/saved-views/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example"}' ``` MCP: `{"name":"update_saved_view","arguments":{"id":"00000000-0000-4000-8000-000000000001","input":{"name":"Example"}}}` ### DELETE /saved-views/{id} Delete a saved view. MCP tool: `delete_saved_view`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X DELETE 'https://prospy.io/api/v1/saved-views/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"delete_saved_view","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ## Alerts endpoints ### GET /projects/{projectId}/alerts List project alert rules. MCP tool: `list_alerts`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/alerts' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_alerts","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### POST /projects/{projectId}/alerts Create an email, Slack or Discord alert within plan limits. MCP tool: `create_alert`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | Yes | string | Minimum length: 1. Maximum length: 200. | | `targetType` | Yes | "all" \| "group" \| "keyword" \| "author" | | | `targetId` | No | string \| null | | | `targetValue` | No | string \| null | | | `minLeadScore` | No | integer | Minimum: 0. Maximum: 100. | | `categoryIds` | No | string[] | Maximum items: 100. | | `sentiments` | No | ("positive" \| "neutral" \| "negative")[] | Maximum items: 3. | | `channel` | Yes | "email" \| "slack" \| "discord" \| "webhook" | | | `destination` | Yes | string | Minimum length: 1. Maximum length: 2000. | | `enabled` | No | boolean | | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/alerts' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example","targetType":"all","channel":"email","destination":"alerts@example.com"}' ``` MCP: `{"name":"create_alert","arguments":{"projectId":"00000000-0000-4000-8000-000000000001","input":{"name":"Example","targetType":"all","channel":"email","destination":"alerts@example.com"}}}` ### PATCH /alerts/{id} Update an alert rule. Requires editor access. MCP tool: `update_alert`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `name` | No | string | Minimum length: 1. Maximum length: 200. | | `targetType` | No | "all" \| "group" \| "keyword" \| "author" | | | `targetId` | No | string \| null | | | `targetValue` | No | string \| null | | | `minLeadScore` | No | integer | Minimum: 0. Maximum: 100. | | `categoryIds` | No | string[] | Maximum items: 100. | | `sentiments` | No | ("positive" \| "neutral" \| "negative")[] | Maximum items: 3. | | `channel` | No | "email" \| "slack" \| "discord" \| "webhook" | | | `destination` | No | string | Minimum length: 1. Maximum length: 2000. | | `enabled` | No | boolean | | Scope: full. Needs editor role or higher. ```bash curl -X PATCH 'https://prospy.io/api/v1/alerts/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Example"}' ``` MCP: `{"name":"update_alert","arguments":{"id":"00000000-0000-4000-8000-000000000001","input":{"name":"Example"}}}` ### DELETE /alerts/{id} Delete an alert rule. MCP tool: `delete_alert`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X DELETE 'https://prospy.io/api/v1/alerts/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"delete_alert","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ### POST /alerts/{id}/test Send a test notification to an alert destination. MCP tool: `test_alert`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/alerts/00000000-0000-4000-8000-000000000001/test' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"test_alert","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ## Webhooks endpoints ### GET /projects/{projectId}/webhooks List webhook endpoints without signing secrets. MCP tool: `list_webhooks`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/webhooks' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_webhooks","arguments":{"projectId":"00000000-0000-4000-8000-000000000001"}}` ### POST /projects/{projectId}/webhooks Create a webhook endpoint; returns the signing secret once. MCP tool: `create_webhook`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `projectId` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `url` | Yes | string | Format: uri. | | `description` | No | string | Maximum length: 2000. | | `eventTypes` | No | ("mention.created" \| "mention.updated" \| "mention.status_changed" \| "mention.marked_irrelevant" \| "keyword.created" \| "keyword.updated" \| "keyword.deleted" \| "alert.triggered" \| "scan.completed")[] | Maximum items: 9. | | `enabled` | No | boolean | | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/projects/00000000-0000-4000-8000-000000000001/webhooks' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"url":"https://example.com/webhooks/prospy"}' ``` MCP: `{"name":"create_webhook","arguments":{"projectId":"00000000-0000-4000-8000-000000000001","input":{"url":"https://example.com/webhooks/prospy"}}}` ### PATCH /webhooks/{id} Update an endpoint URL, events or enabled state. MCP tool: `update_webhook`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | JSON body: | Field | Required | Type | Notes | | --- | --- | --- | --- | | `url` | No | string | Format: uri. | | `description` | No | string | Maximum length: 2000. | | `eventTypes` | No | ("mention.created" \| "mention.updated" \| "mention.status_changed" \| "mention.marked_irrelevant" \| "keyword.created" \| "keyword.updated" \| "keyword.deleted" \| "alert.triggered" \| "scan.completed")[] | Maximum items: 9. | | `enabled` | No | boolean | | Scope: full. Needs editor role or higher. ```bash curl -X PATCH 'https://prospy.io/api/v1/webhooks/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"url":"https://example.com/webhooks/prospy"}' ``` MCP: `{"name":"update_webhook","arguments":{"id":"00000000-0000-4000-8000-000000000001","input":{"url":"https://example.com/webhooks/prospy"}}}` ### DELETE /webhooks/{id} Delete a webhook endpoint. MCP tool: `delete_webhook`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X DELETE 'https://prospy.io/api/v1/webhooks/00000000-0000-4000-8000-000000000001' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"delete_webhook","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ### POST /webhooks/{id}/rotate-secret Replace an endpoint's signing secret and return the new secret once. MCP tool: `rotate_webhook_secret`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/webhooks/00000000-0000-4000-8000-000000000001/rotate-secret' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"rotate_webhook_secret","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ### GET /webhooks/{id}/deliveries List webhook delivery attempts with cursor pagination. MCP tool: `list_webhook_deliveries`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | | `limit` | query | No | integer | Minimum: 1. Maximum: 100. Default: 25. | | `cursor` | query | No | string | Maximum length: 500. | Scope: read or full. ```bash curl -X GET 'https://prospy.io/api/v1/webhooks/00000000-0000-4000-8000-000000000001/deliveries' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"list_webhook_deliveries","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ### POST /webhook-deliveries/{id}/replay Replay a webhook delivery with its original event id. MCP tool: `replay_webhook_delivery`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/webhook-deliveries/00000000-0000-4000-8000-000000000001/replay' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"replay_webhook_delivery","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` ### POST /webhooks/{id}/test Send a sample mention.created event to an endpoint. MCP tool: `test_webhook`. | Parameter | In | Required | Type | Notes | | --- | --- | --- | --- | --- | | `id` | path | Yes | string | Format: uuid. | Scope: full. Needs editor role or higher. ```bash curl -X POST 'https://prospy.io/api/v1/webhooks/00000000-0000-4000-8000-000000000001/test' \ -H "Authorization: Bearer $PROSPY_API_KEY" ``` MCP: `{"name":"test_webhook","arguments":{"id":"00000000-0000-4000-8000-000000000001"}}` --- # Webhooks Receive signed Prospy events in your own app, verify them and replay failed deliveries. ## Add an endpoint Open [Integrations → Webhooks](/integrations/webhooks), enter a public HTTPS URL and choose events. Copy the signing secret when it’s shown; it isn’t displayed again. ## Events - `mention.created` - `mention.updated` - `mention.status_changed` - `mention.marked_irrelevant` - `keyword.created` - `keyword.updated` - `keyword.deleted` - `alert.triggered` - `scan.completed` Each body is JSON with `type`, `timestamp` and `data`. Mention events carry the mention under `data.mention`, with the same fields as the API. Test events set `data.test` to `true`. ## Verify signatures Prospy signs with [Standard Webhooks](https://www.standardwebhooks.com). Check `webhook-id`, `webhook-timestamp` and `webhook-signature` against the raw body using a Standard Webhooks library, and reject invalid or stale requests. ## Handle retries Respond quickly, deduplicate by `webhook-id` and make your handler safe to run twice. You can see every delivery attempt and replay a failed one after fixing your receiver. After rotating the secret, update it in your receiver.