| Code | Meaning | When It Occurs | Action |
| 200 | OK | Request succeeded, data returned | No action needed |
| 201 | Created | Resource created successfully (appeal, cluster, etc.) | Check Location header for new resource URL |
| 400 | Bad Request | Invalid input (missing field, wrong type, malformed JSON) | Review request body structure; ensure all required fields present |
| 401 | Unauthorized | Missing or invalid X-User-Id header | Add valid X-User-Id header to request |
| 402 | Payment Required | Insufficient credits for marketplace query | Allocate more credits or query smaller clusters |
| 403 | Forbidden | User role insufficient (not admin when required) | Use non-destructive endpoints; request admin to perform operation |
| 404 | Not Found | Resource doesn't exist or is soft-deleted (archived) | Verify resource ID; check if resource was archived |
| 422 | Unprocessable Entity | PHI validation failed; PII detected in request | Remove protected identifiers (SSN, phone, email, names) |
| 500 | Internal Server Error | Server bug, unexpected error | Include X-Request-ID in bug report; check server logs |
| 503 | Service Unavailable | Database connection failed, service degraded | Check database connectivity; retry after 30 seconds |
Common Errors and Solutions
Error: 400 Bad Request — "Missing required field: narrative_content"
Cause:
Appeal creation request missing narrative_content field.
Solution:
Check request body structure
Ensure all required fields are present: denial_type, narrative_content, precedent_ids (optional)
Verify JSON is valid (no trailing commas, proper quotes)
Example (broken):
POST /api/appeals
{
"denial_type": "FREQ_LIMIT"
}
Example (fixed):
POST /api/appeals
{
"denial_type": "FREQ_LIMIT",
"narrative_content": "Patient requires more intensive outpatient services to address treatment goals..."
}
Prevention:
Always use endpoint examples from API reference as template; validate JSON before sending.
Error: 401 Unauthorized — "Missing X-User-Id header"
Cause:
Request missing required X-User-Id header (or header invalid).
Solution:
Add X-User-Id header to every request (except public /api/registries endpoints)
Verify user ID format (should be UUID)
Verify user ID is active (not archived)
Example (broken):
curl https://api.stratumcollective.co/api/appeals
Example (fixed):
curl -H "X-User-Id: 3fc26b33-be13-4306-877a-c3b765cabe1d" \
https://api.stratumcollective.co/api/appeals
Prevention:
Check Network tab in browser DevTools (inspect request headers) to verify X-User-Id is present on every request.
Error: 402 Payment Required — "Insufficient credits. Balance: 5, Cost: 8, Shortfall: 3"
Cause:
Attempting to query marketplace clusters but user doesn't have enough credits. Credit cost is calculated as: 1 + (precedent_count / 10 × 0.5).
Solution:
Check credit balance with GET /api/marketplace/profiles/:payer (returns credit_cost in response)
Allocate more credits (monthly allocation = 100)
Query smaller clusters (fewer precedents = lower cost)
Request admin to top up credits
Example cost table:
- 20-precedent cluster: 2 credits
- 50-precedent cluster: 4 credits
- 100-precedent cluster: 6 credits
- 200-precedent cluster: 11 credits
Prevention:
Always call /api/marketplace/profiles/:payer first to see credit cost before querying; alert user if balance too low.
Error: 403 Forbidden — "User role insufficient. Required: admin, Actual: user"
Cause:
Attempting destructive operation (DELETE, PUT, set Medicaid rules) as non-admin user.
Solution:
- Verify user role (check X-User-Id in request)
- Only admin users can: DELETE appeals, modify Medicaid rules, access
/api/admin/ endpoints
- Non-admin users can: GET, POST (create), read marketplace data
- Request admin user to perform operation
Prevention:
Check user role before attempting destructive operations; use GET endpoints for non-admin users.
Error: 404 Not Found — "Appeal id=abc-123 not found"
Cause:
Appeal was soft-deleted (archived) or doesn't exist; or URL path is incorrect.
Solution:
- Verify appeal ID is correct (check URL path, no typos)
- List all appeals with
GET /api/appeals to find correct ID
- Check if appeal was archived:
GET /api/appeals?include_archived=true
- Verify appeal belongs to your tenant (tenant isolation check)
Prevention:
Always list resources first to get correct IDs; verify resource exists before trying to read/update it.
Error: 422 Unprocessable Entity — "PHI validation failed. Detected: [SSN, Phone Number]"
Cause:
Request body contains protected health information (PII/PHI) that violates HIPAA compliance rules.
Detected identifiers:
- Social Security Number (SSN, format:
###-##-####)
- Phone number (10+ digits)
- Email address
- Patient full name
- Medical record number
- Date of birth (exact dates only; ranges are OK)
- Insurance ID number
- Credit/debit card number
Solution:
- Remove detected PII from
narrative_content and all other fields
- Use deidentified data: patient initials instead of names, date ranges instead of exact DOB
- Use generic descriptors: "patient" instead of name, "juvenile" instead of age
Example (broken):
{
"narrative_content": "Patient John Smith (DOB 1985-06-15, SSN 123-45-6789, Phone 555-123-4567) needs increased level of care..."
}
Example (fixed):
{
"narrative_content": "Patient J.S. (age 30s, insured) requires increased frequency of intensive outpatient services..."
}
Prevention:
Use deidentified data only in all API requests; ask data team to strip PII before sending to API. Reference: 45 CFR §164.514 safe harbor method for deidentification.
Error: 500 Internal Server Error — "Unexpected error: Cannot read property 'tenant_id' of undefined"
Cause:
Server-side bug, likely introduced in recent deploy or caused by unexpected input state.
Solution:
Include X-Request-ID header from response in bug report (traces request through server logs)
Check server logs: grep "X-Request-Id: abc123" logs/api.log
Try request again (may be transient)
Contact engineering with request ID and reproduction steps
Prevention:
Monitor error rate dashboard; alert if 5xx errors spike after deploy. Perform smoke tests after each deployment.
Error: 503 Service Unavailable — "Database connection failed"
Cause:
Database is unreachable, overloaded, or in maintenance mode.
Solution:
Check database connectivity: psql -U stratum -h localhost -d stratum_platform -c "SELECT 1"
Check if database is in maintenance window (Monday 2–3am UTC)
Retry request after 30 seconds
Check infrastructure status page
Prevention:
Implement exponential backoff in client (retry after 1s, 2s, 4s with jitter); don't retry immediately.
Debugging Strategies
Strategy 1: Check Request Format
Checklist:
[ ] HTTP method — Are you using GET (read), POST (create), PUT (update), DELETE (delete)?
[ ] URL path — Is path spelled correctly? Check for typos in endpoint name.
[ ] Base URL — Are you hitting https://api.stratumcollective.co (not localhost or staging)?
[ ] Required headers — Does request include X-User-Id, Content-Type: application/json?
[ ] Request body — Is body valid JSON? Do all required fields exist? Correct types (string vs number)?
[ ] Query parameters — If using GET, are query params properly URL-encoded?
Test independently with curl:
curl -X POST https://api.stratumcollective.co/api/appeals \
-H "X-User-Id: 3fc26b33-be13-4306-877a-c3b765cabe1d" \
-H "Content-Type: application/json" \
-d '{
"denial_type": "FREQ_LIMIT",
"narrative_content": "Patient requires more intensive outpatient services...",
"precedent_ids": ["abc-123"]
}'
Strategy 2: Check Response Details
Checklist:
[ ] Status code — What is HTTP status? (200, 400, 401, 402, 403, 404, 422, 500, 503?)
[ ] Response body — Read error message carefully; it usually explains what's wrong
[ ] Response headers — Look for X-Request-ID (for server logs), Cache-Control, Content-Type
[ ] Response size — Is response huge (might be memory leak)? Should be <10MB for normal requests.
How to inspect response in browser:
Open DevTools (F12 or Cmd+Option+I)
Go to Network tab
Click on API request
View Response tab (shows response body)
View Headers tab (shows status code and response headers)
How to inspect with curl:
# Show all headers + response body
curl -i https://api.stratumcollective.co/api/appeals \
-H "X-User-Id: 3fc26b33-be13-4306-877a-c3b765cabe1d"
Show only headers (useful for debugging redirects)
curl -I https://api.stratumcollective.co/api/appeals
Strategy 3: Check Server Logs
How to access logs:
# View real-time API logs (tail last 100 lines)
tail -f /var/log/stratum-platform/api.log
Search logs for specific request by ID
grep "X-Request-Id: abc-123" /var/log/stratum-platform/api.log
Show last 10 errors
grep ERROR /var/log/stratum-platform/api.log | tail -10
Parse JSON logs and pretty-print
tail -f /var/log/stratum-platform/api.log | jq .
What to look for:
Error message (should explain what went wrong)
Stack trace (if 500 error, shows which line of code failed)
Database query that failed (if database error)
User ID / request context (verify right user)
Strategy 4: Check Database State
Connect to database:
psql -U stratum -h localhost -d stratum_platform
Useful queries:
-- Check if record exists
SELECT id, tenant_id, created_at, deleted_at
FROM appeals
WHERE id = 'abc-123';
-- Check tenant isolation (verify you can access this record)
SELECT id, tenant_id, created_at
FROM appeals
WHERE id = 'abc-123' AND tenant_id = 'your-tenant-id';
-- Check for soft-deleted records (deleted_at != null means archived)
SELECT id, created_at, deleted_at
FROM appeals
WHERE id = 'abc-123' AND deleted_at IS NOT NULL;
-- Check audit trail (see all changes to record)
SELECT action, created_at, changes
FROM audit_log
WHERE appeal_id = 'abc-123'
ORDER BY created_at DESC;
-- Check for database connection issues
SELECT 1;
Performance Debugging
Slow API Response (>1 second)
Checklist:
[ ] Query performance — Is database query slow?
EXPLAIN ANALYZE SELECT FROM appeals WHERE tenant_id = 'xyz';
Look for Seq Scan (bad, full table scan). Should use index instead.
[ ] Missing indexes — Add indexes on frequently filtered fields:
CREATE INDEX idx_appeals_tenant_id ON appeals(tenant_id);
CREATE INDEX idx_appeals_created_at ON appeals(created_at DESC);
[ ] N+1 queries — Is code looping and making separate database call for each item?
Use batch queries or JOIN instead:
-- Bad: loops 100 times
SELECT FROM appeals WHERE id = 'abc-1';
SELECT FROM appeals WHERE id = 'abc-2';
...
-- Good: single query
SELECT FROM appeals WHERE id IN ('abc-1', 'abc-2', ...);
[ ] Large result sets — Is API returning 10,000+ rows? Implement pagination:
GET /api/appeals?limit=100&offset=0
[ ] Database connection pool — Are idle connections exhausted?
SELECT datname, count()
FROM pg_stat_activity
GROUP BY datname;
High Memory Usage
Checklist:
[ ] Response size — Is API returning huge JSON?
Check Content-Length header in response (should be <10MB)
[ ] Memory leak — Monitor memory usage over time:
# Monitor memory every 5 seconds
watch -n 5 'ps aux | grep node'
Memory should be stable; if growing, possible leak.
[ ] Unbounded queries — Are queries missing LIMIT?
-- Bad: might return 100,000 rows
SELECT FROM precedents WHERE payer_id = 'cigna';
-- Good: return only 100 rows
SELECT FROM precedents WHERE payer_id = 'cigna' LIMIT 100;
High CPU Usage
Checklist:
[ ] Expensive computations — Are you running expensive operations?
Credit calculation (avoid in hot loop)
Deidentification / PII validation (regex heavy)
Large JSONB queries
[ ] Query complexity — Avoid complex JSONB queries on large tables:
-- Slow: scans all rows, checks JSONB column
SELECT FROM appeals WHERE metadata -> 'key' = 'value';
-- Better: use index or filter by other columns first
SELECT FROM appeals WHERE tenant_id = 'xyz' AND metadata -> 'key' = 'value';
[ ] Rate limiting — Too many concurrent requests?
Implement rate limiter: max 100 requests/user/minute.
Common Debugging Commands
Test Endpoints
# Test if API is responding
curl https://api.stratumcollective.co/health
Get all appeals (requires X-User-Id header)
curl -H "X-User-Id: your-user-id" \
https://api.stratumcollective.co/api/appeals
Create appeal
curl -X POST https://api.stratumcollective.co/api/appeals \
-H "X-User-Id: your-user-id" \
-H "Content-Type: application/json" \
-d '{"denial_type":"FREQ_LIMIT","narrative_content":"..."}'
Check Database
# Test database connection
psql -U stratum -h localhost -d stratum_platform -c "SELECT 1"
Show slow queries (queries taking >1 second)
tail -f /var/log/postgresql/slow.log
Show database size
psql -U stratum -h localhost -d stratum_platform \
-c "SELECT pg_size_pretty(pg_database_size('stratum_platform'))"
Monitor Logs
# Watch API errors in real-time
tail -f /var/log/stratum-platform/api.log | grep ERROR
Count errors by type
grep ERROR /var/log/stratum-platform/api.log | cut -d: -f2 | sort |
uniq -c