API Errors

Standard error envelope, HTTP status meanings, and stable public error codes.

Every non-2xx Platform API response returns the same envelope shape.

{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "API key invalid",
    "param": null,
    "doc_url": "https://docs.medblocks.com/errors/invalid_api_key",
    "request_id": "9c9b6f7a-8e4f-4a3b-9c1e-6f3a2d8b7c4d"
  }
}

Log error.code, error.message, the HTTP status, and error.request_id. Show patients a friendly retry message instead of raw portal or OAuth text.

Envelope Fields

FieldTypeDescription
error.typestringBroad category such as authentication_error, invalid_request_error, or ehr_error.
error.codestringStable machine-readable code. Use this for branching.
error.messagestringHuman-readable explanation for developers and logs.
error.paramstring or nullRequest field or parameter related to the error, when available.
error.doc_urlstringDocumentation URL for the specific code.
error.request_idstringCorrelation ID. Include it in support tickets.

HTTP Statuses

StatusMeaning
400Validation error, malformed request, or unsupported API version.
401Missing, invalid, or expired API key.
403API key is valid but does not have permission for the resource.
404Resource was not found in your organization.
409Resource conflict, such as a duplicate identifier.
413Request payload is too large.
429Rate limit or quota exceeded.
500Unexpected Medblocks server error. Retry with backoff.
502Upstream EHR, OAuth, email, token, or storage service failed.

Public Codes

TypeCodeTypical Cause
authentication_errornot_authenticatedThe request is not authenticated.
authentication_errorinvalid_credentialsLogin or credential verification failed.
authentication_errorsession_expiredA user session expired.
authentication_errormissing_api_keyAuthorization header is missing.
authentication_errorinvalid_api_keyAPI key is invalid.
authentication_errorexpired_api_keyAPI key is expired.
permission_errorforbiddenAuthenticated caller cannot access the operation.
permission_errororg_access_deniedCaller is not a member of the active organization.
permission_errorrole_insufficientUser role is not allowed to perform the operation.
permission_errorpatient_access_deniedPatient session is required or invalid.
permission_errorscope_violationResource is outside the active organization.
permission_errorinsufficient_scopeAPI key lacks the required scope.
invalid_request_errorbad_requestRequest is malformed or missing required fields.
invalid_request_errorinvalid_dataRequest data failed validation.
invalid_request_errorpayload_too_largeRequest body is too large.
invalid_request_errorinvalid_imageImage data or format is invalid.
invalid_request_errorunsupported_api_versionVersion header is not supported.
invalid_request_erroroauth_state_expiredOAuth state expired before callback completion.
not_found_errorresource_not_foundPatient, Session, or source was not found.
conflict_errorresource_conflictRequest conflicts with existing data.
conflict_erroralready_linkedResource is already linked to another entity.
conflict_errorexternal_id_already_existsExternal identifier already exists in the organization.
rate_limit_errorthrottledToo many requests.
rate_limit_errorquota_exceededAPI key quota is exceeded.
ehr_errorfhir_errorUpstream FHIR service failed.
ehr_erroroauth_errorUpstream OAuth provider failed.
ehr_erroremail_errorEmail delivery failed.
ehr_errortoken_exchange_failedMedblocks could not exchange an OAuth code for tokens.
ehr_errortoken_unavailableNo valid token is available for the upstream service.
ehr_errorstorage_errorCloud storage operation failed.
api_errorinternal_errorUnexpected Medblocks server error.
api_errordb_errorDatabase operation failed.
api_errorconfig_missingRequired server configuration is missing.

Handling Pattern

try {
  await medblocks("/sessions", { method: "POST", body });
} catch (error) {
  if (error instanceof MedblocksError) {
    console.error("Medblocks API error", {
      status: error.status,
      code: error.body?.error?.code,
      requestId: error.body?.error?.request_id,
    });
  }

  throw error;
}