Potato API Reference
April 11, 2026 · View on GitHub
This document describes the HTTP API endpoints provided by Potato, enabling integration with custom frontends, automation scripts, or external systems.
Overview
Base URL
http://localhost:8000
Authentication
Most endpoints require an active session. Sessions are established via the login endpoints and maintained via cookies.
For programmatic access, you can:
- Use session cookies from a browser
- Use the debug mode with automatic user creation
- Implement the login flow programmatically
Response Format
All API endpoints return JSON responses. Error responses include an error field with a description.
Session Management
Login
POST /auth
Content-Type: application/x-www-form-urlencoded
Request Body:
username=your_username&password=your_password
Response: Redirects to annotation page on success, or returns error.
Check Session
GET /api/current_instance
Response (authenticated):
{
"instance_id": "item_001",
"current_index": 0,
"total_instances": 100
}
Response (not authenticated):
{
"error": "No active session"
}
Status: 401
Logout
POST /logout
Response: Redirects to home page.
Annotation Endpoints
Get Current Instance
GET /api/current_instance
Returns information about the user's current annotation instance.
Response:
{
"instance_id": "item_001",
"current_index": 5,
"total_instances": 100
}
Get Instance Content
GET /api/spans/{instance_id}
Returns the text content and existing span annotations for an instance.
Response:
{
"instance_id": "item_001",
"text": "The quick brown fox jumps over the lazy dog.",
"spans": [
{
"id": "span_123",
"schema": "entities",
"label": "ANIMAL",
"title": "ANIMAL",
"start": 16,
"end": 19,
"text": "fox",
"color": "#ff6b6b"
}
]
}
Get Annotations
GET /get_annotations?instance_id={instance_id}
Returns all annotations (labels and spans) for a specific instance.
Response:
{
"label_annotations": {
"sentiment": {
"positive": "1"
}
},
"span_annotations": {
"entities:ANIMAL:16:19": "true"
}
}
Submit Annotation
POST /updateinstance
Content-Type: application/json
Submit or update annotations for an instance.
Request Body (Frontend Format):
{
"instance_id": "item_001",
"annotations": {
"sentiment:positive": "1",
"sentiment:negative": "0"
},
"span_annotations": [
{
"schema": "entities",
"name": "PERSON",
"title": "PERSON",
"start": 0,
"end": 5,
"value": "true"
}
],
"client_timestamp": "2024-01-15T10:30:00Z"
}
Request Body (Backend Format):
{
"instance_id": "item_001",
"schema": "sentiment",
"type": "label",
"state": [
{"name": "positive", "value": "1"},
{"name": "negative", "value": "0"}
]
}
Response (Success):
{
"status": "success",
"processing_time_ms": 15,
"performance_metrics": {
"total_annotations": 50,
"session_duration": 1800
}
}
Response (With Quality Control Feedback):
{
"status": "success",
"processing_time_ms": 12,
"qc_result": {
"type": "gold_standard",
"correct": false,
"gold_label": {"sentiment": "positive"},
"explanation": "Strong positive language indicates positive sentiment."
}
}
Response (Attention Check Warning):
{
"status": "success",
"warning": true,
"warning_message": "Please read items carefully before answering.",
"qc_result": {
"type": "attention_check",
"passed": false,
"warning": true
}
}
Response (Blocked):
{
"status": "blocked",
"message": "You have been blocked due to too many incorrect responses."
}
Clear Span Annotations
POST /api/spans/{instance_id}/clear
Clears all span annotations for an instance.
Response:
{
"status": "success",
"cleared_count": 3
}
Navigate to Instance
POST /go_to
Content-Type: application/json
Navigate to a specific instance by ID or index.
Request Body:
{
"go_to": "item_005"
}
Or by action:
{
"action": "next_instance"
}
Schema Information
Get Annotation Schemas
GET /api/schemas
Returns information about configured annotation schemas (primarily for span annotations).
Response:
{
"entities": {
"name": "entities",
"description": "Named entity recognition",
"labels": ["PERSON", "ORGANIZATION", "LOCATION"],
"type": "span"
},
"sentiment_spans": {
"name": "sentiment_spans",
"description": "Sentiment-bearing phrases",
"labels": ["positive", "negative"],
"type": "span"
}
}
Get Label Colors
GET /api/colors
Returns the color mapping for annotation labels.
Response:
{
"entities": {
"PERSON": "#ff6b6b",
"ORGANIZATION": "#4ecdc4",
"LOCATION": "#45b7d1"
}
}
Get Keyword Highlights
GET /api/keyword_highlights/{instance_id}
Returns admin-defined keyword matches found in the instance text. Keywords are configured via keyword_highlights_file in the config.
Parameters:
instance_id(path): The ID of the instance to get keyword highlights for
Response:
{
"instance_id": "item_1",
"keywords": [
{
"label": "positive",
"start": 10,
"end": 19,
"text": "excellent",
"reasoning": "Keyword: excel* → positive",
"schema": "sentiment",
"color": "rgba(34, 197, 94, 0.8)"
},
{
"label": "negative",
"start": 45,
"end": 53,
"text": "terrible",
"reasoning": "Keyword: terrible → negative",
"schema": "sentiment",
"color": "rgba(239, 68, 68, 0.8)"
}
]
}
Response Fields:
| Field | Description |
|---|---|
instance_id | The instance ID |
keywords | Array of keyword matches found in the text |
keywords[].label | The label associated with this keyword |
keywords[].start | Character offset where the match starts |
keywords[].end | Character offset where the match ends |
keywords[].text | The actual matched text from the instance |
keywords[].reasoning | Description of the keyword pattern that matched |
keywords[].schema | The annotation schema this keyword belongs to |
keywords[].color | RGBA color string for rendering the highlight |
Notes:
- Returns empty
keywordsarray if nokeyword_highlights_fileis configured - Keywords are sorted by start position
- Duplicate matches at the same position are deduplicated
- Colors are taken from
ui.spans.span_colorsconfig or auto-assigned
Admin API Endpoints
Admin endpoints require admin privileges or API key authentication.
Health Check
GET /admin/health
Response:
{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00Z",
"version": "2.0.0"
}
Dashboard Overview
GET /admin/api/overview
Response:
{
"total_items": 1000,
"total_annotations": 5000,
"total_users": 25,
"active_users": 10,
"completion_rate": 0.45,
"items_by_status": {
"completed": 450,
"in_progress": 150,
"unassigned": 400
}
}
Get Annotators
GET /admin/api/annotators
Response:
{
"annotators": [
{
"user_id": "user1",
"annotations_count": 200,
"current_phase": "annotation",
"last_active": "2024-01-15T10:30:00Z",
"assigned_items": 250,
"completed_items": 200
}
],
"total_count": 25
}
Get Instances
GET /admin/api/instances
Query Parameters:
status- Filter by status (completed, in_progress, unassigned)limit- Maximum number of results (default: 100)offset- Pagination offset
Response:
{
"instances": [
{
"id": "item_001",
"text_preview": "The quick brown fox...",
"annotations_count": 3,
"status": "completed"
}
],
"total_count": 1000
}
Get Configuration
GET /admin/api/config
Response:
{
"annotation_task_name": "Sentiment Analysis",
"annotation_schemes": [...],
"total_items": 1000,
"output_format": "json"
}
Update Configuration
POST /admin/api/config
Content-Type: application/json
Request Body:
{
"setting_name": "value"
}
Get Annotation History
GET /admin/api/annotation_history
Query Parameters:
user_id- Filter by userinstance_id- Filter by instanceminutes- Time window in minutes
Response:
{
"history": [
{
"user_id": "user1",
"instance_id": "item_001",
"action_type": "add_label",
"schema_name": "sentiment",
"label_name": "positive",
"timestamp": "2024-01-15T10:30:00Z"
}
]
}
Get Suspicious Activity
GET /admin/api/suspicious_activity
Response:
{
"suspicious_users": [
{
"user_id": "user5",
"flags": ["rapid_submissions", "low_time_per_item"],
"avg_time_per_item": 2.5,
"annotations_count": 500
}
]
}
Get Crowdsourcing Data
GET /admin/api/crowdsourcing
Response:
{
"summary": {
"total_workers": 50,
"prolific_workers": 30,
"mturk_workers": 15,
"other_workers": 5
},
"prolific": {
"workers": [...],
"completion_codes_issued": 28
},
"mturk": {
"workers": [...],
"hits_completed": 15
}
}
Quality Control API
Get Quality Control Metrics
GET /admin/api/quality_control
Response:
{
"enabled": true,
"attention_checks": {
"enabled": true,
"total_items": 5,
"total_checks": 150,
"total_passed": 140,
"total_failed": 10,
"by_user": {
"user1": {
"passed": 10,
"failed": 0,
"pass_rate": 1.0
},
"user2": {
"passed": 8,
"failed": 2,
"pass_rate": 0.8
}
}
},
"gold_standards": {
"enabled": true,
"total_items": 10,
"total_evaluations": 200,
"total_correct": 170,
"total_incorrect": 30,
"by_user": {
"user1": {
"correct": 9,
"total": 10,
"accuracy": 0.9
}
},
"by_item": {
"gold_001": {
"correct": 18,
"total": 20,
"accuracy": 0.9
}
}
},
"auto_promotion": {
"enabled": true,
"min_annotators": 3,
"agreement_threshold": 1.0,
"promoted_count": 5,
"promoted_items": [
{
"item_id": "item_042",
"consensus_label": {"sentiment": "positive"},
"annotator_count": 3,
"promoted_at": "2024-01-15T10:30:00Z"
}
],
"candidates": [
{
"item_id": "item_055",
"annotator_count": 2,
"needed_annotators": 3,
"schema_agreement": {
"sentiment": {
"value": "negative",
"count": 2,
"total": 2,
"agreement": 1.0
}
}
}
]
},
"pre_annotation": {
"enabled": true,
"items_with_predictions": 1000
}
}
Get Agreement Metrics
GET /admin/api/agreement
Response:
{
"enabled": true,
"overall": {
"average_krippendorff_alpha": 0.78,
"schemas_evaluated": 2,
"interpretation": "Tentative agreement"
},
"by_schema": {
"sentiment": {
"krippendorff_alpha": 0.82,
"metric_type": "nominal",
"items_evaluated": 100,
"total_annotations": 300,
"interpretation": "Good agreement"
},
"intensity": {
"krippendorff_alpha": 0.74,
"metric_type": "interval",
"items_evaluated": 100,
"total_annotations": 300,
"interpretation": "Tentative agreement"
}
},
"warnings": []
}
AI Assistant API
Get AI Suggestion
GET /get_ai_suggestion?annotationId={annotation_index}&aiAssistant={ai_assistant_type}
Response:
{
"suggestion": "Based on the text, this appears to be positive sentiment.",
"confidence": 0.85,
"labels": {
"sentiment": "positive"
}
}
Get AI Assistant Help
GET /api/ai_assistant?instance_id={instance_id}&schema={schema_name}
Response:
{
"html": "<div class='ai-hint'>This text expresses positive sentiment...</div>",
"suggestions": [
{
"schema": "sentiment",
"label": "positive",
"confidence": 0.9
}
]
}
User State Endpoints (Admin)
Get User State
GET /admin/user_state/{user_id}
Response:
{
"user_id": "user1",
"current_phase": "annotation",
"current_instance_index": 45,
"instance_id_ordering": ["item_001", "item_002", ...],
"assigned_count": 100,
"completed_count": 45,
"annotation_history": [...]
}
Get All Users
GET /admin/system_state
Response:
{
"users": {
"user1": {
"phase": "annotation",
"annotations": 200,
"last_active": "2024-01-15T10:30:00Z"
}
},
"items": {
"total": 1000,
"assigned": 800,
"completed": 500
}
}
Item State Endpoints (Admin)
Get All Items
GET /admin/all_instances
Response:
{
"instances": [
{
"id": "item_001",
"text": "The quick brown fox...",
"assigned_to": ["user1", "user2"],
"annotations_count": 2
}
]
}
Get Item State
GET /admin/item_state/{item_id}
Response:
{
"id": "item_001",
"text": "The quick brown fox jumps over the lazy dog.",
"data": {
"id": "item_001",
"text": "The quick brown fox jumps over the lazy dog.",
"metadata": {...}
},
"assigned_to": ["user1", "user2"],
"annotations": {
"user1": {
"sentiment": {"positive": "1"}
},
"user2": {
"sentiment": {"positive": "1"}
}
}
}
Media Endpoints
Get Audio Waveform
GET /api/waveform/{cache_key}
Returns cached waveform data for audio annotation.
Generate Audio Waveform
POST /api/waveform/generate
Content-Type: application/json
Request Body:
{
"audio_url": "https://example.com/audio.mp3"
}
Response:
{
"cache_key": "abc123",
"waveform_url": "/api/waveform/abc123"
}
Proxy Audio
GET /api/audio/proxy?url={encoded_audio_url}
Proxies external audio files to handle CORS issues.
Get Video Metadata
POST /api/video/metadata
Content-Type: application/json
Request Body:
{
"video_url": "https://example.com/video.mp4"
}
Response:
{
"duration": 120.5,
"width": 1920,
"height": 1080,
"fps": 30
}
Behavioral Tracking API
Track Interactions
POST /api/track_interactions
Content-Type: application/json
Records batched interaction events from the frontend (mouse clicks, focus time, scroll depth).
Track AI Usage
POST /api/track_ai_usage
Content-Type: application/json
Records AI assistance requests, responses, and user decisions for analytics.
Track Annotation Change
POST /api/track_annotation_change
Content-Type: application/json
Records annotation changes from the frontend (select, deselect, update, clear actions).
Get Behavioral Data
GET /api/behavioral_data/{instance_id}
Returns behavioral data for a specific instance (interaction events, timing, AI usage).
Option Highlighting API
Get Option Highlighting Config
GET /api/option_highlights/config
Returns the option highlighting configuration for AI-suggested labels.
Trigger Option Highlight Prefetch
POST /api/option_highlights/prefetch
Triggers prefetching of option highlights for upcoming items.
Get Option Highlights
GET /api/option_highlights/{annotation_id}
Returns AI-suggested option highlights for a specific annotation scheme index.
Entity Linking API
Search Knowledge Base
GET /api/entity_linking/search?query={query}&kb={kb_name}
Searches a configured knowledge base for entities matching the query.
Get Entity Details
GET /api/entity_linking/entity/{kb_name}/{entity_id}
Returns detailed information about a specific entity from a knowledge base.
Get Configured Knowledge Bases
GET /api/entity_linking/configured_kbs
Returns the list of configured knowledge bases.
Update Span with Entity Link
POST /api/entity_linking/update_span
Content-Type: application/json
Updates a span annotation with entity linking information.
Link and Event Annotation API
Get Links
GET /api/links/{instance_id}
Returns link annotations (span relationships) for a specific instance.
Delete Link
DELETE /api/links/{instance_id}/{link_id}
Deletes a specific link annotation.
Get Events
GET /api/events/{instance_id}
Returns event annotations for a specific instance.
Delete Event
DELETE /api/events/{instance_id}/{event_id}
Deletes a specific event annotation.
Span API
Get Span Data
GET /api/spans/{instance_id}
Returns text content and existing span annotations for an instance.
Clear Spans
DELETE /api/spans/{instance_id}/clear
Clears all span annotations for an instance.
Get Span Colors
GET /api/colors
Returns the color mapping for span labels.
Chat Support API
Send Chat Message
POST /api/chat/send
Content-Type: application/json
Sends a message to the LLM chat assistant and returns the response.
Get Chat History
GET /api/chat/history?instance_id={instance_id}
Returns chat history for a specific instance.
Get Chat Config
GET /api/chat/config
Returns chat UI configuration.
Agent Chat API
Send Agent Message
POST /agent_chat/send
Content-Type: application/json
Sends a message to the agent and returns a response.
Finish Agent Chat
POST /agent_chat/finish
Finishes the chat and writes conversation data to the item.
Get Agent Chat Status
GET /agent_chat/status
Returns the current agent chat session status (for page refresh recovery).
ICL Labeling API (Admin)
Get ICL Status
GET /admin/api/icl/status
Returns ICL labeler status and statistics.
Get ICL Examples
GET /admin/api/icl/examples?schema={schema_name}
Returns current high-confidence examples, optionally filtered by schema.
Get ICL Predictions
GET /admin/api/icl/predictions?schema={schema_name}&status={status}&limit={limit}
Returns LLM predictions with filtering options.
Get ICL Accuracy
GET /admin/api/icl/accuracy
Returns accuracy metrics for ICL labeling.
Trigger ICL Operation
POST /admin/api/icl/trigger
Content-Type: application/json
Request Body:
{
"action": "refresh_examples | batch_label | save_state"
}
Record ICL Verification
POST /api/icl/record_verification
Content-Type: application/json
Records human verification of an LLM prediction.
Adjudication API
Get Adjudication Queue
GET /adjudicate/api/queue
Returns the adjudication queue (items needing adjudication).
Get Adjudication Item
GET /adjudicate/api/item/{instance_id}
Returns full item detail for adjudication review.
Submit Adjudication Decision
POST /adjudicate/api/submit
Content-Type: application/json
Submits an adjudication decision.
Get Adjudication Stats
GET /adjudicate/api/stats
Returns adjudication progress statistics.
Skip Adjudication Item
POST /adjudicate/api/skip/{instance_id}
Skips an adjudication item.
Get Next Adjudication Item
GET /adjudicate/api/next
Returns the next adjudication item in the queue.
Get Similar Items
GET /adjudicate/api/similar/{instance_id}
Returns similar items for a specific instance (lazy-loading).
Admin Adjudication Overview
GET /admin/api/adjudication
Returns admin dashboard overview of adjudication status.
BWS / IBWS Scoring API (Admin)
Get BWS Scoring Status
GET /admin/api/bws_scoring
Returns current BWS (Best-Worst Scaling) scoring status and cached scores.
Generate BWS Scores
POST /admin/api/bws_scoring/generate
Generates BWS scores from current annotations.
Get IBWS Status
GET /admin/api/ibws_status
Returns current IBWS (Iterative Best-Worst Scaling) round status and progress.
Get IBWS Ranking
GET /admin/api/ibws_ranking
Returns current IBWS ordinal ranking.
MACE API (Admin)
Get MACE Overview
GET /admin/api/mace/overview
Returns MACE (Multiple Annotator Competence Estimation) results overview.
Get MACE Predictions
GET /admin/api/mace/predictions?schema={schema_name}&instance_id={instance_id}
Returns MACE predicted labels, optionally filtered by schema and instance.
Trigger MACE Computation
POST /admin/api/mace/trigger
Manually triggers a MACE recomputation.
Embedding Visualization API (Admin)
Get Visualization Data
GET /admin/api/embedding_viz/data
Returns visualization data for the embedding scatter plot.
Reorder Queue from Embeddings
POST /admin/api/embedding_viz/reorder
Content-Type: application/json
Reorders the annotation queue based on selected instances in the visualization.
Refresh Embeddings
POST /admin/api/embedding_viz/refresh
Forces re-computation of embeddings and UMAP projection.
Get Embedding Stats
GET /admin/api/embedding_viz/stats
Returns embedding visualization statistics.
Export API (Admin)
List Export Formats
GET /admin/api/export/formats
Returns available export formats with metadata.
Run Export
POST /admin/api/export
Content-Type: application/json
Runs an export in the requested format and returns the result.
Admin Analytics API
Get Behavioral Analytics
GET /admin/api/behavioral_analytics
Returns behavioral analytics data for all annotators (AI usage, interaction types, suspicion scores).
Get Stale Assignments
GET /admin/api/stale_assignments
Returns a list of stale instance assignments (assigned but not annotated past timeout).
Reclaim Instance
POST /admin/api/reclaim_instance
Content-Type: application/json
Manually reclaims a specific instance assignment from a user.
Set User Instances
POST /admin/api/user/{username}/set_instances
Content-Type: application/json
Sets the maximum number of instances for a specific user.
Get Question Analytics
GET /admin/api/questions
Returns aggregate analysis data for all annotation schemas/questions.
Schema API
Get Annotation Schemas
GET /api/schemas
Returns annotation schema information for the current configuration.
Error Responses
All endpoints may return error responses in the following format:
{
"error": "Description of the error"
}
Common HTTP status codes:
400- Bad Request (invalid parameters)401- Unauthorized (no session or invalid credentials)403- Forbidden (insufficient permissions)404- Not Found (resource doesn't exist)500- Internal Server Error
Example: Complete Annotation Flow
Here's an example of a complete annotation flow using the API:
import requests
BASE_URL = "http://localhost:8000"
session = requests.Session()
# 1. Login
session.post(f"{BASE_URL}/auth", data={
"username": "annotator1",
"password": "password123"
})
# 2. Get current instance
response = session.get(f"{BASE_URL}/api/current_instance")
instance_info = response.json()
instance_id = instance_info["instance_id"]
# 3. Get instance content
response = session.get(f"{BASE_URL}/api/spans/{instance_id}")
content = response.json()
print(f"Text: {content['text']}")
# 4. Submit annotation
response = session.post(f"{BASE_URL}/updateinstance", json={
"instance_id": instance_id,
"annotations": {
"sentiment:positive": "1"
}
})
result = response.json()
print(f"Status: {result['status']}")
# 5. Navigate to next instance
session.post(f"{BASE_URL}/go_to", json={
"action": "next_instance"
})
# 6. Repeat steps 2-5 until done
Example: Admin Monitoring
import requests
BASE_URL = "http://localhost:8000"
# Get overview
overview = requests.get(f"{BASE_URL}/admin/api/overview").json()
print(f"Progress: {overview['completion_rate']*100:.1f}%")
# Get annotator stats
annotators = requests.get(f"{BASE_URL}/admin/api/annotators").json()
for a in annotators["annotators"]:
print(f"{a['user_id']}: {a['completed_items']}/{a['assigned_items']}")
# Get agreement metrics
agreement = requests.get(f"{BASE_URL}/admin/api/agreement").json()
print(f"Agreement: α = {agreement['overall']['average_krippendorff_alpha']:.3f}")
# Get quality control metrics
qc = requests.get(f"{BASE_URL}/admin/api/quality_control").json()
if qc["attention_checks"]["enabled"]:
pass_rate = qc["attention_checks"]["total_passed"] / qc["attention_checks"]["total_checks"]
print(f"Attention check pass rate: {pass_rate*100:.1f}%")
WebSocket Events (Future)
Currently, Potato uses polling for real-time updates. WebSocket support may be added in future versions for:
- Real-time annotation updates
- Live progress notifications
- Collaborative annotation features