Fetchply Docs

API reference

Use the Fetchply API with your own API keys, or integrate through the widget, Functions, and webhooks.

Fetchply has a customer API under /api/v1. Authenticate every request with an API key you create in the dashboard. Internal dashboard routes remain unsupported and can change without notice; build only against /api/v1.

Create an API key

  1. In the dashboard, open API keys in the sidebar.
  2. Choose Create key, give it a name, and pick the permissions it needs.
  3. Copy the key when it is shown. It appears once and cannot be retrieved again.

If a key is lost or no longer needed, revoke it from the same page. Revoking takes effect immediately and cannot be undone; create a new key to restore access. An account can hold up to 20 active keys; if creating a key fails with a limit message, revoke one you no longer use first.

Treat API keys like passwords. Use them from your own server or tools, never inside a public website or app where visitors could read them.

Authentication

Send the key as a bearer token on every request:

curl https://fetchply.com/api/v1/agents \
  -H "Authorization: Bearer fp_live_YOUR_KEY"

A missing or invalid key returns 401. A key that lacks the permission for an endpoint returns 403.

Endpoints

Each endpoint has its own reference page in the sidebar with parameters, response fields, and examples. Every page includes a playground: paste your own API key into the Authorization field, fill in the parameters, and send a real request to your account right from the docs.

MethodPathPermissionPurpose
GET/api/v1/agentsread:agentsList the agents the key can access
GET/api/v1/agents/{id}read:agentsRead one agent
GET/api/v1/agents/{id}/overviewread:analyticsOne call answering "how is my agent doing"
GET/api/v1/agents/{id}/analyticsread:analyticsTop questions, unanswered queries, satisfaction, and visitor locations
GET/api/v1/agents/{id}/unanswered-questionsread:analyticsQuestions the agent could not answer
GET/api/v1/agents/{id}/conversationsread:conversationsList conversations, newest first
GET/api/v1/conversations/{id}read:conversationsOne conversation with its transcript
GET/api/v1/agents/{id}/sourcesread:sourcesList training sources with their indexing status
GET/api/v1/agents/{id}/sources/{sourceId}read:sourcesRead one source, including a text snippet's stored content
GET/api/v1/agents/{id}/training-statusread:sourcesLive training progress for an agent
GET/api/v1/agents/{id}/knowledge/searchread:knowledgeSearch what the agent knows and get the most relevant passages
GET/api/v1/agents/{id}/qa-pairsread:qaList curated Q&A pairs
GET/api/v1/agents/{id}/leadsread:leadsList captured leads, newest first
GET/api/v1/agents/{id}/leads/{leadId}read:leadsRead one captured lead
GET/api/v1/usageread:usagePlan usage and message credits
POST/api/v1/agents/{id}/sourceswrite:sourcesAdd a URL or text snippet to the agent's knowledge
POST/api/v1/agents/{id}/sources/fileswrite:sourcesUpload a document file to the agent's knowledge
PATCH/api/v1/agents/{id}/sources/{sourceId}write:sourcesUpdate a text snippet's title or content in place
DELETE/api/v1/agents/{id}/sources/{sourceId}write:sourcesDelete a source and everything indexed from it
POST/api/v1/agents/{id}/retrainwrite:sourcesRefresh the agent's knowledge from its website
POST/api/v1/agents/{id}/qa-pairswrite:qaCreate a Q&A pair
PATCH/api/v1/agents/{id}/qa-pairs/{pairId}write:qaUpdate or disable a Q&A pair
DELETE/api/v1/agents/{id}/qa-pairs/{pairId}write:qaDelete a Q&A pair
POST/api/v1/agents/{id}/chatwrite:chatSend a message to an agent and get its reply

A machine-readable OpenAPI description is available at /api/v1/openapi.json.

The overview, analytics, and unanswered-questions endpoints accept ?period=7d, 30d (default), or 90d. List endpoints are paged with limit (up to 100) and offset. Conversation lists can be filtered by channel or state=open|resolved; source lists by type=url|text|file; Q&A lists by kind=qa|media; lead lists by an email substring and an inclusive startDate/endDate range (YYYY-MM-DD). Conversation and lead data never includes visitor network details, and conversation transcripts never include your team's private notes.

Keep an agent's knowledge fresh

The sources and training endpoints let you sync an agent's knowledge from your own systems, for example after publishing a help article or updating a price list:

# Add a page the agent should learn
curl -X POST https://fetchply.com/api/v1/agents/AGENT_ID/sources \
  -H "Authorization: Bearer fp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "url", "url": "https://acme.com/pricing"}'

# Or push text directly
curl -X POST https://fetchply.com/api/v1/agents/AGENT_ID/sources \
  -H "Authorization: Bearer fp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "text", "title": "Refund policy", "content": "Refunds are available within 30 days..."}'

# Or upload a document file
curl -X POST https://fetchply.com/api/v1/agents/AGENT_ID/sources/files \
  -H "Authorization: Bearer fp_live_YOUR_KEY" \
  -F "[email protected]"

# Edit a text snippet in place (title, content, or both)
curl -X PATCH https://fetchply.com/api/v1/agents/AGENT_ID/sources/SOURCE_ID \
  -H "Authorization: Bearer fp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content": "Refunds are available within 45 days..."}'

Adding a source answers immediately and indexes in the background; watch GET /agents/{id}/sources until the source's status becomes indexed (or failed, with the reason in errorMessage). POST /agents/{id}/retrain re-reads every known page and discovers new ones on the site; poll GET /agents/{id}/training-status for phase and page progress. Useful to know:

  • Only one training job runs per agent at a time. Starting another while one is active returns 409; wait for it to finish or watch training-status.
  • Text snippets can hold up to 1 MB of plain text; URLs must be public pages.
  • Only text snippets can be edited in place. GET /agents/{id}/sources/{sourceId} returns a snippet's stored text in content, so you can read, adjust, and send it back; fields you omit from the PATCH keep their current values. Refresh a URL source by retraining, and a file source by uploading the new file.
  • File uploads accept PDF, DOCX, PPTX, CSV, XLS/XLSX, TXT, Markdown, HTML, or JSON documents up to 10 MB, sent as a file field in a multipart/form-data body.
  • If adding sources returns 403 with training_limit_exceeded, the account reached its plan's training data limit; remove sources or upgrade.
  • Deleting a source removes everything the agent learned from it. This cannot be undone.

Search what an agent knows

GET /api/v1/agents/{id}/knowledge/search looks up a question in the agent's trained knowledge and returns the most relevant passages, best match first, together with the title and address of the page or document each one came from:

curl "https://fetchply.com/api/v1/agents/AGENT_ID/knowledge/search?query=refund%20policy" \
  -H "Authorization: Bearer fp_live_YOUR_KEY"

It uses the same lookup the agent performs when answering a visitor, so it is the quickest way to check whether the agent learned something, without starting a conversation or using message credits. Useful to know:

  • query is required; phrase it like a visitor question for the best matches. limit caps the number of passages (up to 10, default 5).
  • An agent that has not finished training yet returns an empty list. Add sources or retrain, wait for indexing to finish, and search again.
  • An empty list on a trained agent means nothing relevant was found; that topic is a good candidate for a new source or Q&A pair.

Manage Q&A pairs

Q&A pairs are curated answers the agent serves verbatim, and the API can manage them end to end: list them, create new ones, update or disable them, and delete them. A natural loop is to read unanswered-questions and turn the gaps into new pairs. Changes are re-indexed in the background and start matching shortly after; text-only pairs are created through the API, while pairs with images or video are managed in the dashboard.

Chat with an agent

POST /api/v1/agents/{id}/chat sends a message and returns the agent's answer as JSON, so you can put your agent inside your own product, backend, or automation tool:

curl -X POST https://fetchply.com/api/v1/agents/AGENT_ID/chat \
  -H "Authorization: Bearer fp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "What are your opening hours?"}'

The response contains the reply, the sources it was grounded in, and a sessionId. Send the same sessionId in your next request to continue the conversation; omit it to start a new one. Useful to know:

  • Each delivered message uses one message credit from your plan, the same as widget messages. When credits run out the endpoint returns 402.
  • Conversations show up in your dashboard Inbox under the API channel, so you can review them like any other conversation.
  • Retries are safe: pass a clientMessageId of your choosing and repeated sends of the same message never use extra credits.
  • Replies are markdown formatted. The endpoint answers with text only; it does not send files or images.

A quick first test: open the List agents page from the sidebar, paste your key, and send the request. Copy an agent id from the response and use it on the other endpoint pages.

Connect an AI assistant (MCP)

Fetchply is also an MCP server, so AI assistants like Claude and Cursor can work with your agents directly: list them, check how they perform, surface unanswered questions, search what they know, read conversations and leads, monitor usage, and (with write permissions) manage training sources and Q&A pairs. See Connect an AI assistant for setup in each client, the available tools, and troubleshooting.

Rate limits

Each key allows 60 requests per minute by default. Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. When the limit is exceeded, requests return 429 with a Retry-After header; wait that many seconds before retrying.

Errors

Errors are JSON documents with a stable type, a human-readable title, and the HTTP status:

{ "type": "insufficient_scope", "title": "Key lacks required permissions", "status": 403 }

Troubleshooting

  • Every request returns 401. The key was mistyped, revoked, or expired. Check for extra spaces in the header and confirm the key still appears as active on the API keys page; if not, create a new one.
  • A request returns 403. The key does not have the permission that endpoint requires. Create a new key with the right permissions selected.
  • An agent or conversation returns 404. The ID is wrong, the item was deleted, or the key is restricted to other agents. List /api/v1/agents to see what the key can access.
  • Unanswered questions return 403. That data is part of advanced analytics, which your current plan does not include. The response names the plan that does. The analytics endpoint still works on every plan; its advanced sections are empty and flagged with advancedAnalytics: false.
  • Adding a source or retraining returns 409. A training job is already running for that agent. Poll training-status and try again when it finishes.
  • A source stays in processing or pending. Indexing runs in the background and large pages can take a few minutes. If it ends as failed, errorMessage explains why; fix the source and add it again.
  • Adding a URL returns 400. The address is not a public web page. Private, internal, and localhost addresses are not accepted.
  • Updating a source returns 400. Only text snippets can be edited in place. Refresh a URL source with retraining, or replace a file source by uploading the new document and deleting the old one.
  • Uploading a file returns 400 or 413. The file type is unsupported or the file is over 10 MB. Check the supported formats above and send the document as a file field in a multipart/form-data body.
  • A Q&A change returns 503. The change was saved but indexing could not be scheduled right away. It is indexed with the next Q&A change, or retry in a moment.
  • Requests return 429. The key hit its per-minute limit. Respect the Retry-After header, or spread requests out.

Other integration surfaces

Widget data attributes

After the floating widget script loads:

  • data-fetchply-open opens chat from your own button.
  • data-fetchply-message="..." opens chat and sends the supplied message.

Copy the exact install script from Deploy. The public agent ID may appear in client code. API keys and integration secrets must not.