For Developers
Integrate with Refine's REST API or connect AI tools via the Model Context Protocol (MCP)
MCP
Model Context Protocol (MCP)
MCP is an open standard that lets AI assistants interact with external tools and data sources directly. Connect your preferred AI tool to Refine with a single endpoint.
- Add the Refine MCP endpoint URL to your AI tool's configuration
- Your tool will handle OAuth authentication automatically
Using Claude on the web, desktop, or mobile? Install the Refine connector straight from the Claude directory — no configuration to paste.
Open the Refine connector{
"mcpServers": {
"refine": {
"url": "https://api.refine.ink/mcp"
}
}
}{
"mcpServers": {
"refine": {
"url": "https://api.refine.ink/mcp"
}
}
}{
"servers": {
"refine": {
"type": "http",
"url": "https://api.refine.ink/mcp"
}
}
}OAuth is the default authentication method. Your MCP client will handle the authorization flow automatically.
MCP can also use API keys for authentication.
REST API
REST API
A RESTful API with interactive OpenAPI documentation. Explore all available endpoints, request and response schemas, and try requests directly from the browser.
Explore API Documentation- Create an API key in your profile's Advanced Settings
- Use the key to authenticate your requests
# 1. Upload a document
UPLOAD=$(curl -s -X POST "https://api.refine.ink/documents/upload" \
-H "X-API-Key: your-api-key" \
-F "file=@paper.pdf")
TASK_ID=$(echo $UPLOAD | jq -r '.task_id')
# 2. Wait for upload processing via SSE
curl -N "https://api.refine.ink/documents/upload/events/$TASK_ID?token=your-api-key"
# Listen until you receive: event: complete, data: {"document_id": "..."}
DOCUMENT_ID="<document_id from SSE>"
# 3. Start document processing (costs 1 credit)
PROCESS=$(curl -s -X POST "https://api.refine.ink/documents/$DOCUMENT_ID/process" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"preview": false}')
SESSION_ID=$(echo $PROCESS | jq -r '.session_id')
# 4. Stream processing progress via SSE
curl -N "https://api.refine.ink/documents/$DOCUMENT_ID/process/events/$SESSION_ID?token=your-api-key"import requests
import sseclient # pip install sseclient-py
API_KEY = "your-api-key"
BASE = "https://api.refine.ink"
headers = {"X-API-Key": API_KEY}
# 1. Upload a document
with open("paper.pdf", "rb") as f:
upload = requests.post(
f"{BASE}/documents/upload",
headers=headers,
files={"file": f}
).json()
task_id = upload["task_id"]
# 2. Wait for upload processing via SSE
response = requests.get(
f"{BASE}/documents/upload/events/{task_id}?token={API_KEY}",
stream=True
)
client = sseclient.SSEClient(response)
for event in client.events():
if event.event == "complete":
document_id = json.loads(event.data)["document_id"]
break
# 3. Start document processing (costs 1 credit)
process = requests.post(
f"{BASE}/documents/{document_id}/process",
headers=headers,
json={"preview": False}
).json()
session_id = process["session_id"]
# 4. Stream processing progress via SSE
response = requests.get(
f"{BASE}/documents/{document_id}/process/events/{session_id}?token={API_KEY}",
stream=True
)
for event in sseclient.SSEClient(response).events():
print(event.event, event.data)const API_KEY = "your-api-key";
const BASE = "https://api.refine.ink";
// 1. Upload a document
const form = new FormData();
form.append("file", new Blob([fileBuffer]), "paper.pdf");
const upload = await fetch(`${BASE}/documents/upload`, {
method: "POST",
headers: { "X-API-Key": API_KEY },
body: form,
}).then(r => r.json());
const taskId = upload.task_id;
// 2. Wait for upload processing via SSE
const uploadEvents = new EventSource(
`${BASE}/documents/upload/events/${taskId}?token=${API_KEY}`
);
const documentId = await new Promise<string>((resolve) => {
uploadEvents.addEventListener("complete", (e) => {
resolve(JSON.parse(e.data).document_id);
uploadEvents.close();
});
});
// 3. Start document processing (costs 1 credit)
const process = await fetch(
`${BASE}/documents/${documentId}/process`,
{
method: "POST",
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ preview: false }),
}
).then(r => r.json());
// 4. Stream processing progress via SSE
const processEvents = new EventSource(
`${BASE}/documents/${documentId}/process/events/${process.session_id}?token=${API_KEY}`
);
// Events are named, so listen per event rather than on "message"
processEvents.addEventListener("progress", (e) => {
console.log(JSON.parse(e.data));
});
processEvents.addEventListener("complete", (e) => {
console.log(JSON.parse(e.data));
processEvents.close();
});Keep your API keys secure. Do not commit them to version control or expose them in client-side code.
Testing
Test your integration
You don't need to spend credits to build against Refine. Mock the API from our OpenAPI schema while you wire things up, then switch to the real pipeline when you're ready.
Mock the API from the OpenAPI schema
Every endpoint is described in our OpenAPI schema, so any mocking tool that reads OpenAPI can stand up a fake Refine API for you — Prism, Mockoon, Microcks, WireMock, Postman, or your framework's own mock server. Point your client at it to exercise your upload, processing and polling code without touching the real service.
# Grab the OpenAPI schema
curl -o refine-openapi.json https://api.refine.ink/openapi.json
# Serve a mock from it with the tool of your choice, e.g. Prism
npx @stoplight/prism-cli mock refine-openapi.json
# Point your client at the mock instead of the real API
export REFINE_API_URL=http://127.0.0.1:4010The schema is always in sync with the live API: view the OpenAPI schema
Or test against the real flow
Mocks can't tell you how real feedback looks. Get in touch and we'll grant preview credits to your account, so you can run real documents through the full pipeline. Preview runs are a quick, low-processing pass, so they return fewer comments than a Full Review — enough to validate your integration end to end.
Contact us to request preview creditsStart Building
Developer APIs are in beta — we welcome your feedback as we continue to develop them.