api-spec

star 1

Generate OpenAPI-compatible REST API specification for FastAPI endpoints in Label Suite.

singyichen By singyichen schedule Updated 3/26/2026

name: api-spec description: Generate OpenAPI-compatible REST API specification for FastAPI endpoints in Label Suite.

API Specification

Generate a comprehensive REST API specification for a new FastAPI endpoint group following RESTful conventions and the project's security requirements.

Usage

/api-spec "Submission API — annotator submits predictions"
/api-spec "Task Configuration API — admin manages annotation tasks"
/api-spec "Leaderboard API — public ranking endpoint"

Output Format

# API Specification: [API Group Name]

**Version**: v1
**Base URL**: `/api/v1`
**Auth**: Bearer JWT (except public endpoints)
**Date**: YYYY-MM-DD

---

## Authentication

All endpoints require `Authorization: Bearer <token>` except those marked `[PUBLIC]`.

```mermaid
sequenceDiagram
    participant C as Client
    participant A as FastAPI
    participant DB as PostgreSQL
    C->>A: POST /api/v1/auth/login {username, password}
    A->>DB: Verify credentials
    DB-->>A: User record
    A-->>C: {access_token, token_type: "bearer"}
    C->>A: GET /api/v1/tasks (Authorization: Bearer <token>)
    A-->>C: Task list

Endpoints

POST /api/v1/submissions

Summary: Submit predictions for a task Auth: Required (Annotator role) Rate Limit: Configurable per task (default: 10/day)

Request Body:

{
  "task_id": 42,
  "predictions": ["positive", "negative", "neutral"]
}

Request Validation:

Field Type Required Constraints Description
task_id integer > 0 ID of the annotation task
predictions array[string] non-empty Predicted labels/values

Response — 201 Created:

{
  "submission_id": 101,
  "task_id": 42,
  "status": "queued",
  "created_at": "2026-03-18T10:00:00Z"
}

Security: answer, reference, and gold_label fields are NEVER included in responses.

Error Responses:

Status Code Description
401 UNAUTHORIZED Missing or invalid JWT token
403 FORBIDDEN Task not assigned to this annotator
422 VALIDATION_ERROR Invalid request body
429 RATE_LIMIT_EXCEEDED Daily submission limit reached

GET /api/v1/submissions/{submission_id}

Summary: Get submission status and score Auth: Required (owner annotator or admin)

Path Parameters:

Parameter Type Description
submission_id integer Submission ID

Response — 200 OK:

{
  "submission_id": 101,
  "task_id": 42,
  "status": "completed",
  "score": 0.833,
  "metric": "f1_macro",
  "rank": 5,
  "created_at": "2026-03-18T10:00:00Z",
  "scored_at": "2026-03-18T10:00:28Z"
}

Security: No answer or reference fields in response.


GET /api/v1/leaderboard [PUBLIC]

Summary: Get public leaderboard for a task Auth: Not required

Query Parameters:

Parameter Type Required Default Description
task_id integer Filter by task
page integer 1 Page number
page_size integer 20 Max 100

Response — 200 OK:

{
  "data": [
    {
      "rank": 1,
      "team_name": "NLP Lab A",
      "score": 0.921,
      "metric": "f1_macro",
      "submitted_at": "2026-03-18T10:00:00Z"
    }
  ],
  "meta": {
    "task_id": 42,
    "total": 150,
    "page": 1,
    "page_size": 20
  }
}

Data Models

SubmissionCreate (Request)

class SubmissionCreate(BaseModel):
    task_id: int = Field(gt=0)
    predictions: list[str] = Field(min_length=1)

SubmissionResponse (Response)

class SubmissionResponse(BaseModel):
    submission_id: int
    task_id: int
    status: Literal["queued", "processing", "completed", "failed"]
    score: float | None = None
    metric: str | None = None
    rank: int | None = None
    created_at: datetime
    scored_at: datetime | None = None
    # NOTE: answer/reference fields are intentionally omitted

Standard Response Envelope

# List response
{
  "data": [...],
  "meta": {"total": N, "page": N, "page_size": N}
}

# Single object response
{
  "data": {...}
}

# Error response
{
  "detail": "Error message",
  "code": "ERROR_CODE"
}

Error Codes Reference

HTTP Status Application Code Description
400 BAD_REQUEST Malformed request
401 UNAUTHORIZED Authentication required
403 FORBIDDEN Insufficient permissions
404 NOT_FOUND Resource not found
422 VALIDATION_ERROR Pydantic validation failure
429 RATE_LIMIT_EXCEEDED Submission limit reached
500 INTERNAL_ERROR Unexpected server error

Rate Limiting

Endpoint Limit Window Header
POST /submissions Configurable per task Per day X-RateLimit-Limit, X-RateLimit-Remaining
POST /auth/login 10 Per minute Retry-After
GET /leaderboard 100 Per minute

429 Response:

{
  "detail": "Daily submission limit of 10 reached",
  "code": "RATE_LIMIT_EXCEEDED",
  "retry_after": "2026-03-19T00:00:00Z"
}

Naming Conventions

Pattern Convention Example
URL path kebab-case /annotation-tasks
Query param snake_case ?task_id=42&page_size=20
JSON field snake_case submission_id, created_at
HTTP method Resource action GET=read, POST=create, PUT=replace, PATCH=update, DELETE=remove

Install via CLI
npx skills add https://github.com/singyichen/label-suite --skill api-spec
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator