Enterprise API

Book Appearance Attorneys
Programmatically

Integrate CourtCounsel directly into your legal platform. POST a hearing, GET matched attorneys, receive webhooks on confirmation. Built for AI legal companies, practice management platforms, and high-volume law firms.

API Key Auth JSON REST API Webhook Events All 50 States Sandbox Included

CourtCounsel Enterprise API

The CourtCounsel API lets your platform programmatically book bar-verified appearance attorneys across all 50 states. When your application identifies a court date — from a calendar event, case management system, or AI workflow — a single API call posts the appearance request, triggers matching against our attorney network, and returns confirmation within hours.

All endpoints return JSON. The API uses API key authentication via a request header. Sandbox mode is available for integration testing at no charge.

Enterprise Access: API keys are issued to approved partners. To request access, contact api@courtcounsel.ai or use the contact form. Sandbox keys are available immediately; production keys are issued after brief integration review.

API Key Authentication

Every request must include your API key in the X-API-Key header. Keys are scoped to your organization and tied to your enterprise client record — all requests are attributed to your account automatically.

Required Header

Include X-API-Key: YOUR_API_KEY in every request. Requests without a valid key return 401 Unauthorized.

Example Request Header
POST https://app.courtcounsel.ai/api/v1/enterprise/post
Content-Type: application/json
X-API-Key: cc_live_a1b2c3d4e5f6g7h8i9j0...

Keep your API key secret. Do not expose it in client-side code, public repositories, or logs. Rotate keys immediately at app.courtcounsel.ai/admin if compromised.

Endpoints & Versioning

All API endpoints are served from https://app.courtcounsel.ai/api/v1/. The current version is v1. Breaking changes will be versioned; existing clients will receive 90-day deprecation notice before any v1 sunset.

# Base URL
https://app.courtcounsel.ai/api/v1/

# Enterprise endpoints
POST   /enterprise/post              # Create appearance request
GET    /enterprise/requests          # List your requests
GET    /enterprise/requests/{id}     # Get request details

HTTP Status Codes

The API uses standard HTTP status codes. All error responses include a JSON body with an error field describing the issue.

CodeMeaningCommon Cause
200OKRequest succeeded
201CreatedAppearance request created successfully
400Bad RequestMissing required fields or invalid data
401UnauthorizedMissing or invalid API key
403ForbiddenAPI key lacks permission for this action
404Not FoundRequest ID not found or belongs to another client
429Too Many RequestsRate limit exceeded — see Rate Limits
500Server ErrorInternal error — retry with exponential backoff

POST /enterprise/post

Creates a new appearance request. Once submitted, the matching algorithm immediately notifies qualified attorneys in the target jurisdiction. Most requests receive attorney confirmation within 4–8 hours.

POST /api/v1/enterprise/post
Creates an appearance request and begins attorney matching. Returns the request ID and initial status.
Request Body (JSON)
FieldTypeRequiredDescription
courthouse string Required Full courthouse name, e.g. "Los Angeles Superior Court – Stanley Mosk"
state string Required Two-letter state code, e.g. "CA", "TX", "NY"
hearing_date string Required ISO 8601 date: "2026-05-15"
case_type string Required E.g. "Status Conference", "Motion Hearing", "Arraignment", "Immigration Hearing"
hearing_time string Optional 24h format: "09:30". Required for same-day or urgent bookings.
courthouse_address string Optional Full street address for proximity matching accuracy
case_number string Optional Court-assigned case number for attorney reference
description string Optional Instructions for the attorney, background on the hearing, special requirements
contact_email string Optional Email to receive attorney confirmation and outcome report. Defaults to API key account email.
budget_min integer Optional Minimum acceptable attorney fee in USD. Default: 250
budget_max integer Optional Maximum attorney fee in USD. Default: 500
urgency string Optional "standard" (default, 24h+ lead time) | "urgent" (4–24h) | "emergency" (<4h, premium pricing)
curl -X POST https://app.courtcounsel.ai/api/v1/enterprise/post \
  -H "Content-Type: application/json" \
  -H "X-API-Key: cc_live_your_key_here" \
  -d '{
    "courthouse": "U.S. District Court - Southern District of New York",
    "state": "NY",
    "hearing_date": "2026-05-20",
    "hearing_time": "10:00",
    "courthouse_address": "500 Pearl Street, New York, NY 10007",
    "case_type": "Status Conference",
    "case_number": "1:26-cv-04512",
    "description": "Plaintiff appearing for routine status conference. Supervising attorney is lead PI counsel. Attorney must be SDNY admitted.",
    "contact_email": "cases@yourfirm.com",
    "budget_max": 400,
    "urgency": "standard"
  }'
import requests

url = "https://app.courtcounsel.ai/api/v1/enterprise/post"
headers = {
    "Content-Type": "application/json",
    "X-API-Key": "cc_live_your_key_here"
}
payload = {
    "courthouse": "U.S. District Court - Southern District of New York",
    "state": "NY",
    "hearing_date": "2026-05-20",
    "hearing_time": "10:00",
    "case_type": "Status Conference",
    "case_number": "1:26-cv-04512",
    "budget_max": 400,
    "urgency": "standard"
}

response = requests.post(url, json=payload, headers=headers)
data = response.json()
print(f"Request ID: {data['id']}, Status: {data['status']}")
// Using fetch (Node 18+)
const response = await fetch(
  "https://app.courtcounsel.ai/api/v1/enterprise/post",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": "cc_live_your_key_here"
    },
    body: JSON.stringify({
      courthouse: "U.S. District Court - Southern District of New York",
      state: "NY",
      hearing_date: "2026-05-20",
      hearing_time: "10:00",
      case_type: "Status Conference",
      case_number: "1:26-cv-04512",
      budget_max: 400,
      urgency: "standard"
    })
  }
);
const { id, status } = await response.json();
console.log(`Request ${id} created — status: ${status}`);
Response — 201 Created
201 CreatedRequest created successfully
{
  "id": "a3f8c2b1d4e9",
  "status": "open",
  "message": "Request created. Matching in progress."
}

GET /enterprise/requests

Returns all appearance requests associated with your API key. Results are sorted by creation date, most recent first. Limited to 100 results per call.

GET /api/v1/enterprise/requests
Lists your organization's appearance requests. No request body required.
Response Fields
FieldTypeDescription
requestsarrayArray of request objects
countintegerTotal number of requests returned
idstringUnique request ID (16 hex chars)
statusstringopen | matched | confirmed | completed | cancelled
matched_attorney_idstring | nullAttorney ID once matched; null until then
courthousestringCourthouse as submitted
statestringTwo-letter state
hearing_datestringISO 8601 date
created_atstringISO 8601 datetime (UTC)
Example Response
{
  "requests": [
    {
      "id": "a3f8c2b1d4e9",
      "courthouse": "U.S. District Court - SDNY",
      "state": "NY",
      "hearing_date": "2026-05-20",
      "case_type": "Status Conference",
      "urgency": "standard",
      "status": "confirmed",
      "budget_min": 250,
      "budget_max": 400,
      "matched_attorney_id": "atty_8f3a1c9",
      "created_at": "2026-05-14T18:42:31Z"
    }
  ],
  "count": 1
}

GET /enterprise/requests/{id}

Retrieves full details for a specific appearance request, including matched attorney information and outcome report once the appearance is complete.

GET /api/v1/enterprise/requests/{id}
Returns complete details for a single request. The {id} path parameter is the 16-character hex ID returned at creation.
Additional Response Fields (vs. list)
FieldTypeDescription
descriptionstringHearing description as submitted
case_numberstringCase number as submitted
contact_emailstringNotification email on file
outcome_reportstring | nullAttorney's post-hearing outcome report. Populated after completion.
hearing_timestring | nullHearing time if provided
updated_atstringLast status update timestamp (UTC)

Webhook Notifications

CourtCounsel sends webhook events to your registered endpoint URL when key status changes occur. Configure your webhook URL in the Enterprise Dashboard or via api@courtcounsel.ai.

Webhooks are in active development. Event delivery is live for request.confirmed and request.completed. Additional event types ship Q2 2026. Contact api@courtcounsel.ai to register your endpoint.

EventWhen FiredPayload
request.confirmedAttorney accepts the assignmentRequest object + attorney name and bar number
request.completedAttorney files outcome reportRequest object + full outcome report text
request.cancelledRequest cancelled (client or no match)Request object + cancellation reason
request.matchedAttorney matched, awaiting acceptanceRequest object + match score
Example Webhook Payload
{
  "event": "request.confirmed",
  "timestamp": "2026-05-14T22:15:08Z",
  "data": {
    "id": "a3f8c2b1d4e9",
    "status": "confirmed",
    "attorney_name": "Jane R. Smith, Esq.",
    "attorney_bar": "NY-5471823",
    "hearing_date": "2026-05-20",
    "courthouse": "U.S. District Court - SDNY"
  }
}

Rate Limits

Rate limits are applied per API key. Exceeding the limit returns 429 Too Many Requests with a Retry-After header indicating when to retry.

Sandbox
100
requests / day
Standard
1,000
requests / day
Enterprise
Unlimited
custom SLA

Full Workflow Example

The typical integration pattern: detect a court date in your system, POST a request, poll for status changes (or use webhooks), and surface confirmation to your users.

import requests, time

API_KEY = "cc_live_your_key_here"
BASE    = "https://app.courtcounsel.ai/api/v1"
HEADERS = {"Content-Type": "application/json", "X-API-Key": API_KEY}

# 1. Create appearance request
resp = requests.post(f"{BASE}/enterprise/post", json={
    "courthouse": "Cook County Circuit Court - Daley Center",
    "state": "IL",
    "hearing_date": "2026-06-10",
    "case_type": "Motion Hearing",
    "urgency": "standard"
}, headers=HEADERS)

request_id = resp.json()["id"]
print(f"Created: {request_id}")

# 2. Poll for confirmation (or use webhook)
for _ in range(12):
    time.sleep(3600)  # check every hour
    detail = requests.get(
        f"{BASE}/enterprise/requests/{request_id}",
        headers=HEADERS
    ).json()
    if detail["status"] == "confirmed":
        print("Attorney confirmed! Notify client.")
        break
const API_KEY = "cc_live_your_key_here";
const BASE    = "https://app.courtcounsel.ai/api/v1";
const headers = {
  "Content-Type": "application/json",
  "X-API-Key": API_KEY
};

// 1. Create appearance request
const createRes = await fetch(`${BASE}/enterprise/post`, {
  method: "POST", headers,
  body: JSON.stringify({
    courthouse: "Cook County Circuit Court - Daley Center",
    state: "IL",
    hearing_date: "2026-06-10",
    case_type: "Motion Hearing",
    urgency: "standard"
  })
});
const { id } = await createRes.json();
console.log(`Created: ${id}`);

// 2. Check status (in production: use webhooks instead)
const pollStatus = async (requestId) => {
  const res = await fetch(`${BASE}/enterprise/requests/${requestId}`, { headers });
  return res.json();
};

const detail = await pollStatus(id);
console.log(`Status: ${detail.status}`);

SDKs & Libraries

Official SDKs are in development. In the meantime, the REST API works with any HTTP client. Below are the packages we recommend for integration.

LanguageRecommended LibraryInstall
Pythonrequestspip install requests
Node.jsNative fetch (18+) or axiosnpm install axios
Rubyfaradaygem install faraday
GoStandard net/httpBuilt-in
JavaOkHttpMaven/Gradle
PHPGuzzlecomposer require guzzlehttp/guzzle

Official Python and Node SDKs are on the roadmap for Q3 2026. To be notified on release, contact api@courtcounsel.ai.

Ready to Integrate?

Get sandbox access within 24 hours. No commitment required. Our team will walk you through authentication and your first test request.