TPA Integration Guide
End-to-end guide for Third-Party Administrators (TPAs/Trading Partners) to integrate with the Turquoise Direct Contract platform.
Overview: TPAs as Trading Partners
In the Turquoise ecosystem, a TPA (Third-Party Administrator) is a "Trading Partner" that facilitates contract lookups and claims processing between plans and providers. Your role:
- Contract Verification: Look up guaranteed rates before service delivery
- Claims Processing: Submit FHIR claims and manage adjudication
- Settlement Management: Authorize fund releases and reconcile payments
- Reporting: Monitor ROI and contract utilization
"Trading Partner" is the internal term for any organization processing claims through Turquoise APIs. This includes TPAs, TPAs-lite, and third-party platforms.
Architecture Overview
Two-Stage Contract Verification
Turquoise uses a two-stage verification process to ensure contract accuracy and speed:
Stage 1: Blind Lookup (< 200ms)
Request contract rates without member-specific information:
curl -X POST \
https://api.turquoise.health/tpa-api/v1/contracts/lookup \
-H "X-API-Key: $TURQUOISE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider_npi": "1234567890",
"plan_id": "SHARP-HMO-2024",
"service_code": "43235",
"lookup_type": "blind"
}'
Response (service fee not charged):
{
"contract_id": "DIR-2024-001",
"lookup_type": "blind",
"service_code": "43235",
"negotiated_rate": 1200.00,
"member_responsibility": 100.00,
"plan_pays": 1100.00,
"valid_for": 3600,
"expires_at": "2024-03-10T12:00:00Z",
"status": "available"
}
Use blind lookups at the front desk to provide immediate pricing guarantees. No member authentication required.
Stage 2: Full Lookup (with Member)
Verify member eligibility and deductible status:
curl -X POST \
https://api.turquoise.health/tpa-api/v1/contracts/lookup \
-H "X-API-Key: $TURQUOISE_API_KEY" \
-d '{
"provider_npi": "1234567890",
"plan_id": "SHARP-HMO-2024",
"service_code": "43235",
"member_id": "SHP00123456",
"lookup_type": "full"
}'
Response (includes member-specific details):
{
"contract_id": "DIR-2024-001",
"lookup_type": "full",
"service_code": "43235",
"negotiated_rate": 1200.00,
"deductible_remaining": 500.00,
"member_responsibility": 100.00,
"plan_pays": 1100.00,
"member_status": "active",
"effective_date": "2024-01-01",
"term_date": "2024-12-31",
"valid_for": 3600
}
Claims Processing Flow
Step 1: Prepare FHIR Claim
Structure your claim using Fast FHIR:
{
"resourceType": "Claim",
"id": "CLM-2024-001",
"status": "active",
"type": { "coding": [{ "code": "institutional" }] },
"use": "claim",
"patient": { "identifier": { "value": "SHP00123456" } },
"provider": { "identifier": { "value": "1234567890" } },
"insurer": { "identifier": { "value": "SHARP-HMO-2024" } },
"created": "2024-03-10T10:00:00Z",
"servicedDate": "2024-03-10",
"item": [{
"sequence": 1,
"productOrService": { "coding": [{ "code": "43235" }] },
"servicedDate": "2024-03-10",
"unitPrice": { "value": 1200.00, "currency": "USD" },
"net": { "value": 1200.00, "currency": "USD" }
}]
}
Step 2: Submit Claim
curl -X POST \
https://api.turquoise.health/tpa-api/v1/claims/submit \
-H "X-API-Key: $TURQUOISE_API_KEY" \
-H "Content-Type: application/fhir+json" \
-d @claim.json
Response (202 Accepted):
{
"resourceType": "Bundle",
"type": "transaction-response",
"entry": [{
"response": {
"status": "202 Accepted",
"location": "ClaimResponse/CLMR-2024-001"
}
}]
}
Step 3: Poll for Adjudication
Claims are adjudicated asynchronously. Poll for results:
curl -X GET \
https://api.turquoise.health/tpa-api/v1/claims/CLM-2024-001/response \
-H "X-API-Key: $TURQUOISE_API_KEY"
Response:
{
"resourceType": "ClaimResponse",
"id": "CLMR-2024-001",
"status": "active",
"outcome": "complete",
"adjudication": [{
"category": { "coding": [{ "code": "allowedamount" }] },
"amount": { "value": 1200.00, "currency": "USD" }
}],
"extension": [{
"url": "https://turquoise.health/stripe-trace-id",
"valueString": "trace_0324_abc123xyz"
}]
}
Step 4: Authorize Settlement
Once adjudicated, authorize the fund release:
curl -X POST \
https://api.turquoise.health/tpa-api/v1/settlements/authorize \
-H "X-API-Key: $TURQUOISE_API_KEY" \
-d '{
"claim_response_id": "CLMR-2024-001",
"authorization_code": "AUTH-20240310",
"approver": "john.smith@tpa.com"
}'
Response:
{
"settlement_id": "SETTLE-2024-001",
"status": "pending",
"claim_response_id": "CLMR-2024-001",
"authorized_at": "2024-03-10T10:15:00Z",
"expected_arrival": "2024-03-12T09:00:00Z"
}
Once authorized, settlements cannot be reversed. Ensure claim adjudication is verified before authorization.
Step 5: Monitor Settlement
Listen for settlement completion webhook:
# You'll receive this webhook:
POST /webhooks/settlements
{
"event": "settlement.completed",
"settlement_id": "SETTLE-2024-001",
"claim_response_id": "CLMR-2024-001",
"stripe_trace_id": "trace_0324_abc123xyz",
"provider_npi": "1234567890",
"amount": 1100.00,
"arrived_at": "2024-03-12T09:00:00Z"
}
Crawl-Walk-Run: Batch to Real-Time Transition
Turquoise supports a phased integration approach:
Phase 1: Crawl (Batch Processing - Weeks 1-4)
Submit daily batch files via SFTP or API:
# Daily batch submission
curl -X POST \
https://api.turquoise.health/tpa-api/v1/claims/batch-submit \
-H "X-API-Key: $TURQUOISE_API_KEY" \
-H "Content-Type: application/fhir+json" \
-d @daily-claims.ndjson
Phase 2: Walk (Mixed Processing - Weeks 5-8)
Hybrid approach: batch for high-volume, real-time for urgent cases:
# Continue batch submissions
curl -X POST https://api.turquoise.health/tpa-api/v1/claims/batch-submit ...
# Add real-time for critical procedures
curl -X POST https://api.turquoise.health/tpa-api/v1/claims/submit \
-H "Priority: high" ...
Phase 3: Run (Real-Time Processing - Week 9+)
Full real-time integration with guaranteed sub-200ms contract lookups:
# All claims submitted in real-time
curl -X POST \
https://api.turquoise.health/tpa-api/v1/claims/submit \
-H "X-API-Key: $TURQUOISE_API_KEY" \
--data @claim.json
Security Handshake Setup
Option 1: VPN-Based
Establish a dedicated VPN tunnel for API requests:
# Configure VPN
export TURQUOISE_VPN_ENDPOINT="vpn.turquoise.health"
export TURQUOISE_VPN_CERT="./vpn-client.crt"
# Traffic flows through VPN only
# No requirement for TLS 1.3 on public internet
Option 2: mTLS-Based (Recommended)
Use mutual TLS with client certificates:
# Install certificates
cp client.crt /etc/turquoise/certs/
cp client.key /etc/turquoise/certs/
chmod 600 /etc/turquoise/certs/client.key
# All requests use mTLS
curl -X GET \
https://api.turquoise.health/tpa-api/v1/health \
--cert /etc/turquoise/certs/client.crt \
--key /etc/turquoise/certs/client.key
mTLS is required for production. VPN is optional for additional security layers.
Error Handling & Retry Strategy
Idempotency Keys
All claim submissions should include an idempotency key:
curl -X POST \
https://api.turquoise.health/tpa-api/v1/claims/submit \
-H "Idempotency-Key: CLM-20240310-001" \
-H "X-API-Key: $TURQUOISE_API_KEY" \
-d @claim.json
This ensures duplicate submissions don't create duplicate claims.
Retry Logic
Implement exponential backoff for transient errors:
import time
def submit_claim_with_retry(claim, max_retries=3):
for attempt in range(max_retries):
try:
response = turquoise_client.claims.submit(claim)
return response
except TurquoiseError as e:
if e.status_code in [408, 429, 500, 502, 503, 504]:
wait_time = 2 ** attempt + random.uniform(0, 1)
time.sleep(wait_time)
else:
raise
raise Exception("Max retries exceeded")
Common Error Codes
| Code | Meaning | Action |
|---|---|---|
| 400 | Invalid claim format | Fix claim structure, retry once |
| 401 | Unauthorized | Check API key, refresh OAuth token |
| 429 | Rate limited | Wait and retry with backoff |
| 500 | Server error | Retry with exponential backoff |
| 503 | Service unavailable | Retry after checking status page |
Monitoring & Observability
Key Metrics to Track
{
"metrics": {
"daily_claims_submitted": 1250,
"claims_adjudicated_percent": 98.5,
"average_adjudication_time_ms": 1200,
"settlement_success_rate_percent": 99.8,
"average_settlement_delay_hours": 48,
"contract_lookup_success_rate_percent": 100.0,
"api_error_rate_percent": 0.2
}
}
Logging Example
{
"timestamp": "2024-03-10T10:30:00Z",
"claim_id": "CLM-2024-001",
"action": "submit",
"status": "success",
"response_time_ms": 145,
"stripe_trace_id": "trace_0324_abc123xyz"
}
Next Steps
- Mock Pricing Pilot - Test ROI before full deployment
- Hospital RCM Integration - For provider-side setup
- FHIR Claim Schema - Full field reference
- Webhook Documentation - Real-time event handling