Error Code Reference¶
All Curaway API errors follow the naming convention {DOMAIN}_{CATEGORY}_{SEQUENCE} where:
- DOMAIN -- The system area (e.g.,
AUTH,INTAKE,FHIR) - CATEGORY -- The error type (e.g.,
TOKEN,VALIDATION,NOT_FOUND) - SEQUENCE -- A three-digit number (e.g.,
001,002)
Errors are returned inside the standard response envelope errors array.
AUTH -- Authentication & Authorization¶
Errors related to JWT validation, token lifecycle, and permission checks.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
AUTH_TOKEN_EXPIRED_001 |
401 | JWT token has expired | User session timed out | Re-authenticate via Clerk to obtain a fresh token |
AUTH_TOKEN_INVALID_001 |
401 | JWT signature verification failed | Tampered or malformed token | Ensure the token was issued by Clerk and has not been modified |
AUTH_UNAUTHORIZED_001 |
403 | User lacks permission for this action | Role does not have required scope | Check the user's role assignment in Clerk dashboard |
AUTH_HEADER_MISSING_001 |
401 | Authorization header not provided | Client did not send Bearer token | Add Authorization: Bearer <token> header to the request |
TENANT -- Tenant Management¶
Errors related to multi-tenant isolation and tenant configuration.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
TENANT_NOT_FOUND_001 |
404 | Tenant ID does not exist | Typo in X-Tenant-ID header |
Verify the tenant ID against the tenant registry |
TENANT_HEADER_MISSING_001 |
400 | X-Tenant-ID header not provided |
Client omitted the required header | Add X-Tenant-ID header to all API requests |
TENANT_MISMATCH_001 |
403 | JWT tenant claim does not match X-Tenant-ID header |
Cross-tenant access attempt | Ensure the JWT was issued for the same tenant specified in the header |
INTAKE -- Patient Intake & Case Management¶
Errors during patient creation, case lifecycle, and intake form processing.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
INTAKE_VALIDATION_001 |
422 | One or more input fields failed validation | Missing required fields or invalid format | Check the field property in the error object for the specific field |
INTAKE_DUPLICATE_001 |
409 | A patient with matching identifiers already exists | Same email + date of birth combination | Use the existing patient record or call the merge endpoint |
INTAKE_CASE_NOT_FOUND_001 |
404 | The specified case ID does not exist | Stale reference or typo | Query /cases/ to list available cases for the patient |
INTAKE_CASE_CLOSED_001 |
400 | Cannot modify a case that has been closed | Attempting to update a finalized case | Create a new case if further action is needed |
FHIR -- Clinical Data (FHIR R4)¶
Errors when reading or writing FHIR-formatted clinical resources.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
FHIR_RESOURCE_INVALID_001 |
422 | FHIR resource failed R4 schema validation | Missing required fields or invalid coding system | Validate the resource against the FHIR R4 spec before submission |
FHIR_RESOURCE_NOT_FOUND_001 |
404 | The requested FHIR resource does not exist | Invalid resource ID or resource was deleted | Verify the resource ID and type |
FHIR_CODING_UNKNOWN_001 |
422 | Unrecognized coding system or code value | Typo in ICD-10, SNOMED CT, or LOINC code | Cross-reference the code against the relevant coding system registry |
MATCH -- Provider Matching¶
Errors from the AI-powered provider matching engine.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
MATCH_NO_RESULTS_001 |
404 | No providers matched the given criteria | Overly restrictive filters or unsupported procedure/country combination | Broaden search criteria or check that providers exist for the procedure |
MATCH_EMBEDDING_FAILED_001 |
500 | Failed to generate embedding for the search query | Embedding service (Qdrant/OpenAI) is unavailable | Retry after a brief delay; check embedding service health |
MATCH_GRAPH_QUERY_FAILED_001 |
500 | Neo4j graph traversal failed during matching | Neo4j connection timeout or corrupted graph data | Check Neo4j connectivity; re-seed graph if data is stale |
AGENT -- AI Agent & Chat¶
Errors from the conversational AI agent that guides patients through intake.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
AGENT_GUARDRAIL_INPUT_001 |
400 | Input was blocked by the guardrail classifier | User message contained prohibited content (PII solicitation, medical advice request) | Rephrase the message to stay within the agent's scope |
AGENT_GUARDRAIL_OUTPUT_001 |
500 | Agent response was blocked by output validator | LLM generated content matching a forbidden output pattern | Retry the request; if persistent, review guardrail rules |
AGENT_LLM_TIMEOUT_001 |
504 | LLM did not respond within the timeout window | High load on the LLM provider or network issues | Retry with exponential backoff; check LLM provider status |
AGENT_CONTEXT_OVERFLOW_001 |
400 | Conversation history exceeds the model's context window | Very long chat session without summarization | Start a new conversation or clear older messages |
PROVIDER -- Provider Management¶
Errors related to provider profiles and configuration.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
PROVIDER_NOT_FOUND_001 |
404 | The specified provider does not exist | Invalid provider ID | Query /providers/ to list available providers |
PROVIDER_INACTIVE_001 |
400 | Provider is currently inactive and cannot accept cases | Provider has been deactivated by admin | Contact the admin to reactivate the provider or choose a different one |
PROVIDER_CAPACITY_001 |
409 | Provider has reached their case capacity limit | Too many active cases assigned | Wait for existing cases to complete or select an alternative provider |
DOCTOR -- Doctor Profiles¶
Errors related to doctor records, search, and procedure associations.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
DOCTOR_NOT_FOUND_001 |
404 | The specified doctor does not exist | Invalid doctor ID or doctor was removed | Query /doctors/ to list available doctors |
DOCTOR_VALIDATION_001 |
422 | Doctor profile data failed validation | Missing required fields (name, specialty, license number) | Check the field property in the error for specifics |
DOCTOR_DUPLICATE_001 |
409 | A doctor with the same license number already exists | Attempting to create a duplicate record | Use the existing doctor record or update it |
DOCTOR_PROCEDURE_EXISTS_001 |
409 | This doctor is already associated with the specified procedure | Duplicate procedure association attempt | No action needed -- the association already exists |
PUBLIC -- Public Storefront¶
Errors from the public-facing provider storefront (unauthenticated).
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
PUBLIC_PROVIDER_NOT_FOUND_001 |
404 | Provider slug does not exist | Invalid or stale provider URL | Verify the provider slug against the provider directory |
PUBLIC_DOCTOR_NOT_FOUND_002 |
404 | Doctor slug does not exist | Invalid or stale doctor URL | Verify the doctor slug against the doctor directory |
PUBLIC_TREATMENT_NOT_FOUND_003 |
404 | Treatment slug does not exist | Invalid or stale treatment URL | Verify the treatment slug against available treatments |
PUBLIC_DESTINATION_NOT_FOUND_004 |
404 | Country slug does not exist | Invalid or stale country URL | Verify the country slug against available destinations |
PUBLIC_INVALID_FILTER_005 |
400 | Invalid filter parameter value | Unrecognized or malformed filter value | Check the API docs for valid filter values |
PUBLIC_INVALID_SORT_006 |
400 | Invalid sort_by parameter | Unrecognized sort field | Valid sort fields: name, rating, price |
PUBLIC_SEARCH_QUERY_TOO_SHORT_007 |
400 | Search query less than 2 characters | User submitted a single character | Provide a search query of at least 2 characters |
PUBLIC_SEARCH_QUERY_TOO_LONG_008 |
400 | Search query exceeds 200 characters | Extremely long search string | Shorten the search query to 200 characters or fewer |
PUBLIC_RATE_LIMIT_EXCEEDED_009 |
429 | 60 requests per minute per IP exceeded | Automated scraping or high-frequency polling | Wait for the rate limit window to reset (1 minute) |
PUBLIC_CACHE_ERROR_010 |
500 | Redis cache failure (non-fatal, falls through to DB) | Redis connectivity issue | No user action needed -- request will be served from DB |
PUBLIC_PAGINATION_INVALID_011 |
400 | page < 1 or per_page > 100 | Invalid pagination parameters | Use page >= 1 and per_page between 1 and 100 |
PUBLIC_SLUG_CONFLICT_012 |
409 | Duplicate slug detected | Slug already exists for another entity | Choose a different slug or modify the existing one |
CONSENT -- GDPR Consent Management¶
Errors related to consent capture, revocation, and audit trails.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
CONSENT_NOT_FOUND_001 |
404 | No consent record found for this patient/purpose | Consent was never captured or was fully revoked | Prompt the patient to provide consent |
CONSENT_ALREADY_REVOKED_001 |
409 | Consent has already been revoked | Duplicate revocation attempt | No action needed -- consent is already revoked |
CONSENT_REQUIRED_001 |
403 | This action requires patient consent that has not been granted | Attempting a data-sharing action without consent | Capture consent from the patient before proceeding |
GRAPH -- Knowledge Graph (Neo4j)¶
Errors from the Neo4j-backed knowledge graph used for provider relationships and procedure hierarchies.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
GRAPH_CONNECTION_001 |
503 | Cannot connect to Neo4j | Neo4j instance is down or URI is misconfigured | Verify NEO4J_URI environment variable and Neo4j service health |
GRAPH_QUERY_FAILED_001 |
500 | Cypher query execution failed | Malformed query or constraint violation | Check the Cypher query syntax and data integrity |
NOTIFY -- Notifications (Email, SMS)¶
Errors from the notification subsystem powered by Resend.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
NOTIFY_EMAIL_FAILED_001 |
500 | Failed to send email via Resend | Invalid recipient address or Resend API error | Verify the email address and Resend API key |
NOTIFY_TEMPLATE_NOT_FOUND_001 |
404 | Email template ID does not exist | Typo in template name or template was deleted | Check available templates in the notification config |
NOTIFY_RATE_LIMITED_001 |
429 | Too many notifications sent in the current window | Burst of notifications triggered by automation | Wait for the rate limit window to reset |
NOTIFY_RECIPIENT_INVALID_001 |
422 | Recipient address failed validation | Malformed email or phone number | Validate the recipient address format before sending |
VIDEO -- Video Consultation¶
Errors related to video consultation sessions.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
VIDEO_SESSION_NOT_FOUND_001 |
404 | The video session does not exist | Invalid session ID or session expired | Create a new video session |
VIDEO_SESSION_EXPIRED_001 |
410 | The video session has expired | Session exceeded its TTL | Create a new video session |
VIDEO_PROVIDER_ERROR_001 |
502 | Upstream video provider returned an error | Third-party video service outage | Retry after a delay; check provider status page |
VIDEO_PARTICIPANT_LIMIT_001 |
400 | Maximum number of participants reached | Exceeded the configured participant cap | Remove a participant or upgrade the session tier |
STORAGE -- File Storage (Cloudflare R2)¶
Errors related to file uploads, presigned URLs, and document processing.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
STORAGE_UPLOAD_FAILED_001 |
500 | File upload to Cloudflare R2 failed | R2 connectivity issue or bucket misconfiguration | Check CLOUDFLARE_R2_* environment variables and R2 service status |
STORAGE_PRESIGN_FAILED_001 |
500 | Failed to generate presigned upload URL | Invalid R2 credentials or expired signing key | Rotate R2 credentials and verify configuration |
STORAGE_FILE_TOO_LARGE_001 |
413 | File exceeds the maximum allowed size | Upload exceeds the 20 MB limit | Compress the file or split into smaller documents |
STORAGE_FILE_TYPE_001 |
422 | File type is not allowed | Uploaded file extension is not in the allow list | Allowed types: PDF, JPEG, PNG, DICOM. Convert the file to an accepted format |
SYS -- System & Infrastructure¶
General system-level errors not tied to a specific domain.
| Code | HTTP Status | Description | Common Cause | Resolution |
|---|---|---|---|---|
SYS_INTERNAL_001 |
500 | Unhandled internal server error | Uncaught exception in application code | Check server logs for the stack trace; report as a bug if persistent |
SYS_DATABASE_001 |
503 | PostgreSQL connection failed | Database is down or connection pool exhausted | Check DATABASE_URL configuration and database health |
SYS_RATE_LIMITED_001 |
429 | Global rate limit exceeded | Too many requests from this tenant | Wait for the rate limit window to reset; consider upgrading tier |
SYS_MAINTENANCE_001 |
503 | System is undergoing scheduled maintenance | Deployment or migration in progress | Retry after the maintenance window (check status page) |
SYS_TIMEOUT_001 |
504 | Request processing exceeded the timeout limit | Complex query or downstream service latency | Retry with a simpler request; if persistent, contact support |
Summary¶
| Domain | Code Count | Section |
|---|---|---|
| AUTH | 4 | Authentication |
| TENANT | 3 | Tenant |
| INTAKE | 4 | Intake |
| FHIR | 3 | FHIR |
| MATCH | 3 | Matching |
| AGENT | 4 | Agent |
| PROVIDER | 3 | Provider |
| DOCTOR | 4 | Doctor |
| PUBLIC | 12 | Public Storefront |
| CONSENT | 3 | Consent |
| GRAPH | 2 | Graph |
| NOTIFY | 4 | Notifications |
| VIDEO | 4 | Video |
| STORAGE | 4 | Storage |
| SYS | 5 | System |
| Total | 62 |