Investigate API
A free, unauthenticated REST endpoint for AI agents and developers. Send structured medical bill line items, get Medicare rate benchmarks and AI-powered billing error analysis back.
Quick Start
curl -X POST https://www.billsherlock.app/api/v1/investigate \
-H "Content-Type: application/json" \
-d '{
"line_items": [
{ "code": "99285", "charge": 4500, "description": "Emergency dept visit level 5" },
{ "code": "99291", "charge": 8200, "description": "Critical care first hour" }
],
"facility_type": "outpatient_facility",
"facility_name": "Cedar-Sinai Medical Center",
"state": "CA"
}'Endpoint Reference
| Method | POST |
| URL | https://www.billsherlock.app/api/v1/investigate |
| Content-Type | application/json |
| Auth | None required |
| Max body size | 64 KB |
| Rate limit | 10 requests/hour per IP |
Request Schema
InvestigateRequest
| Field | Type | Description |
|---|---|---|
| line_items | array (required) | 1–50 line item objects. Each must have code and charge. |
| facility_type | string | One of: professional_office, professional_facility, outpatient_facility, inpatient_facility, lab_diagnostic. |
| facility_name | string | Required when facility_type is a facility classification. Max 200 chars. |
| state | string | 2-letter uppercase US state code (e.g., "CA", "TX"). |
| payer_id | string | Payer identifier. Triggers payer ID validation rules. |
| insurance_company | string | Insurance company name. Helps contextualize payer-specific rules. |
| network_status | string | One of: IN_NETWORK, OUT_OF_NETWORK, UNKNOWN. |
InvestigateLineItem
| Field | Type | Description |
|---|---|---|
| code | string (required) | CPT/HCPCS, NDC, revenue code, or internal code. Max 20 chars. |
| code_type | string | CPT_HCPCS, NDC, REV_CODE, INTERNAL, or UNKNOWN. Auto-detected if omitted. |
| charge | number (required) | Billed amount in USD. Must be > 0, max 999,999.99. |
| description | string | Service description (not clinical notes). Max 200 chars. |
| quantity | integer | Units/quantity. 1–99, default 1. |
| modifiers | string[] | CPT modifiers (e.g., ["-25", "-59"]). Max 4 items. |
| service_date | string | YYYY-MM-DD format. Helps detect duplicates. |
| rev_code | string | UB-04 revenue code. 3–4 digit numeric. |
Code Type Auto-Detection
When code_type is omitted, the API infers it from the code format:
| Pattern | Detected as |
|---|---|
| 5-digit numeric (99285, 36556) | CPT_HCPCS |
| Letter + 4 digits (J1234, A0425) | CPT_HCPCS (HCPCS Level II) |
| 10-11 digit with dashes (53746-0442-01) | NDC |
| 3-4 digit numeric (0250, 0450) | REV_CODE |
| Anything else | UNKNOWN |
Sensitive Data Guidance
Do not send patient name, date of birth, member ID, claim number, account number, address, phone number, or full document text. The description field should contain only service descriptions, not clinical notes or patient details.
Response Schema
A successful response (200) returns the standard API envelope with data and meta fields.
line_items[] — Medicare Rate Benchmarks
| Field | Type | Description |
|---|---|---|
| code | string | Echoed from request. |
| code_type | string | Resolved code type: CPT_HCPCS, NDC, REV_CODE, INTERNAL, or UNKNOWN. |
| charge | number | Echoed from request. |
| medicare_rate | number | null | Medicare benchmark rate. Only populated for CPT/HCPCS codes with a known rate. |
| ratio | number | null | charge / medicare_rate. |
| pricing_tier | string | null | fair-price (≤2x), tier-2x (2–3x), tier-3x (3–4x), tier-4x (4–5x), tier-5x (>5x). |
| benchmark_source | string | null | Rate source: PFS, CLFS, OPPS, or PART_B_DRUGS. |
| benchmark_year | integer | null | Rate schedule year. |
| benchmark_basis | string | null | national (state-only input) or locality (ZIP resolved). |
analysis.findings[]
Present when analysis_status is "complete". Null when "unavailable".
| Field | Type | Description |
|---|---|---|
| category | string | Issue category (e.g., Coding Error, Duplicate Billing, Surprise Billing). |
| title | string | Short patient-readable label. |
| explanation | string | What the issue is and why, with policy/coding rationale. |
| financial_impact | number | Estimated savings in USD. |
| confidence_score | integer | 0–100, evidence-based confidence. |
| estimated_effort | string | LOW (phone call), MEDIUM (multiple calls/docs), HIGH (formal appeal). |
| estimated_resolution_time | string | e.g., "15-30 minutes", "1-2 hours", "2-4 weeks". |
| recommendation | string | Concrete next action for the patient. |
summary
| Field | Type | Description |
|---|---|---|
| total_charged | number | Sum of all line item charges. |
| total_medicare_benchmark | number | Sum of Medicare rates for items with rates. |
| overall_ratio | number | null | total_charged / total_medicare_benchmark. |
| findings_count | integer | Total findings (0 when analysis unavailable). |
| potential_savings | number | Sum of financial_impact across all findings. |
input_quality
Indicates how much context the caller provided. score is one of: complete, partial, or minimal. missing_fields lists fields that would improve accuracy. next_best_questions suggests questions the agent can ask the user.
analysis_status
| Value | Meaning |
|---|---|
| complete | AI analysis ran successfully. analysis contains findings. |
| unavailable | AI analysis failed. analysis is null. Medicare rate benchmarks are still returned. |
Example
Request
{
"line_items": [
{
"code": "99285",
"charge": 4500,
"description": "Emergency dept visit level 5"
},
{
"code": "99291",
"charge": 8200,
"description": "Critical care first hour"
}
],
"facility_type": "outpatient_facility",
"facility_name": "Cedar-Sinai Medical Center",
"state": "CA",
"network_status": "IN_NETWORK"
}Show full response
{
"data": {
"line_items": [
{
"code": "99285",
"code_type": "CPT_HCPCS",
"charge": 4500,
"medicare_rate": 637.41,
"ratio": 7.06,
"pricing_tier": "tier-5x",
"benchmark_source": "PFS",
"benchmark_year": 2026,
"benchmark_basis": "national"
},
{
"code": "99291",
"code_type": "CPT_HCPCS",
"charge": 8200,
"medicare_rate": 462.15,
"ratio": 17.74,
"pricing_tier": "tier-5x",
"benchmark_source": "PFS",
"benchmark_year": 2026,
"benchmark_basis": "national"
}
],
"analysis_status": "complete",
"analysis": {
"overall_assessment": "MAJOR_ISSUES",
"findings": [
{
"category": "Coding Error",
"title": "Level 5 ER Visit Without Documented Complexity",
"explanation": "99285 requires high-complexity medical decision-making...",
"financial_impact": 1800.00,
"confidence_score": 65,
"estimated_effort": "MEDIUM",
"estimated_resolution_time": "1-2 hours",
"recommendation": "Request itemized records showing medical decision-making complexity."
}
],
"quick_checks": [
"Were you in the ER for more than 30 minutes of critical care?",
"Did you receive any procedures during the ER visit?"
]
},
"summary": {
"total_charged": 12700,
"total_medicare_benchmark": 1099.56,
"overall_ratio": 11.55,
"findings_count": 2,
"potential_savings": 6300.00
},
"input_quality": {
"score": "partial",
"missing_fields": ["allowed_amount", "paid_amount"],
"next_best_questions": [
"Do you have the EOB showing what insurance paid vs. what you owe?"
]
},
"limitations": [
"Findings are based only on user-provided structured line items, not a reviewed document.",
"Medicare benchmarks are approximate.",
"This analysis is informational only and does not constitute medical, legal, or financial advice."
],
"upsell": {
"message": "We found 2 potential billing issues. Upload your full bill for a comprehensive audit.",
"url": "https://billsherlock.app/audit?ref=api-investigate",
"full_audit_includes": [
"Full document OCR",
"Hospital-specific cash prices",
"No Surprises Act detection",
"Downloadable audit report"
]
}
},
"meta": {
"timestamp": "2026-05-14T18:30:00Z",
"version": "1.0",
"rate_limit": {
"remaining": 9,
"reset_at": "2026-05-14T19:00:00Z"
}
}
}Errors & Rate Limits
| Status | Code | When |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request body, missing required fields, or body exceeds 64 KB. |
| 429 | RATE_LIMITED | Exceeded 10 requests/hour. Check Retry-After header. |
| 503 | SERVICE_UNAVAILABLE | Service temporarily unavailable. Retry with backoff. |
Example error responses
400 — Validation Error
{
"error": {
"code": "VALIDATION_ERROR",
"message": "line_items is required and must contain 1-50 items"
},
"meta": { "timestamp": "2026-05-14T18:30:00Z" }
}429 — Rate Limited
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again in 42 minutes."
},
"meta": { "timestamp": "2026-05-14T18:30:00Z" }
}Graceful Degradation
When AI analysis fails but Medicare rate lookups succeed, the endpoint returns a 200 with analysis_status: "unavailable" and analysis: null. Agents can still present rate benchmarks to users.
The unauthenticated rate limit is 10 requests per hour per IP. Agent platforms typically make one API call per user interaction, so this covers normal usage. For higher-volume integrations, contact us about API key access.
Agent Integration
ChatGPT Custom GPT
- In the GPT builder, go to Configure → Actions → Import from URL.
- Enter:
https://www.billsherlock.app/api/v1/openapi - Set Authentication to None.
- In Instructions, tell the GPT to extract service codes, charges, and context from user messages, then call
investigateBill. Present findings with confidence scores and recommendations. Always include the link to the full audit.
Claude tool_use
Define a tool that calls POST /api/v1/investigate with the request schema above. The OpenAPI spec at /api/v1/openapi provides the full schema for programmatic consumption.
LangChain / LlamaIndex
Use the OpenAPI spec URL with your framework's OpenAPI tool loader (e.g., LangChain's OpenAPIToolkit). The spec includes full request/response schemas and the investigateBill operation ID.
OpenAPI Specification
The machine-readable OpenAPI 3.0 spec is available at:
https://www.billsherlock.app/api/v1/openapiDisclaimers
- Results are informational only and do not constitute medical, legal, or financial advice.
- Medicare benchmarks are approximate and vary by locality, setting, modifiers, and date of service.
- Findings are based on user-provided structured line items, not a reviewed document.
- Potential savings are estimates and are not guaranteed.
- Agents should always present the
limitationsarray from the response to users alongside findings.