Skip to content

Create an eConsult

A case (eConsult) needs four things: a connected practice (you send its practice key), a patient, an active provider from the practice’s roster, and a clinical question for one or more specialties. Attachments are optional but usually helpful.

You have two options.

Create the patient with the case. Send the patient’s demographics in the patient field of POST /cases, instead of patient_id. Thea finds or creates the patient in the same request, so a patient only exists in Thea once a consult is sent for them. See Create the case.

Or create the patient first with POST /patients, then reference them by patient_id. This suits integrations that sync patients anyway.

Terminal window
curl -X POST "$THEA_API/patients" \
-H "Authorization: Bearer $THEA_PARTNER_KEY" \
-H "Thea-Practice-Key: $THEA_PRACTICE_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: patient-acme-pt-99812" \
-d '{
"external_id": "acme-pt-99812",
"first_name": "Avery",
"last_name": "Johnson",
"date_of_birth": "1984-03-12"
}'

Both ways, Thea looks only in the practice your practice key belongs to, for:

  1. A patient with the same external_id, then
  2. A patient with the same first name, last name, and date of birth.

Patients in other practices are never matched, even with the same external_id, name, and date of birth.

If one matches, Thea uses that patient and updates the fields you sent (fields you omit stay unchanged). Otherwise it creates a new patient. POST /patients returns 200 for a match and 201 for a new patient; POST /cases always returns 201 with the case. Always sending external_id makes matching exact.

Terminal window
curl -X POST "$THEA_API/cases" \
-H "Authorization: Bearer $THEA_PARTNER_KEY" \
-H "Thea-Practice-Key: $THEA_PRACTICE_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: acme-ref-5521" \
-d '{
"patient": {
"external_id": "acme-pt-99812",
"first_name": "Avery",
"last_name": "Johnson",
"date_of_birth": "1984-03-12"
},
"provider": { "npi": "1234567890" },
"created_by_email": "ma@riverbend.example",
"specialty_ids": ["12"],
"question": "55F with new-onset palpitations; Holter shows frequent PVCs (8% burden). Echo normal. Is a beta-blocker reasonable first-line, and when should she see cardiology in person?",
"patient_consent_given": true,
"external_ids": { "referral_id": "acme-ref-5521" }
}'
Field Notes
patient or patient_id The patient’s demographics, or the id of a patient you created earlier. Send one, not both.
provider The clinician the case is for, by roster id, npi, or email. They must be an active provider in the practice. Specialists address their answer to them, and they get Thea’s usual notifications.
created_by_email Optional. An active staff member creating the case on the provider’s behalf.
specialty_ids From GET /specialties. Usually one; send several if the question spans specialties.
question The clinical question with relevant history, findings, and what you want answered. Specific questions get faster, more useful answers.
patient_consent_given Must be true. You confirm the patient agreed to an eConsult.
external_ids Optional. Your own IDs, such as referral_id. Thea echoes them on the case and on every webhook about it.

The response is the new case with status: "open", your external_ids, and a url that opens the case in Thea. responding_specialists stays empty until a specialist replies.

If the provider has no active seat, for example because the admin removed it after you showed the option, the request fails with 422 provider-not-active. Using your referral ID as the Idempotency-Key makes retries safe.

Attachments, such as your referral PDF, usually help the specialist. Upload each file to the case in one request, as multipart/form-data. PDF, JPEG, PNG, and HEIC files up to 25 MB are accepted. The file is posted in the case thread from the requesting provider (or author_provider_id), and specialists see it straight away.

Terminal window
curl -X POST "$THEA_API/cases/a1f3c9e27b4d4e0f9c6b2d8e5f7a1c3b/files" \
-H "Authorization: Bearer $THEA_PARTNER_KEY" \
-H "Thea-Practice-Key: $THEA_PRACTICE_KEY" \
-H "Idempotency-Key: acme-ref-5521-referral-pdf" \
-F "file=@referral-5521.pdf;type=application/pdf"
Response
{ "id": "6d0e4f2a9b", "filename": "referral-5521.pdf", "content_type": "application/pdf", "size_bytes": 482113 }

A file over 25 MB returns 413 file-too-large. To download any file on a case, including ones specialists attach, call GET /files/{file_id} for a link that works for 5 minutes.

  • Replies: each message triggers case.message.created. See Case messaging.
  • Specialists: a specialist appears in responding_specialists once they reply. Thea doesn’t share who a case is assigned to before then.
  • First response: first_specialist_response_at records when a specialist first replied.

When the question is answered, the provider closes the case, either in Thea or through you on their behalf. Specialists can’t close cases. When you close one, it’s recorded as closed by the requesting provider unless you name another active provider:

Terminal window
curl -X POST "$THEA_API/cases/a1f3c9e27b4d4e0f9c6b2d8e5f7a1c3b/close" \
-H "Authorization: Bearer $THEA_PARTNER_KEY" \
-H "Thea-Practice-Key: $THEA_PRACTICE_KEY" \
-H "Content-Type: application/json" \
-d '{ "closed_by_provider_id": "2210" }'

A closed case has status: "closed", a closed_at timestamp, and closed_by, and its thread is read-only. POST /cases/{case_id}/reopen reopens it, with an optional reopened_by_provider_id. Both calls are safe to repeat.

Thea builds its consult report PDF in the web app when a provider closes the case, so the API doesn’t return a PDF. To file a report in your system, wait for case.closed, fetch GET /cases/{case_id} and GET /cases/{case_id}/messages, and render the case and its conversation in your own format.

A case can be reopened and closed again (case.reopened, then case.closed), so treat each close as a new version of the report.