Authentication

All requests require an API key passed in the X-API-Key header:

X-API-Key: your_api_key_here

Base URL

{baseUrl}/api/partner/v1

Workflow Overview

1
Create Case
POST /cases
2
Upload Docs
POST /evidence
3
Trigger Processing
POST /process
4
Get Results
GET /cases/{id}

Step 1: Create a Case

Request

POST /cases
POST /cases
Content-Type: application/json
X-API-Key: your_api_key

{
  "external_case_id": "YOUR-REFERENCE-001",
  "ombudsman": "your_tenant_id",
  "case_type_id": "your_case_type_uuid",
  "case_title": "Customer billing dispute"
}

Request Fields

Field Required Type Description
external_case_id Yes string Your unique case reference
ombudsman Yes string Your tenant ID (provided during onboarding)
case_type_id Recommended uuid Case type for field extraction
case_title No string Human-readable case title
case_initiated_date No string ISO 8601 date (e.g., "2025-01-15")

Response

{
  "case_id": "80058c5f-100e-428d-b547-79da822b736b",
  "external_case_id": "YOUR-REFERENCE-001",
  "ombudsman": "your_tenant_id",
  "case_type_id": "2b5b8bcd-3a0d-4a22-a5b9-53d4a58c1496",
  "case_type_name": "Default",
  "status": "created",
  "case_title": "Customer billing dispute",
  "case_summary": null,
  "case_specific_fields": null,
  "processing_started_at": null,
  "processing_completed_at": null,
  "created_at": "2026-02-02T10:21:41.558Z",
  "updated_at": "2026-02-02T10:21:41.558Z",
  "chronology": [],
  "evidence": []
}
Important: Save the case_id - you'll need it for all subsequent requests.

Step 2: Upload Evidence Documents

Upload PDF, DOCX, or image files as evidence. Each document is automatically queued for AI processing.

Request

POST /cases/{case_id}/evidence
POST /cases/{case_id}/evidence
Content-Type: multipart/form-data
X-API-Key: your_api_key

file: [binary file data]

Response (Immediately After Upload)

{
  "document_id": "1d7e21ab-fb5d-40ca-b6bf-b14357ce11d9",
  "case_id": "80058c5f-100e-428d-b547-79da822b736b",
  "external_document_id": null,
  "status": "pending_processing",
  "uploaded_at": "2026-02-02T10:22:11.544Z",
  "title": null,
  "short_description": null,
  "summary": null,
  "case_insights": null,
  "event_date": null,
  "event_date_start": null,
  "event_date_end": null,
  "claimant_support_score": null,
  "defendant_support_score": null
}
Note: Repeat for each document. Upload all evidence files before triggering processing.

Step 2b: Poll for Document Processing

Poll each document until all reach processing_complete status before proceeding to Step 3.

Request

GET /cases/{case_id}/evidence/{document_id}

Document Status Progression

Status Description
pending_processing Document uploaded, waiting in queue
processing AI is analyzing the document
processing_complete Processing finished, AI fields populated
processing_failed Processing failed

Example: Polling Multiple Documents

Poll 1 (5s):   doc1: processing_complete, doc2: processing_complete, doc3: pending_processing
Poll 2 (10s):  doc1: processing_complete, doc2: processing_complete, doc3: processing
Poll 3 (15s):  doc1: processing_complete, doc2: processing_complete, doc3: processing_complete

Response (After Processing Complete)

{
  "document_id": "1d7e21ab-fb5d-40ca-b6bf-b14357ce11d9",
  "case_id": "80058c5f-100e-428d-b547-79da822b736b",
  "external_document_id": null,
  "status": "processing_complete",
  "uploaded_at": "2026-02-02T10:22:11.544Z",
  "title": "Complaint Form - Jack Grainger v Sonicwave - Contract Discount and Early Termination Fee Dispute",
  "short_description": "Customer complaint regarding removal of contractual monthly discount and disputed early termination fee charged by Sonicwave.",
  "summary": "# Complaint Form - Jack Grainger v Sonicwave...\n\nThis is a formal complaint submission form documenting a dispute between a customer and their service provider...",
  "case_insights": "- Claimant's position: discount was for full contract duration\n- Disputes April price increase\n- Disputes £130 ETF\n- Remedy sought: £12 + £130 refund minimum\n- First complained: 15/07/2025\n- Deadlock letter received: 18/05/2025",
  "event_date": "2025-07-15T00:00:00.000Z",
  "event_date_start": "2025-07-15T00:00:00.000Z",
  "event_date_end": "2025-07-15T00:00:00.000Z",
  "claimant_support_score": 7,
  "defendant_support_score": 2
}
Note: The case_insights and support scores are populated after document processing completes. These provide key facts relevant to the dispute and indicate how strongly the document supports each party.

Step 3: Trigger Case Assessment

Once all documents have status: processing_complete, trigger the AI case assessment.

Request

POST /cases/{case_id}/process

Response

{
  "case_id": "80058c5f-100e-428d-b547-79da822b736b",
  "status": "processing"
}

Error: Documents Not Ready

If any documents are still processing:

{
  "statusCode": 400,
  "message": "Cannot process case: documents are still being processed"
}
Note: Wait for all documents to complete before retrying.

Step 4: Poll for Assessment Completion

Poll the case endpoint until status changes to processed.

Request

GET /cases/{case_id}

Case Status Progression

Status Description
created Case created, awaiting documents
processing AI assessment in progress
processed Assessment complete
error Assessment failed

Example: Polling Case Status

[10s]  Status: processing
[20s]  Status: processing
[30s]  Status: processing
...
[120s] Status: processed

Step 5: Retrieve Full Results

Once status is processed, the case contains the complete AI assessment.

Request

GET /cases/{case_id}

Full Response

{
  "case_id": "80058c5f-100e-428d-b547-79da822b736b",
  "external_case_id": "JACK-GRAINGER-1770027701",
  "ombudsman": "your_tenant_id",
  "case_type_id": "2b5b8bcd-3a0d-4a22-a5b9-53d4a58c1496",
  "case_type_name": "Default",
  "status": "processed",
  "case_title": "Broadband Promotional Pricing And Termination Fee",
  "case_summary": "This case concerns a dispute between a broadband customer and their provider over promotional pricing terms and early termination fees. The claimant believed a £12 monthly discount would apply for the full 18-month contract term, but the provider applied it only for the first 12 months as stated in the welcome email...",
  "case_specific_fields": "- Claimant: Jack Grainger\n- Respondent: Sonicwave Broadband Ltd\n- ABTA Case Reference: Not found\n- Internal Case Reference: CW-2025-038\n- Total Holiday Cost: Not found\n- Amount Claimed: £142.00\n- Pre-Arbitration Offer: Not found",
  "processing_started_at": null,
  "processing_completed_at": "2026-02-02T10:26:15.922Z",
  "created_at": "2026-02-02T10:21:41.558Z",
  "updated_at": "2026-02-02T10:26:15.922Z",
  "chronology": [...],
  "evidence": [...]
}

Response Field Reference

Case Fields

Field Type Description
case_id uuid Internal case identifier
external_case_id string Your case reference
status string Case status
case_title string AI-generated case title
case_summary string AI-generated comprehensive case summary
case_specific_fields string Extracted case-specific fields as markdown bullet list (based on case type configuration)
processing_completed_at string ISO timestamp when assessment completed
chronology array AI-generated timeline of events
evidence array List of evidence documents with AI analysis

Evidence Document Fields

Field Type Description
document_id uuid Document identifier
external_document_id string Your document reference (if provided)
status string Processing status
title string AI-generated document title
short_description string Brief summary (1-2 sentences)
summary string Full markdown summary
case_insights string Key facts relevant to the dispute
event_date string Primary date from document
event_date_start string Date range start
event_date_end string Date range end
claimant_support_score integer How strongly document supports claimant (0-10)
defendant_support_score integer How strongly document supports defendant (0-10)

Chronology Entry Fields

Field Type Description
timeline_id uuid Timeline entry identifier
title string Event title
description string Event description
timeline_date string ISO timestamp of event
documents array Associated document references
is_ai_generated boolean Whether entry was AI-generated

Example: Case Specific Fields

The case_specific_fields contains AI-extracted key information as a markdown-formatted bullet list. The fields extracted depend on the case type configuration.

Example Response

{
  "case_specific_fields": "- Claimant: Jack Grainger\n- Respondent: Sonicwave Broadband Ltd\n- ABTA Case Reference: Not found\n- Internal Case Reference: CW-2025-038\n- Total Holiday Cost: Not found\n- Amount Claimed: £142.00\n- Pre-Arbitration Offer: Not found"
}

Rendered Output

  • Claimant: Jack Grainger
  • Respondent: Sonicwave Broadband Ltd
  • ABTA Case Reference: Not found
  • Internal Case Reference: CW-2025-038
  • Total Holiday Cost: Not found
  • Amount Claimed: £142.00
  • Pre-Arbitration Offer: Not found
Note: The fields extracted are configured per case type. Contact your account manager to customize which fields are extracted for your use case.

Example: Chronology Response

The AI extracts and orders key events from all documents:

{
  "chronology": [
    {
      "timeline_id": "cd49cd8b-1af5-4ba2-a874-1a9bd2c6f2a9",
      "title": "Contract signed",
      "description": "Jack Grainger signed an 18-month contract with Sonicwave for the Ultimate Fibre 100 plan.",
      "timeline_date": "2024-04-03T00:00:00.000Z",
      "documents": [
        {"document_id": "3e75c2b8-2dac-4618-80f0-c4f94bc02557", "external_document_id": null}
      ],
      "is_ai_generated": true
    },
    {
      "timeline_id": "52d24b05-f4f8-4bb3-8ea2-d7038e7da224",
      "title": "Promotional period ended",
      "description": "The 12-month promotional period at £23.99/month ended, after which the standard rate of £35.99/month applied.",
      "timeline_date": "2025-04-07T00:00:00.000Z",
      "documents": [
        {"document_id": "c239cd5e-17c6-4f77-9304-71721e5f1565", "external_document_id": null}
      ],
      "is_ai_generated": true
    },
    {
      "timeline_id": "2b0cffd1-c718-4709-af07-fd39e2984888",
      "title": "Cancellation requested",
      "description": "Jack Grainger contacted Sonicwave via chat to terminate his broadband contract. Agent confirmed an early termination fee would apply.",
      "timeline_date": "2025-05-09T00:00:00.000Z",
      "documents": [
        {"document_id": "2ca24f0c-e116-4d52-9dae-eb3d63bee4b6", "external_document_id": null}
      ],
      "is_ai_generated": true
    },
    {
      "timeline_id": "56136799-f3e0-4208-b09e-3ae52119cfa7",
      "title": "Deadlock letter issued",
      "description": "Sonicwave issued a final response confirming the early termination fee was applied in accordance with terms.",
      "timeline_date": "2025-05-18T00:00:00.000Z",
      "documents": [
        {"document_id": "3e75c2b8-2dac-4618-80f0-c4f94bc02557", "external_document_id": null}
      ],
      "is_ai_generated": true
    }
  ]
}

Example: Evidence with Support Scores

Each document is analyzed for how strongly it supports each party:

{
  "evidence": [
    {
      "document_id": "f56d4437-0900-4e63-9f39-529d82c46d1c",
      "title": "Sonicwave Broadband Welcome Email - Ultimate Fibre 100 Plan",
      "short_description": "Welcome email confirming subscription with promotional pricing.",
      "case_insights": "- Contract term: 18 months\n- Months 1-12: £23.99 (promotional)\n- After 12 months: £35.99 (standard)\n- Early exit fee: £130.00 clearly stated\n- Critical evidence supporting defendant's position",
      "claimant_support_score": 2,
      "defendant_support_score": 9
    },
    {
      "document_id": "1d7e21ab-fb5d-40ca-b6bf-b14357ce11d9",
      "title": "Complaint Form - Contract Discount and Early Termination Fee Dispute",
      "short_description": "Customer complaint regarding removal of contractual discount.",
      "case_insights": "- Claimant's position: discount was for full contract duration\n- Disputes £130 ETF\n- Remedy sought: £12 + £130 refund minimum",
      "claimant_support_score": 7,
      "defendant_support_score": 2
    },
    {
      "document_id": "c239cd5e-17c6-4f77-9304-71721e5f1565",
      "title": "Chat log - Billing Increase Query",
      "short_description": "Customer service chat about price increase from £23.99 to £35.99.",
      "case_insights": "- Agent confirmed promotional terms were in welcome email\n- Jack admits he 'must have missed that in the email'\n- No retention offers available",
      "claimant_support_score": 4,
      "defendant_support_score": 7
    }
  ]
}

Error Handling

Status Code Meaning Action
400 Invalid request Check request format, UUIDs, required fields
401 Unauthorized Verify API key
404 Not found Verify case_id or document_id exists
500 Server error Retry request

Example Error Response

{
  "statusCode": 400,
  "message": "Validation failed (uuid is expected)"
}

Processing Times

Stage Typical Duration
Document processing (per document) 10-30 seconds
AI case assessment (after /process) 60-180 seconds
Total end-to-end (9 documents) 3-5 minutes

Complete Integration Example

import requests
import time

API_KEY = "your_api_key"
BASE_URL = "{baseUrl}/api/partner/v1"
HEADERS = {"X-API-Key": API_KEY}

# Step 1: Create case
case_response = requests.post(
    f"{BASE_URL}/cases",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "external_case_id": "MY-CASE-001",
        "ombudsman": "your_tenant_id",
        "case_type_id": "your_case_type_uuid",
        "case_title": "Customer dispute"
    }
)
case_id = case_response.json()["case_id"]
print(f"Created case: {case_id}")

# Step 2: Upload documents
document_ids = []
for file_path in ["complaint.pdf", "contract.pdf", "correspondence.pdf"]:
    with open(file_path, "rb") as f:
        response = requests.post(
            f"{BASE_URL}/cases/{case_id}/evidence",
            headers=HEADERS,
            files={"file": f}
        )
        document_ids.append(response.json()["document_id"])
        print(f"Uploaded: {file_path}")

# Step 2b: Wait for document processing
print("Waiting for document processing...")
while True:
    all_complete = True
    for doc_id in document_ids:
        response = requests.get(
            f"{BASE_URL}/cases/{case_id}/evidence/{doc_id}",
            headers=HEADERS
        )
        if response.json()["status"] != "processing_complete":
            all_complete = False
            break

    if all_complete:
        print("All documents processed!")
        break
    time.sleep(5)

# Step 3: Trigger assessment
requests.post(f"{BASE_URL}/cases/{case_id}/process", headers=HEADERS)
print("Assessment triggered")

# Step 4: Wait for assessment
print("Waiting for AI assessment...")
while True:
    response = requests.get(f"{BASE_URL}/cases/{case_id}", headers=HEADERS)
    status = response.json()["status"]
    print(f"Status: {status}")

    if status in ["processed", "error"]:
        break
    time.sleep(10)

# Step 5: Get results
result = requests.get(f"{BASE_URL}/cases/{case_id}", headers=HEADERS).json()
print(f"Case Title: {result['case_title']}")
print(f"Summary: {result['case_summary']}")
print(f"Timeline Events: {len(result['chronology'])}")
print(f"Documents Analyzed: {len(result['evidence'])}")