Handle the return

Read the return_url params, then show the connected facilities in your app.

Build Patient Access with AI
Open in
Show prompt text
You are an AI coding agent helping integrate Medblocks Patient Access into the codebase that is currently open. Treat the live Medblocks docs and generated API reference as the source of truth. If you are running inside a local repo that contains openapi/medblocks.json, read it too. Do not rely on endpoint names, SDK calls, response fields, or code snippets from memory.

Before changing code, read the current docs directly.

- Patient Access overview https://medblocks.com/docs/patient-access/overview
- Find connections https://medblocks.com/docs/patient-access/find-connections
- Create patients https://medblocks.com/docs/patient-access/create-patients
- Create a patient session https://medblocks.com/docs/patient-access/create-patient-session
- Medblocks-hosted page https://medblocks.com/docs/patient-access/create-patient-session/medblocks-hosted-page
- Your own UI https://medblocks.com/docs/patient-access/create-patient-session/your-own-ui
- Handle the return https://medblocks.com/docs/patient-access/handle-the-return
- After connection https://medblocks.com/docs/patient-access/after-connection
- Get the data https://medblocks.com/docs/patient-access/get-the-data
- API conventions https://medblocks.com/docs/reference/conventions
- API reference https://medblocks.com/docs/reference/api

Use the page I copied this from as the immediate task context, then use the rest of the Build pages to understand the full flow.

Work in this order.

1. Inspect this codebase first. Identify the app framework, server boundary, environment variable pattern, existing API client pattern, current patient or user identity model, logging style, and test runner.
2. Read the generated API reference before naming any route, field, enum, header, error code, or SDK method. If your tool has local filesystem access and this repo has openapi/medblocks.json, read that too. If the docs and reference disagree, stop and ask the user which source to follow.
3. Decide whether this app should use the Medblocks-hosted page, your own UI, or both. Ask the user if the answer is not obvious from the product.
4. Keep the Medblocks API key server-side. Never expose it through public environment variable prefixes, frontend bundles, browser logs, or client-side fetches.
5. Implement the smallest complete path for the selected page. Follow existing project conventions for file locations, naming, validation, errors, loading states, and tests.
6. After a patient returns from authorization, verify the result from the server using the latest documented Patient Access status flow. Do not trust query string values as the final source of truth.
7. Preserve Medblocks request IDs and documented error details in logs and server responses where safe. Avoid logging PHI unless this codebase already has an approved pattern.
8. Run the relevant type checks and tests before reporting done. If a live smoke test needs credentials the repo does not have, explain the exact manual smoke test steps.

If any required detail is missing, ask concise questions before writing code. In a healthcare integration, a correct pause is better than an incorrect assumption.

After the patient finishes the hosted page or the direct portal flow, their browser lands back on the return_url you set when you started the patient session. That URL is a route in your app, usually something like /connected. This page handles the return for both paths, the Medblocks-hosted page and your own UI.

What comes back

Every return URL carries patient_id and patient_session_id. When your own UI sends the patient straight to one connection, Medblocks also includes success or failure details for that connection.

ParameterMeaning
patient_idThe stable ID you gave the patient. Use it to read the patient’s current connections.
patient_session_idThe ID of this patient session. Store it if you want to inspect this browser journey later.
successPresent when your own UI sent the patient straight to one connection. true means the facility connected, false means the portal returned an error.
connection_idPresent on success when your own UI sent the patient straight to one connection.
error and error_descriptionPresent when the portal returned the patient without a connected facility.

parseReturnUrl reads those parameters and returns a typed object. If the current page was not opened from a Medblocks return URL, it returns null.

On your landing page

You can handle the return entirely on the server. Parse the URL, show a retry path when the portal returned an error, and read the patient’s connected facilities when the connection succeeded.

server/connected.ts
import { parseReturnUrl } from "medblocks";
import { mb } from "./medblocks";

export async function connected(req: Request): Promise<Response> {
  const result = parseReturnUrl(new URL(req.url).searchParams);
  if (!result) return new Response("Missing return parameters", { status: 400 });

  if ("success" in result && !result.success) {
    return Response.json({
      status: "retry",
      message: result.error_description ?? "Connection failed. Please try again.",
    });
  }

  const connections = await mb.patients.getConnections(result.patient_id, {
    hydrate: true,
  });

  return Response.json({
    status: "connected",
    patientId: result.patient_id,
    sessionId: result.patient_session_id,
    connections: connections.map((facility) => ({
      id: facility.id,
      name: facility.name,
      logo_url: facility.logo_url,
    })),
  });
}
connected-page.tsx
import { parseReturnUrl } from "medblocks";

export function ConnectedPage() {
  const result = parseReturnUrl();
  if (!result) return <Dashboard />;

  if ("success" in result && !result.success) {
    return <RetryPanel message={result.error_description ?? "Please try again."} />;
  }

  return <ConnectedFacilities patientId={result.patient_id} />;
}

Show connected facilities

The server example uses mb.patients.getConnections(result.patient_id, { hydrate: true }). That reads the patient, filters to connected facilities, and hydrates their names, logos, and portal URLs so your UI can display them immediately.

server/connected-facilities.ts
import { mb } from "./medblocks";

const facilities = await mb.patients.getConnections("user_42", { hydrate: true });

for (const facility of facilities) {
  console.log(facility.name, facility.logo_url);
}
Parameters
idstringrequired

Your patient_id from Patient creation or Session upsert.

Parameters
AuthorizationBearer <token>required

Medblocks API key for server-side requests.

Versionstring

Date-pinned API version. If omitted, Medblocks uses the version pinned on your API key.

Common errors

CodeMeaning
not_foundNo patient matches the patient_id in the return URL.
missing_api_keyThe Authorization header is missing from your server’s request.
invalid_api_keyThe key is invalid or does not belong to your organization.

Read the full envelope and code list in Errors.

See also