openapi: 3.2.0 info: title: Medblocks Patient Sessions API version: '2026-04-25' description: 'Developer API for the Medblocks Platform. Connect any patient to one or more EHRs (Epic, Cerner, Athena, …) via a single hosted PatientSession, then pull their unified FHIR records through this API. Server-to-server only — no browser-side calls. Authenticate every request with a Bearer secret key. **Resources:** `PatientSession`, `Patient`, `Connection`, `FhirSource`. **Conventions:** date-pinned versioning (optional `Version` header), a typed error envelope on every non-2xx response.' license: name: Proprietary url: https://medblocks.com/terms servers: - url: https://app.medblocks.com security: - BearerAuth: [] tags: - name: Patient Sessions paths: /patient-sessions: post: operationId: api.initPatientSession summary: Start a patient session description: Start a patient session and get back a `url` to send the patient to so they can connect their records. Track progress with the session's `status`. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PatientSessionInitInput' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/PatientSession' '400': description: '400' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '401': description: '401' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '403': description: '403' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '404': description: '404' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '409': description: '409' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': description: '429' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' headers: Retry-After: $ref: '#/components/headers/RetryAfter' '500': description: '500' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' parameters: - $ref: '#/components/parameters/Version' callbacks: pickerModeReturn: https://your-app.com/connected?patient_id={patient_id}&patient_session_id={patient_session_id}: get: summary: Medblocks-hosted page - patient clicked Done description: When the patient chooses a connection on the Medblocks-hosted page, Medblocks redirects the patient after they click Done. Call `GET /patients/{patient_id}` from your backend to inspect the patient's current connection state, or `GET /patient-sessions/{patient_session_id}` for the specific connections made in this session. parameters: - name: patient_id in: query required: true schema: type: string description: Your developer-supplied external patient id. Use this to look up the patient via `GET /patients/{id}`. - name: patient_session_id in: query required: true schema: type: string description: The `ps_*` public id of the completed patient_session. responses: '200': description: Your handler accepted the redirect. directModeSuccess: ? https://your-app.com/connected?patient_id={patient_id}&patient_session_id={patient_session_id}&success=true&connection_id={connection_id} : get: summary: Your own UI - EHR connection succeeded description: When `connection_id` was set on patient_session creation and the patient successfully authenticated with the EHR, Medblocks redirects straight to your `return_url` without showing any UI. parameters: - name: patient_id in: query required: true schema: type: string description: Your developer-supplied external patient id. Use this to look up the patient via `GET /patients/{id}`. - name: patient_session_id in: query required: true schema: type: string description: The `ps_*` public id of the completed patient_session. - name: success in: query required: true schema: type: string enum: - 'true' description: Always `"true"` on success. - name: connection_id in: query required: true schema: type: string description: The `fhirsrc_*` public id of the connected EHR. responses: '200': description: Your handler accepted the redirect. directModeError: ? https://your-app.com/connected?patient_id={patient_id}&patient_session_id={patient_session_id}&success=false&error={error_code} : get: summary: Your own UI - EHR connection failed description: When `connection_id` was set on patient_session creation and the EHR authentication failed (patient denied, OAuth error, etc.), Medblocks redirects to your `return_url` with error details. parameters: - name: patient_id in: query required: true schema: type: string description: Your developer-supplied external patient id. Use this to look up the patient via `GET /patients/{id}`. - name: patient_session_id in: query required: true schema: type: string description: The `ps_*` public id of the patient_session. - name: success in: query required: true schema: type: string enum: - 'false' description: Always `"false"` on failure. - name: error in: query required: true schema: type: string description: Stable error code (e.g. `user_denied`, `oauth_callback_failed`). - name: error_description in: query required: false schema: type: string description: Human-readable error message. responses: '200': description: Your handler accepted the redirect. tags: - Patient Sessions /patient-sessions/{id}: get: operationId: api.retrievePatientSession summary: Retrieve a patient session description: Retrieve a patient session by its `ps_` id, including its current status and the connections created during it. parameters: - name: id in: path required: true schema: type: string description: Patient session id (`ps_*`). - $ref: '#/components/parameters/Version' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/PatientSession' '400': description: '400' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '401': description: '401' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '403': description: '403' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '404': description: '404' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '409': description: '409' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': description: '429' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' headers: Retry-After: $ref: '#/components/headers/RetryAfter' '500': description: '500' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' tags: - Patient Sessions components: parameters: Version: name: Version in: header required: false description: Date-pinned API version. If omitted, Medblocks uses the version pinned on your API key. example: '2026-04-25' schema: type: string schemas: ErrorEnvelope: type: object properties: error: type: object properties: type: type: string description: Error category (e.g. authentication_error, permission_error, conflict_error). code: type: string description: Stable code within the type (e.g. invalid_api_key, external_id_already_exists). message: type: string description: Human-readable error message. param: anyOf: - type: string - type: 'null' description: Affected request parameter, if applicable. doc_url: type: string description: Link to the API errors reference. request_id: type: string description: Correlation id - include in support tickets. Echoes the `X-Request-Id` response header. required: - type - code - message - param - doc_url - request_id required: - error examples: - error: type: authentication_error code: invalid_api_key message: API key invalid param: null doc_url: https://medblocks.com/docs/reference/errors request_id: 9c9b6f7a-8e4f-4a3b-9c1e-6f3a2d8b7c4d PatientSessionInitInput: type: object properties: patient_id: type: string minLength: 1 description: Your stable identifier for this patient. patient_email: type: string format: email description: Patient email to store or update. patient_name: type: string description: Patient display name to store or update. connection_id: type: string minLength: 1 description: Connection ID from `/connections`. When present, the patient goes straight to that facility's patient portal. Mutually exclusive with `recommended_connection_ids`. recommended_connection_ids: type: array items: type: string minLength: 1 description: Connection IDs to show first on the Medblocks-hosted page. Mutually exclusive with `connection_id`. return_url: type: string format: uri description: URL to redirect after the patient session. return_button_label: type: string minLength: 1 maxLength: 60 description: Text shown on the patient-facing completion button. expires_in: type: integer minimum: 60 maximum: 86400 description: Seconds until the patient_session token expires. Default 1800 (30 min). Max 86400 (24h). metadata: type: object propertyNames: type: string additionalProperties: {} description: Additional metadata returned with the patient session. required: - patient_id - return_url additionalProperties: false examples: - patient_id: user_42 patient_email: jane@example.com patient_name: Jane Doe recommended_connection_ids: - fhirsrc_02Zh2bnvRoWQJYgOAkI0Twcc - fhirsrc_0a9Ea55aR4u7HaWMyFBN8wcc - fhirsrc_lcvXRHLSSI2WK9Prrt5Qggcc return_url: https://app.example.com/connected return_button_label: Acme Health expires_in: 1800 metadata: signup_source: checkout PatientSession: type: object properties: id: type: string description: Public id, prefixed `ps_`. resource_type: const: patient_session description: Resource type discriminator. Always `"patient_session"` for this resource. status: enum: - open - complete - expired type: string description: Lifecycle state. `open` while the patient is interacting; `complete` after they click Done; `expired` after `expires_at`. url: type: string description: Patient-facing URL. Redirect the patient browser to this on patient_session creation. patient_id: type: string description: The patient's `patient_id` (developer-provided). connection_id: anyOf: - type: string - type: 'null' description: Connection ID (`fhirsrc_*`) when the session was started for one facility. Null when the patient chooses on the Medblocks-hosted page. recommended_connection_ids: anyOf: - type: array items: type: string - type: 'null' description: Connection IDs (`fhirsrc_*`) shown first on the Medblocks-hosted page. Null when the session was started for one facility. return_url: type: string description: Where the patient lands when finishing the flow. Echoes the request value. return_button_label: anyOf: - type: string - type: 'null' description: Custom label on the "Done — return to {label}" button. Null when not set. connections: type: array items: type: object properties: id: anyOf: - type: string - type: 'null' description: Connection id (`conn_*`). Null for failed auth attempts. connection_id: type: string description: EHR id (`fhirsrc_*`). status: enum: - active - failed - expired - refresh_failed - disconnected type: string description: Connection lifecycle state. `active` = data flowing; `disconnected` = access was revoked; everything else needs patient remediation. failure_code: anyOf: - type: string - type: 'null' description: Stable failure code when `status=failed`. Null otherwise. failure_at: anyOf: - type: string - type: 'null' description: ISO 8601 timestamp of the failure when `status=failed`. Null otherwise. created_at: type: string description: ISO 8601 timestamp of when this connection was created. required: - id - connection_id - status - failure_code - failure_at - created_at description: Connections created during this patient_session — including failed attempts. Empty when no EHR has been connected yet. expires_at: type: string description: ISO 8601 timestamp at which the patient_session token becomes invalid. metadata: type: object propertyNames: type: string additionalProperties: {} description: Developer-supplied metadata key/value pairs. created_at: type: string description: ISO 8601 timestamp of when the patient_session was created. required: - id - resource_type - status - url - patient_id - connection_id - recommended_connection_ids - return_url - return_button_label - connections - expires_at - metadata - created_at examples: - id: ps_01J9YQ8M2X4VZ6P2K5RH7M3KQT resource_type: patient_session status: open url: https://app.medblocks.com/c/9c9b6f7a8e4f4a3b9c1e6f3a2d8b7c4d patient_id: user_42 connection_id: null recommended_connection_ids: - fhirsrc_02Zh2bnvRoWQJYgOAkI0Twcc - fhirsrc_0a9Ea55aR4u7HaWMyFBN8wcc - fhirsrc_lcvXRHLSSI2WK9Prrt5Qggcc return_url: https://app.example.com/connected return_button_label: Acme Health connections: [] expires_at: '2026-04-25T15:00:00.000Z' metadata: signup_source: checkout created_at: '2026-04-25T14:30:00.000Z' headers: RetryAfter: description: Whole seconds to wait before retrying a rate-limited request. schema: type: integer minimum: 1 securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: API key (mb_sk_live_...) description: Medblocks API key for server-side requests.