Potato API Reference
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: 1. Use session cookies from a browser 2. Use the debug mode with automatic user creation 3. 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 keywords array if no keyword_highlights_file is configured
- Keywords are sorted by start position
- Duplicate matches at the same position are deduplicated
- Colors are taken from ui.spans.span_colors config 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 user
- instance_id - Filter by instance
- minutes - 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