API and developers
DockyDoc can act for you inside other software: a WhatsApp bot, an AI assistant, a script. You give the tool a personal API key; from then on it can find your documents from a plain sentence, get a download link for them, and store new ones. Everything it does, it does as you, in the workspaces you belong to.
API access is part of the Business plan and above. Two ways in, same key for both: REST for anything that can make an HTTP call, and MCP for assistants such as Claude.
1. Get a key
In DockyDoc open Settings → Integrations → New key. Name it after the thing you are connecting, for example “Clawdbot on WhatsApp”. Leave Allow uploads and changes off unless the tool needs to save files: a read-only key can find and download but cannot change anything, so a leak costs less.
The key is shown once. Copy it into the other tool. If you lose it, revoke it and make another; the old one stops working the moment you revoke it. Keys look like dd_live_ followed by 40 characters.
2. Base URL and auth
Base URL: https://dockydoc.app/api/v1
Header: Authorization: Bearer dd_live_…
Body: JSON (Content-Type: application/json), except upload which is multipart/form-dataCheck a key works with GET /integrations/me. It returns who the key belongs to, whether it can write, and their workspaces.
3. The one call a bot needs
Send the person’s sentence; get back download links, or a question to put to them.
POST https://dockydoc.app/api/v1/integrations/fetch
{ "query": "my passport and UK visa", "expiresInMinutes": 15 }{
"mode": "ai",
"items": [
{
"ask": "passport",
"match": { "id": "…", "name": "Alice passport", "fileName": "passport.pdf", "confidence": 0.95,
"labels": ["passport", "travel"], "workspace": { "id": "…", "name": "Alice's Workspace" } },
"alternatives": [],
"delivery": { "url": "https://dockydoc.app/api/v1/public/shares/…/download", "fileName": "passport.pdf",
"mimeType": "application/pdf", "expiresAt": "2026-09-17T18:45:00Z" },
"needsChoice": false
},
{
"ask": "UK visa",
"match": { "name": "UK visa 2024", "confidence": 0.55 },
"alternatives": [{ "name": "UK visa 2019" }],
"delivery": null,
"needsChoice": true
}
]
}Read it like this. When delivery is set, send the person the url; it needs no login and stops working at expiresAt (default 15 minutes, up to a day). When needsChoice is true, DockyDoc was not sure enough to hand a document over: show match and alternatives, let the person pick, then call /integrations/deliver with the id they chose. Sending the wrong passport is worse than asking.
mode says how the matching was done: ai uses the model, lexical is a word-overlap fallback. Both return the same shape.
4. All calls
| Call | Does |
|---|---|
| GET /integrations/me | Who the key belongs to, whether it can write, and their workspaces. |
| POST /integrations/find | {query, workspaceId?, includeText?}. Matching only, no links. Same items as fetch minus delivery. |
| POST /integrations/read | {documentIds[], includeText?, maxTextChars?}. What is in documents you know the ids of: details, every extracted field as key and value, and text, what was read from the file. For answering a question without sending the file. |
| POST /integrations/deliver | {documentIds[], expiresInMinutes?}. Links for documents you already know the ids of. Up to 10 at a time. |
| POST /integrations/fetch | {query, workspaceId?, expiresInMinutes?, includeText?}. Find and deliver in one call. Every matched document carries details, the fields read from it; includeText adds its text. |
| POST /integrations/upload | multipart: file, name?, description?, labels? (comma-separated, created if missing), workspaceId?. Needs a key with write access. Files over 4 MB: send them to the API host directly, https://dockydoc-api-staging.onrender.com/api/v1/integrations/upload, same key. |
Every other endpoint in the API also accepts a key, with one rule: a read-only key can only make GET requests there. Each find, fetch or deliver counts as one AI action on the key owner’s plan.
5. Examples
curl
KEY=dd_live_…
curl -s https://dockydoc.app/api/v1/integrations/fetch \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"query": "my passport"}'
# upload
curl -s https://dockydoc.app/api/v1/integrations/upload \
-H "Authorization: Bearer $KEY" \
-F "file=@policy.pdf" -F "name=Car insurance 2026" -F "labels=insurance,car"Python
import requests
KEY = "dd_live_…"
H = {"Authorization": f"Bearer {KEY}"}
r = requests.post("https://dockydoc.app/api/v1/integrations/fetch", headers=H,
json={"query": "my passport and UK visa"}, timeout=60)
for item in r.json()["items"]:
if item["delivery"]:
print(item["ask"], "->", item["delivery"]["url"])
elif item["needsChoice"]:
names = [item["match"]["name"]] + [a["name"] for a in item["alternatives"]]
print(item["ask"], "-> which one?", names)
else:
print(item["ask"], "-> nothing found")JavaScript (Node 18+)
const KEY = "dd_live_…";
const res = await fetch("https://dockydoc.app/api/v1/integrations/fetch", {
method: "POST",
headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ query: "my passport", expiresInMinutes: 30 }),
});
const { items } = await res.json();
for (const item of items) {
if (item.delivery) console.log(item.ask, item.delivery.url);
else if (item.needsChoice) console.log(item.ask, "ask the person:", item.match?.name, item.alternatives.map((a) => a.name));
}6. MCP for assistants
Server URL https://dockydoc.app/api/v1/mcp, transport Streamable HTTP, header Authorization: Bearer dd_live_…. Stateless, so no session handling. Add it to Claude, or any assistant that speaks the Model Context Protocol, and it gets these tools:
| Tool | Same as |
|---|---|
| whoami | GET /integrations/me |
| find_documents | POST /integrations/find |
| read_documents | POST /integrations/read |
| get_download_links | POST /integrations/deliver |
| fetch_documents | POST /integrations/fetch. The tool description tells the assistant to put alternatives to the person when needsChoice is true. |
| upload_document | POST /integrations/upload, with the file as base64. |
7. WhatsApp bots
DockyDoc does not run a WhatsApp number of its own. A bot you already run (Clawdbot, or one built on the WhatsApp Business API, Twilio or a similar service) calls DockyDoc with your key. When it receives “send me my passport and UK visa” from your number it should:
- Call
POST /integrations/fetchwith that sentence asquery. - For each item with
delivery, send theurl, or download the file and attach it (the link serves the bytes with the right file name). - For each item with
needsChoice, list the match and the alternatives by name and ask which one. When the person answers, call/integrations/deliverwith that document’s id.
If the bot supports MCP servers, add the MCP URL above with the key and it gets the same behaviour without any of that being written by hand. A bot serving several people needs one key per person, each made from that person’s DockyDoc account.
8. Errors and limits
| Status | Meaning |
|---|---|
| 401 | Missing, wrong or revoked key. |
| 402 | The key owner’s plan does not allow this (API needs Business or above; AI actions used up). The body carries code, plan and upgradeTo. |
| 403 | Read-only key trying to change something, or no access to that workspace. |
| 429 | Rate limit: 120 requests a minute on Business, 600 on Team, per account. Twenty wrong keys a minute from one address are refused too. |
Every link handed out is an ordinary external share on the document, visible in its share list and revocable there, and each download is recorded with time, IP and user agent. Links are bearer tokens: anyone holding one can download until it expires, so keep expiresInMinutes short for anything like a passport.
9. Interactive reference
The full request and response shapes, with a “Try it out” button that runs against your account once you paste a key: dockydoc.app/api/docs. The same in OpenAPI 3 JSON for Postman, code generators or an AI tool: dockydoc.app/api/docs-json.
Questions or a use case we have not covered: support@dockydoc.app.