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.
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.
| Code | Meaning | Common Cause |
|---|---|---|
| 200 | OK | Request succeeded |
| 201 | Created | Appearance request created successfully |
| 400 | Bad Request | Missing required fields or invalid data |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | API key lacks permission for this action |
| 404 | Not Found | Request ID not found or belongs to another client |
| 429 | Too Many Requests | Rate limit exceeded — see Rate Limits |
| 500 | Server Error | Internal 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.
| Field | Type | Required | Description |
|---|---|---|---|
| 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}`);
{
"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.
| Field | Type | Description |
|---|---|---|
| requests | array | Array of request objects |
| count | integer | Total number of requests returned |
| id | string | Unique request ID (16 hex chars) |
| status | string | open | matched | confirmed | completed | cancelled |
| matched_attorney_id | string | null | Attorney ID once matched; null until then |
| courthouse | string | Courthouse as submitted |
| state | string | Two-letter state |
| hearing_date | string | ISO 8601 date |
| created_at | string | ISO 8601 datetime (UTC) |
{
"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.
{id} path parameter is the 16-character hex ID returned at creation.| Field | Type | Description |
|---|---|---|
| description | string | Hearing description as submitted |
| case_number | string | Case number as submitted |
| contact_email | string | Notification email on file |
| outcome_report | string | null | Attorney's post-hearing outcome report. Populated after completion. |
| hearing_time | string | null | Hearing time if provided |
| updated_at | string | Last 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.
| Event | When Fired | Payload |
|---|---|---|
| request.confirmed | Attorney accepts the assignment | Request object + attorney name and bar number |
| request.completed | Attorney files outcome report | Request object + full outcome report text |
| request.cancelled | Request cancelled (client or no match) | Request object + cancellation reason |
| request.matched | Attorney matched, awaiting acceptance | Request object + match score |
{
"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.
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.
| Language | Recommended Library | Install |
|---|---|---|
| Python | requests | pip install requests |
| Node.js | Native fetch (18+) or axios | npm install axios |
| Ruby | faraday | gem install faraday |
| Go | Standard net/http | Built-in |
| Java | OkHttp | Maven/Gradle |
| PHP | Guzzle | composer require guzzlehttp/guzzle |
Official Python and Node SDKs are on the roadmap for Q3 2026. To be notified on release, contact api@courtcounsel.ai.