Authentication
Turquoise uses industry-standard API key and OAuth 2.0 authentication with mTLS for production environments.
API Key Authentication (Sandbox & Staging)
Basic Usage
Pass your API key via the X-API-Key header on every request:
curl -X POST \
https://sandbox.api.turquoise.health/tpa-api/v1/contracts/lookup \
-H "X-API-Key: sk_sand_abc123xyz..." \
-H "Content-Type: application/json" \
-d '{...}'
Key Format
- Sandbox:
sk_sand_*(64 characters) - Staging:
sk_stage_*(64 characters) - Production: Not supported (use OAuth 2.0)
Key Management
Scopes
API keys can be restricted to specific scopes for least-privilege access:
| Scope | Permission | Default |
|---|---|---|
contract_lookup | Read contract rates | ✓ |
claim_pricing | Submit claims and get pricing | ✓ |
fund_release | Authorize settlements | ✗ |
ledger_access | View settlement records | ✗ |
Rotation
Rotate API keys every 90 days:
# List active keys
curl -X GET \
https://sandbox.api.turquoise.health/tpa-api/v1/keys \
-H "X-API-Key: $TURQUOISE_API_KEY"
# Rotate key (old key remains valid for 24 hours)
curl -X POST \
https://sandbox.api.turquoise.health/tpa-api/v1/keys/rotate \
-H "X-API-Key: $TURQUOISE_API_KEY"
Keep both the old and new key during the 24-hour grace period to avoid service interruption.
OAuth 2.0 with mTLS (Production)
Overview
Production deployments use OAuth 2.0 with mutual TLS (mTLS) for enhanced security:
Client (TPA) ←→ (mTLS) ←→ Turquoise Auth Server ←→ Resource Server
Setup Steps
1. Request mTLS Certificate
Contact support@turquoise.health with:
- Organization name
- Technical contact email
- Intended use (TPA, Provider, Plan Sponsor)
2. Install Certificate
You'll receive:
client.crt(client certificate)client.key(private key)ca.crt(Turquoise CA certificate)
# Verify certificate
openssl x509 -in client.crt -text -noout
# Ensure correct permissions
chmod 600 client.key
3. Get Access Token
curl -X POST \
https://auth.turquoise.health/oauth2/token \
--cert client.crt \
--key client.key \
--cacert ca.crt \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "your-client-id",
"scopes": ["contract_lookup", "claim_pricing", "fund_release"]
}'
4. Use Access Token
curl -X POST \
https://api.turquoise.health/tpa-api/v1/contracts/lookup \
--cert client.crt \
--key client.key \
--cacert ca.crt \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{...}'
Token Management
- Validity: 1 hour
- Refresh: Obtain new token before expiry
- Revocation: Tokens revoked if client certificate rotates
Access tokens are opaque and should not be decoded by clients. Treat them as strings.
Rate Limiting
Requests are rate-limited to protect service quality:
| Tier | Requests/Minute | Concurrent |
|---|---|---|
| Sandbox | Unlimited | 10 |
| Staging | 200 | 20 |
| Production (Default) | 100 | 10 |
| Production (Enterprise) | 500+ | Custom |
Rate Limit Headers
Every response includes rate limit information:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1710000060
When limit exceeded, receive 429 Too Many Requests:
{
"error": "rate_limit_exceeded",
"message": "You have exceeded 100 requests per minute",
"retry_after": 45
}
Security Best Practices
Encryption
- In Transit: TLS 1.3+ required (TLS 1.2 only for legacy systems)
- At Rest: AES-256 encryption for sensitive data
- Hashing: SHA-256 for audit trails
API Key Storage
# Bad: Don't hardcode keys
api_key = "sk_sand_abc123xyz..."
# Good: Use environment variables
export TURQUOISE_API_KEY="..."
api_key = os.getenv('TURQUOISE_API_KEY')
# Better: Use secrets manager
# AWS Secrets Manager, Azure Key Vault, etc.
Monitoring
Log all API calls for audit purposes (without storing keys):
{
"timestamp": "2024-03-10T10:30:00Z",
"method": "POST",
"endpoint": "/contracts/lookup",
"client_id": "org-123",
"status": 200,
"response_time_ms": 145,
"key_id": "kid_abc123"
}
Error Responses
401 Unauthorized
{
"error": "invalid_api_key",
"message": "API key is invalid or expired",
"documentation": "https://docs.turquoise.health/auth#401"
}
403 Forbidden
{
"error": "insufficient_scope",
"message": "API key lacks 'fund_release' scope",
"required_scope": "fund_release",
"current_scopes": ["contract_lookup", "claim_pricing"]
}
429 Too Many Requests
{
"error": "rate_limit_exceeded",
"message": "You have exceeded 100 requests per minute",
"retry_after": 45
}
Check the retry_after header before making retry attempts. Use exponential backoff with jitter.
Testing Authentication
Sandbox Health Check
curl -X GET \
https://sandbox.api.turquoise.health/tpa-api/v1/health \
-H "X-API-Key: $TURQUOISE_API_KEY" \
-v
Production Certificate Validation
# Verify mTLS setup
openssl s_client -connect api.turquoise.health:443 \
-cert client.crt -key client.key -cacert ca.crt