> For the complete documentation index, see [llms.txt](https://docs.bloodgpt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bloodgpt.com/integration-guides/troubleshooting.md).

# Troubleshooting

Common issues and solutions when integrating BloodGPT.

Solutions to common issues encountered during integration and operation.

## API Issues

### 401 Unauthorized

**Error:**

```json
{"error": "invalid_api_key", "message": "The provided API key is invalid or expired"}
```

**Solutions:**

* Verify API key is correct (no extra spaces)
* Check `Authorization: Bearer YOUR_KEY` format
* Ensure using correct key for environment (sandbox vs production)
* Contact support if key was recently issued

### 413 Payload Too Large

**Error:**

```json
{"error": "file_too_large", "message": "File size exceeds 40MB limit"}
```

**Solutions:**

* Reduce file size (compress images, optimize PDF)
* Maximum file size is 40MB
* For large batches, split into multiple requests

### 422 Unprocessable Entity

**Error:**

```json
{"error": "invalid_request_body", "message": "The provided JSON or form data is invalid"}
```

**Solutions:**

* Validate JSON syntax
* Check required fields are present:
  * `patient_id`
  * `external_id`
  * `payload.parameters`
* Ensure correct data types (numbers vs strings)

### 429 Too Many Requests

**Error:**

```json
{"error": "rate_limit_exceeded", "message": "Too many requests"}
```

**Solutions:**

* Implement exponential backoff
* Use batch API for multiple tests
* Contact support for higher rate limits

## Webhook Issues

### Webhook Not Receiving Events

**Checklist:**

1. ✅ Webhook URL is publicly accessible
2. ✅ HTTPS endpoint (HTTP not supported)
3. ✅ Returns 200 status within 30 seconds
4. ✅ Firewall allows incoming requests
5. ✅ URL correctly specified in API request

**Test your endpoint:**

```bash
curl -X POST https://your-server.com/webhook \
  -H "Content-Type: application/json" \
  -d '{"test": true}'
```

### Webhook Signature Validation Failing

Verify signature using the shared secret:

```python
import hmac
import hashlib

def verify_signature(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
```

### Duplicate Webhook Events

Webhooks may be retried if your endpoint doesn't return 200. Handle duplicates:

```python
processed_events = set()

def handle_webhook(event):
    event_id = event.get("event_id")
    if event_id in processed_events:
        return {"status": "already_processed"}

    processed_events.add(event_id)
    # Process event...
```

## Patient Portal Issues

### Patient Not Receiving Magic Link Email

**Checklist:**

1. ✅ Patient email is correct in registration
2. ✅ `patient_id` in API request matches registered External ID
3. ✅ Check spam/junk folder
4. ✅ Email domain not blocking emails

**Debug steps:**

1. Verify patient exists: Check dashboard → Portal → Patients
2. Verify ID match: Compare `patient_id` in request with registered External ID
3. Check logs: View email delivery status in dashboard

### Branding Not Appearing

**Solutions:**

* Clear browser cache
* Wait 5-10 minutes for CDN propagation
* Verify settings were saved successfully
* Check logo file meets requirements (PNG/SVG, <500KB)

### Magic Link Expired

Links expire after 15 minutes. Patient can:

1. Go to portal login page
2. Enter email address
3. Receive new magic link

## HL7 Issues

### HL7 Message Rejected

**Common causes:**

* Missing required segments (MSH, PID, OBR, OBX)
* Invalid date format (should be YYYYMMDD or YYYYMMDDHHMMSS)
* Missing patient ID in PID segment

**Validate your message:**

```
MSH|^~\&|SENDING|FACILITY|BLOODGPT|API|20250115100000||ORU^R01|MSG001|P|2.5
PID|1||PAT-001||Doe^John||19850325|M
OBR|1|TEST-001||CBC^Complete Blood Count
OBX|1|NM|2345-7^Glucose^LN||95|mg/dL|70-100|N|||F
```

See [HL7 Format documentation](/submitting-tests/hl7.md) for full specification.

### OBX Segment Not Recognized

Ensure OBX segments include:

* **OBX-3:** Test identifier (LOINC code recommended)
* **OBX-5:** Numeric value
* **OBX-6:** Units
* **OBX-7:** Reference range

## Polling Issues

### Report Never Ready (Continuous 404)

**Possible causes:**

* Processing taking longer than expected
* Error during processing

**Solutions:**

1. Wait up to 5 minutes for complex reports
2. Check for webhook notification (if configured)
3. Contact support with `test_id` from response

### Download URL Expired (403 Forbidden)

Pre-signed URLs expire after 24 hours. Solutions:

* Download report promptly after notification
* Re-submit request to get new URL
* Use webhook to trigger immediate download

## Performance Issues

### Slow Response Times

**For single requests:**

* Normal processing: 30-60 seconds
* Complex reports: up to 2 minutes

**For batch requests:**

* Use batch API instead of sequential calls
* Implement async processing with webhooks

### High Latency in Production

**Checklist:**

* Using production URL (`sandbox.bloodgpt.com`)?
* Network path to API optimal?
* Consider webhook-based flow instead of polling

## Getting Help

### Before Contacting Support

Gather this information:

* **Test ID:** From API response (`test_id`)
* **External ID:** Your reference ID
* **Timestamp:** When issue occurred
* **Error message:** Full error response
* **Request payload:** Sanitized (remove PHI)

### Contact Support

Email: <contact@bloodgpt.com>

Include:

* Your organization name
* Integration type (PDF-Only, Portal, Full API)
* Information gathered above
* Steps to reproduce issue

### Response Times

| Priority     | Description         | Response   |
| ------------ | ------------------- | ---------- |
| **Critical** | Production down     | < 4 hours  |
| **High**     | Feature broken      | < 24 hours |
| **Normal**   | Questions, guidance | < 48 hours |

{% hint style="info" %}
**Pro tip:** Most issues are resolved by verifying API key, checking `patient_id` matches, and ensuring webhook endpoint returns 200.
{% endhint %}
