Skip to main content

Batch Patient Import

Create or update as many as 500 patients from one CSV file on the import page. Each data row is processed independently, so one failed row does not undo successful rows.

Quick start

  1. Download the current CSV template from the import page.
  2. Add one patient per row. Keep the camelCase column names exactly as shown.
  3. Upload the file and correct any client-side validation errors.
  4. Submit the import.
  5. Review the separate patient and insurance totals. Every CSV row remains available in the result table, including rows with no insurance information.
  6. Download the insurance-results CSV if you need to reconcile unresolved, incomplete, or failed coverages outside Solum.

Identifying a patient

Each row must contain either:
  • phoneNumber; or
  • all three of firstName, lastName, and dateOfBirth.
You may also provide a typed external ID using the optional pair externalIdType and externalId.
Both external-ID cells may be blank. If either is present, both are required.
  • externalIdType accepts the UUID or case-insensitive name of an external-ID type configured for your company.
  • externalId is trimmed and must contain 1–500 characters.
  • A row supports one typed external ID.
  • If the same resolved type and value appears more than once in the file, every duplicate row fails. Other rows continue.

How existing patients are matched

Batch import uses the same matching rules as the patient upsert API, in this order:
  1. Exact typed external ID
  2. Exact first name, last name, and date of birth
  3. Normalized phone number plus fuzzy name
  4. Normalized email plus fuzzy name
When a patient matches, supplied non-null fields update that patient using the same normalization, phone-lock, payor, audit-history, webhook, and side-effect rules as POST /v1/patients/upsert. If no patient matches, a new patient is created.

CSV columns

Column order does not matter. Unknown columns are ignored.

Patient fields

Workflow and tags

Values that cannot be resolved are reported in dropped_fields for that row.

Insurance

Insurance names are lookup-only and flow through the same resolver used by POST /v1/patients/upsert. Solum can select only an active insurance belonging to your company with a nonblank trading-partner service ID. It tries canonical names, configured aliases, state-aware variants, and then a bounded AI-assisted match. An unresolved insurance does not fail the patient row. The patient and any other valid coverage can still succeed, and the unresolved coverage is reported with a stable reason. A member ID with a blank insurance-name cell is reported as incomplete; a row where all four insurance cells are blank is not_provided.

Referral

Partial-success results

A valid top-level request returns HTTP 200 even if individual rows fail. Authentication errors, malformed JSON, an empty item list, and more than 500 items remain request-level errors. The response keeps the original patient aggregates and adds separate insurance aggregates plus one ordered result for every patient row. Each row contains one ordered payor_results item per supplied primary or secondary coverage.
row is the one-based data-row number and does not count the header. Patient outcomes are represented by error, created, and matched; insurance outcomes come from insurance_status and payor_results.

Insurance statuses and outcomes

Row-level insurance_status values are: Each payor_results[].outcome is one of created, updated, unchanged, unresolved, incomplete, failed, or not_processed. Expected resolution abstentions use these stable reason_code values:
  • insurance_name_missing
  • no_configured_match
  • configured_insurance_inactive
  • insurance_not_vob_ready
  • ambiguous_match
  • match_confidence_too_low
  • resolution_unavailable
  • persistence_failed
  • patient_row_failed
The completion page shows all rows, supports All, Needs Review, Created, Updated, Unchanged, and No Insurance filters, and paginates after filtering. Needs Review does not include informational not_provided rows. The downloadable insurance report contains patient and configured-coverage identifiers and safe outcome details, but never patient names or insurance member IDs.

Troubleshooting