Skip to main content

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:

ScopePermissionDefault
contract_lookupRead contract rates
claim_pricingSubmit claims and get pricing
fund_releaseAuthorize settlements
ledger_accessView 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"
warning

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
info

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:

TierRequests/MinuteConcurrent
SandboxUnlimited10
Staging20020
Production (Default)10010
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
}
tip

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

Next Steps