Files
StageAI/docs/API_GUIDE.md
CTO Agent 41fcc5be42
Some checks failed
Deploy to VPS / deploy (push) Failing after 49s
feat: extend skills with dynamic resolution and RBAC, add API docs
- Add resolveAnalysisMode() to modes/index.ts for dynamic skill lookup
- Extend structured-analysis.ts to use resolveAnalysisMode (supports custom skill prompts and skillId persistence)
- Update structured analyses route to use resolveAnalysisMode instead of hardcoded VALID_MODES set
- Add skills:read/create/edit/delete RBAC permissions to rbac.ts
- Add docs/API_GUIDE.md with full endpoint reference

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-15 08:22:33 +00:00

15 KiB

StageAI API Usage Guide

This guide covers all API endpoints with practical examples for text and office document sources.

Base URL

http://localhost:3000/api

1. Authentication

Register a New Tenant

Creates a new tenant (law firm) and its first admin user.

curl -X POST http://localhost:3000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Dr. Müller",
    "email": "mueller@kanzlei.de",
    "password": "securepassword123",
    "tenantName": "Kanzlei Müller"
  }'

Response (201):

{
  "user": {
    "id": "uuid",
    "email": "mueller@kanzlei.de",
    "name": "Dr. Müller",
    "role": "admin"
  },
  "tenant": {
    "id": "uuid",
    "name": "Kanzlei Müller",
    "slug": "kanzlei-mueller"
  }
}

Authentication uses NextAuth.js with the Credentials provider. Sign in to get a session cookie:

curl -X POST http://localhost:3000/api/auth/callback/credentials \
  -H "Content-Type: application/json" \
  -d '{"email": "mueller@kanzlei.de", "password": "securepassword123"}' \
  -c cookies.txt

Use -b cookies.txt on subsequent requests to send the session cookie.

Session Info

curl http://localhost:3000/api/auth/session -b cookies.txt

Returns the current user session including tenantId, userId, role, email, and name.

Note: Sessions expire after 8 hours. All protected endpoints require a valid session cookie. Tenant isolation is enforced at the database level via Row-Level Security.


2. Cases (Fälle)

Create a Case

curl -X POST http://localhost:3000/api/cases \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "caseNumber": "2024-BSchG-001",
    "title": "Nichtverlängerung Solist",
    "clientName": "Max Mustermann",
    "opposingParty": "Staatstheater Berlin",
    "venue": "Bühnenschiedsgericht Berlin",
    "status": "active",
    "domains": ["nv_buehne", "arbeitsrecht"]
  }'

Response (201):

{
  "id": "uuid",
  "caseNumber": "2024-BSchG-001",
  "title": "Nichtverlängerung Solist",
  "clientName": "Max Mustermann",
  "status": "active",
  "createdAt": "2024-01-15T10:00:00Z"
}

List Cases

# All cases
curl http://localhost:3000/api/cases -b cookies.txt

# Search + filter
curl "http://localhost:3000/api/cases?q=Mustermann&status=active&limit=10&offset=0" \
  -b cookies.txt

Get Case Details

curl http://localhost:3000/api/cases/{caseId} -b cookies.txt

Returns the case along with related analyses and proceedings.

Update / Delete a Case

# Update
curl -X PATCH http://localhost:3000/api/cases/{caseId} \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"status": "closed"}'

# Delete
curl -X DELETE http://localhost:3000/api/cases/{caseId} -b cookies.txt

3. Document Upload (Text & Office Sources)

StageAI supports PDF and DOCX files (max 10 MB). Text is extracted automatically after upload.

Upload a Generic Document

curl -X POST http://localhost:3000/api/documents \
  -b cookies.txt \
  -F "file=@/path/to/urteil.pdf" \
  -F "category=entscheidung" \
  -F "sourceScope=global"

Parameters:

Field Required Values
file Yes PDF or DOCX file
category Yes entscheidung, norm, falldokument, sonstiges
sourceScope No case (private to a case) or global
caseId No Link to a specific case
decisionId No Link to a specific decision
normInstrumentId No Link to a norm instrument

Response (201):

{
  "id": "uuid",
  "filename": "urteil.pdf",
  "mimeType": "application/pdf",
  "category": "entscheidung",
  "status": "uploaded",
  "createdAt": "2024-01-15T10:30:00Z"
}

After upload, text extraction runs asynchronously. Status progresses: uploaded -> extracting -> extracted (or failed).

List Documents

# All documents
curl "http://localhost:3000/api/documents" -b cookies.txt

# Filter by category and scope
curl "http://localhost:3000/api/documents?category=entscheidung&sourceScope=global&limit=20&offset=0" \
  -b cookies.txt

4. Contract Analysis (Vertragsanalyse)

Upload employment contracts (NV Bühne) for AI-powered clause analysis.

Upload a Contract

curl -X POST http://localhost:3000/api/contracts \
  -b cookies.txt \
  -F "file=@/path/to/arbeitsvertrag.pdf" \
  -F "caseId=uuid-of-case"

Response (201):

{
  "id": "uuid",
  "filename": "arbeitsvertrag.pdf",
  "mimeType": "application/pdf",
  "status": "uploaded",
  "caseId": "uuid-of-case"
}

Trigger Clause Analysis

After uploading, trigger the AI analysis:

curl -X POST http://localhost:3000/api/contracts/{contractId}/analyze \
  -b cookies.txt

This extracts text from the document, identifies contract clauses, and compares them against NV Bühne standard clauses. The status progresses: uploaded -> extracting -> extracted -> analyzing -> completed.

Get Contract with Analysis Results

curl http://localhost:3000/api/contracts/{contractId} \
  -H "x-tenant-id: your-tenant-id" \
  -b cookies.txt

Response (200):

{
  "document": {
    "id": "uuid",
    "filename": "arbeitsvertrag.pdf",
    "status": "completed"
  },
  "clauses": [
    {
      "id": "uuid",
      "category": "Vergütung",
      "extractedText": "Die monatliche Gage beträgt...",
      "rating": "standard",
      "analysis": "Entspricht der Gagenklasse III NV Bühne.",
      "riskScore": 5,
      "deviations": []
    },
    {
      "id": "uuid",
      "category": "Nichtverlängerung",
      "extractedText": "Der Vertrag kann mit einer Frist von...",
      "rating": "kritisch",
      "analysis": "Die Frist weicht von § 69 NV Bühne ab.",
      "riskScore": 85,
      "deviations": ["Frist kürzer als tariflich vorgesehen"]
    }
  ]
}

Clause Categories: Vertragsparteien, Vertragsdauer, Nichtverlängerung, Vergütung, Arbeitszeit, Proben, Gastspiele, Urlaub, Krankheit, Kündigung, Nebentätigkeit, Geheimhaltung, Sonstiges

Ratings: standard (conforms to NV Bühne), abweichend (deviates), kritisch (critical deviation), unbekannt (unclassifiable)

List Contracts

curl "http://localhost:3000/api/contracts?limit=20&offset=0" -b cookies.txt

Create a Norm Instrument

curl -X POST http://localhost:3000/api/norms \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "type": "tarifvertrag",
    "sourceRank": "tarifvertrag",
    "abbreviation": "NV Bühne",
    "fullTitle": "Normalvertrag Bühne",
    "enactedAt": "2023-01-01",
    "issuingBody": "GDBA / VdO / DBV"
  }'

Import Norm Provisions (Bulk)

curl -X POST http://localhost:3000/api/norms/import \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "instrumentId": "uuid-of-instrument",
    "provisions": [
      {
        "paragraph": "§ 1",
        "title": "Geltungsbereich",
        "body": "Dieser Normalvertrag gilt für alle Bühnenmitglieder...",
        "validFrom": "2023-01-01",
        "domains": ["nv_buehne"]
      },
      {
        "paragraph": "§ 69",
        "title": "Nichtverlängerungsmitteilung",
        "body": "Die Nichtverlängerungsmitteilung muss bis zum 31. Oktober...",
        "validFrom": "2023-01-01",
        "domains": ["nv_buehne", "nichtverlängerung"]
      }
    ]
  }'

Query Norms (with Temporal Versioning)

Retrieve all paragraphs of an instrument valid on a specific date:

# Norms valid today (default)
curl http://localhost:3000/api/norms/{instrumentId} -b cookies.txt

# Norms valid on a specific date (Stichtag)
curl "http://localhost:3000/api/norms/{instrumentId}?date=2024-06-15" -b cookies.txt

Response (200):

{
  "instrument": {
    "id": "uuid",
    "abbreviation": "NV Bühne",
    "fullTitle": "Normalvertrag Bühne",
    "type": "tarifvertrag"
  },
  "provisions": [
    {
      "id": "uuid",
      "paragraph": "§ 1",
      "title": "Geltungsbereich",
      "body": "Dieser Normalvertrag gilt für alle Bühnenmitglieder...",
      "validFrom": "2023-01-01",
      "validTo": null
    }
  ]
}

6. Decisions (Entscheidungen)

Create a Decision

curl -X POST http://localhost:3000/api/decisions \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "type": "schiedsspruch",
    "caseReference": "BSchG Berlin 3/2024",
    "decisionDate": "2024-03-15",
    "court": "Bühnenschiedsgericht Berlin",
    "headnote": "Zur Wirksamkeit einer Nichtverlängerungsmitteilung...",
    "tenor": "Der Schiedsspruch wird aufgehoben...",
    "facts": "Der Kläger ist seit 2018 als Solist...",
    "reasoning": "Die Nichtverlängerungsmitteilung ist unwirksam, weil...",
    "domains": ["nv_buehne", "nichtverlängerung"],
    "keywords": ["Nichtverlängerung", "Solist", "Fristversäumnis"]
  }'

Full-Text Search for Decisions

Uses PostgreSQL full-text search with German language support:

# Search by keyword
curl "http://localhost:3000/api/decisions?q=Vergütung" -b cookies.txt

# Combined filters
curl "http://localhost:3000/api/decisions?q=Nichtverlängerung&court=Bühnenschiedsgericht&type=schiedsspruch&dateFrom=2020-01-01&dateTo=2024-12-31" \
  -b cookies.txt
curl -X POST http://localhost:3000/api/decisions/{decisionId}/norms \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "normId": "uuid-of-norm-paragraph",
    "applicationType": "angewendet",
    "passage": "Rn. 15-18"
  }'

Application types: angewendet (applied), zitiert (cited), ausgelegt (interpreted), verworfen (rejected)


Create a Streaming Analysis

curl -X POST http://localhost:3000/api/analyses \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "mode": "gutachten",
    "title": "Wirksamkeit der Nichtverlängerung",
    "query": "Ist die Nichtverlängerungsmitteilung vom 15.11.2024 wirksam, wenn der Solist seit 15 Jahren am Haus beschäftigt ist?",
    "normIds": ["uuid-of-§69-nv-buehne"],
    "decisionIds": ["uuid-of-relevant-decision"],
    "documentIds": ["uuid-of-uploaded-document"],
    "stichtag": "2024-11-15",
    "caseId": "uuid-of-case"
  }'

The response streams text (the AI-generated analysis). The X-Analysis-Id response header contains the analysis ID for later retrieval.

Analysis Modes:

Mode Purpose Requires
gutachten Expert legal opinion Norms
entscheidung Decision proposal based on precedent Decisions
vergleich Comparative analysis Norms or decisions
risiko Risk assessment with probability ratings Any sources

Create a Structured Analysis (JSON Output)

curl -X POST http://localhost:3000/api/analyses/structured \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "mode": "risiko",
    "query": "Risikobewertung für die Kündigung eines Chormitglieds nach § 626 BGB",
    "normIds": ["uuid1"],
    "decisionIds": ["uuid2"]
  }'

Returns typed JSON with structured fields depending on the mode.

List & Retrieve Analyses

# List (metadata only, DSGVO-compliant)
curl "http://localhost:3000/api/analyses?limit=20&offset=0" -b cookies.txt

# Get single analysis with full result and sources
curl http://localhost:3000/api/analyses/{analysisId} \
  -H "x-tenant-id: your-tenant-id" \
  -b cookies.txt

8. Proceedings (Verfahren)

Create a Proceeding

curl -X POST http://localhost:3000/api/proceedings \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "your-tenant-id",
    "type": "bschgo_bezirk",
    "caseId": "uuid-of-case",
    "applicant": "Max Mustermann",
    "respondent": "Staatstheater Berlin",
    "subject": "Nichtverlängerung Spielzeit 2024/25"
  }'

Proceeding types: bschgo_bezirk, bschgo_bund, arbgg_erste_instanz, arbgg_berufung, arbgg_revision

Workflow steps and initial deadlines are automatically created from templates.

Check Deadlines

# All deadlines
curl http://localhost:3000/api/proceedings/{proceedingId}/deadlines

# Only overdue deadlines
curl "http://localhost:3000/api/proceedings/{proceedingId}/deadlines?overdue=true"

# Upcoming in next 14 days
curl "http://localhost:3000/api/proceedings/{proceedingId}/deadlines?upcoming=14"

Advance Proceeding

curl -X POST http://localhost:3000/api/proceedings/{proceedingId}/advance \
  -b cookies.txt

9. NV Bühne Utilities

These are public endpoints (no auth required) for quick calculations.

Calculate Compensation (Gage)

# GET (simple query)
curl "http://localhost:3000/api/nv-buehne/compensation?gagenklasse=III&yearsOfService=5&spielzeit=2024/25&fachgruppe=Solo"

# POST (with tenant-specific rules)
curl -X POST http://localhost:3000/api/nv-buehne/compensation \
  -H "Content-Type: application/json" \
  -d '{
    "gagenklasse": "III",
    "yearsOfService": 5,
    "spielzeit": "2024/25",
    "fachgruppe": "Solo",
    "tenantId": "uuid",
    "fachgruppeId": "uuid"
  }'

Check Non-Renewal Deadline (Nichtverlängerungsfrist)

curl "http://localhost:3000/api/nv-buehne/deadline-check?yearsOfService=15&isOver55=false&spielzeit=2024/25&fachgruppe=Solo&referenceDate=2024-10-31"

Get Current Spielzeit (Season)

curl "http://localhost:3000/api/nv-buehne/spielzeit"
# or for a specific date:
curl "http://localhost:3000/api/nv-buehne/spielzeit?date=2024-09-01"

10. Settings

Manage AI Provider API Keys

# List keys (returns hints only, never full keys)
curl http://localhost:3000/api/settings/api-keys -b cookies.txt

# Add an API key
curl -X POST http://localhost:3000/api/settings/api-keys \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "provider": "anthropic",
    "apiKey": "sk-ant-...",
    "label": "Production Key"
  }'

Keys are encrypted at rest with AES-256-GCM.


Pagination

All list endpoints support pagination:

?limit=20&offset=0

Response format:

{
  "data": [...],
  "pagination": {
    "total": 100,
    "limit": 20,
    "offset": 0,
    "hasMore": true
  }
}

Error Handling

All errors return JSON:

{
  "error": "Human-readable error message"
}
Status Meaning
400 Validation error (missing/invalid fields)
401 Not authenticated (missing or expired session)
403 Permission denied (role lacks required permission)
404 Resource not found
409 Conflict (duplicate entry)
413 File too large (max 10 MB)

User Roles & Permissions

Role Permissions
admin Full access, manage settings & users
attorney Create/edit cases, analyses, norms, decisions
paralegal Read access + limited write
viewer Read-only

Typical Workflow

  1. Register a tenant and admin user
  2. Configure AI provider API key in Settings
  3. Create norms (import NV Bühne provisions)
  4. Upload decisions (create + link applicable norms)
  5. Create a case for a client
  6. Upload documents (court rulings, contracts as PDF/DOCX)
  7. Upload & analyze a contract to identify clause deviations
  8. Run AI analyses referencing norms, decisions, and documents
  9. Create proceedings to track deadlines and workflow steps