API v1 · Reference
POST /v1/soap
One-call SOAP intake. Submit a finished transcript or the consultation audio, and the platform queues the full pipeline: structured SOAP note, ICD-10 candidates matched from the curated code table, WHO/IMCI-aligned triage and the NHIS billing proposal.
What one call produces
Everything below is generated from the consultation alone — no invented facts, no demographic inferences.
Subjective, Objective, Assessment and Plan drafted from strictly validated, evidence-grounded facts extracted from the consultation.
Codes matched programmatically from the curated ICD-10-CM table, each with the concept and verbatim note phrases that produced it. The model never invents a code.
Deterministic, offline triage over the transcript and note: general danger signs, matching WHO and national protocols, ordered next steps and notifiable-disease flags.
Claim items tagged by scheme with coverage notes, plus claim-readiness checks that flag the usual denial reasons before filing.
Request format
Required scope: transcription.create. Send either a JSON transcript or a multipart audio upload — never both.
| Field | Required | Description |
|---|---|---|
| transcript | JSON only | The consultation transcript, 20–100,000 characters. Use this when your app already holds text (telemedicine chat, typed notes, a completed streaming session). |
| audio | Multipart only | The consultation recording as multipart field `audio`. Max 60 MB. Accepted types: audio/webm, ogg, wav, mpeg, mp4, m4a, flac. Audio is stored in the partner bucket only and deleted once transcription finishes. |
| external_consultation_id | Required for audio; recommended always | Your own encounter reference (≤128 chars). It is the idempotency key: resubmitting the same reference returns the existing job instead of creating a duplicate encounter. Omitted values are auto-generated. |
| encounter_type | No | One of outpatient (default), inpatient, telehealth, emergency, follow_up. |
| language | No | BCP-47 style code for the consultation language — en, yo, ha, sw, pcm. Amharic (am) and Oromo (om) are in beta. Improves transcription and terminology handling. |
| specialty | No | A specialty engine id from GET /specialties (behavioural health, refugee/immigrant health, PT, OT and core specialties). Shapes note structure and vocabulary only; never adds facts. |
| external_patient_id | No | Your own opaque patient reference (≤128 chars). Never a name, phone number or medical record number. Defaults to "unspecified". |
| external_clinician_id | No | Your own opaque clinician reference (≤128 chars). Defaults to "unspecified". |
| age_group | No | One of infant, child, adult (default), elderly. Selects the correct WHO/IMCI protocol set for triage. The API never infers age from the transcript — pass it when you know it. |
| pregnant | No | Boolean, default false. Applies pregnancy-specific triage protocols (for example pre-eclampsia and malaria-in-pregnancy pathways). |
curl -X POST https://gelypticmd.com/api/public/v1/soap \
-H "Authorization: Bearer $GELYPTIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_consultation_id": "clinic-4821",
"encounter_type": "outpatient",
"language": "pcm",
"age_group": "child",
"transcript": "Doctor: Wetin dey worry am? Mother: the pikin dey purge since yesterday and e no fit feed..."
}'
# -> 202 Accepted
# {
# "encounter_id": "b0f1c2d3-...",
# "job_id": "JOB-9F2C4B1E8A7D4C2F",
# "status": "processing"
# }curl -X POST https://gelypticmd.com/api/public/v1/soap \
-H "Authorization: Bearer $GELYPTIC_API_KEY" \
-F "external_consultation_id=clinic-4821" \
-F "encounter_type=outpatient" \
-F "language=yo" \
-F "age_group=adult" \
-F "audio=@consultation.webm"Response
The request is accepted synchronously; the AI work never runs inline.
{
"encounter_id": "b0f1c2d3-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
"job_id": "JOB-9F2C4B1E8A7D4C2F",
"status": "processing"
}- encounter_id
- The platform encounter id. Use it with GET /clinical/notes/{encounter_id} once the note is drafted.
- job_id
- Pollable via GET /jobs/{job_id}. Queued → Processing → Completed/Failed.
- x-request-id
- Every response carries a request id header; quote it when contacting support.
- Idempotency
- Re-submitting the same external_consultation_id returns 200 with the current job state and idempotent: true — no duplicate encounter is created.
- Errors
- 400 INVALID_REQUEST (bad payload), 401 (missing/invalid key), 403 (scope missing), 413 PAYLOAD_TOO_LARGE, 429 RATE_LIMITED, 500 INTERNAL_ERROR.
{
"encounter_id": "b0f1c2d3-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
"job_id": "JOB-9F2C4B1E8A7D4C2F",
"status": "PROCESSING",
"idempotent": true
}Receiving the result
Two delivery options. Use the webhook in production; polling is the fallback.
{
"id": "evt_01H…",
"type": "soap.generated",
"created_at": "2026-10-06T22:41:07Z",
"api_version": "v1",
"data": {
"consultation_id": "b0f1c2d3-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
"external_consultation_id": "clinic-4821",
"job_id": "JOB-9F2C4B1E8A7D4C2F",
"status": "draft",
"fhir_bundle": { "resourceType": "Bundle", "type": "collection", "entry": [ "..." ] },
"icd10_suggestions": [
{
"concept": "uncomplicated malaria",
"codes": [ { "code": "B54", "title": "Unspecified malaria" } ]
}
],
"triage": {
"level": "priority",
"danger_signs": [],
"actions": [ "Do a malaria RDT before starting treatment." ],
"notifiable": false
},
"billing": {
"scheme": "NHIS",
"claim_items": [
{ "id": "mrdt", "label": "Malaria rapid diagnostic test",
"note": "Reimbursable diagnostic. Attach the result value to avoid a denial." }
],
"claim_checks": [
{ "id": "diagnosis", "label": "A codable diagnosis is documented",
"passed": true, "detail": "1 ICD-10 candidate(s) found." }
]
}
}
}curl https://gelypticmd.com/api/public/v1/jobs/JOB-9F2C4B1E8A7D4C2F \
-H "Authorization: Bearer $GELYPTIC_API_KEY"
# {
# "job_id": "JOB-9F2C4B1E8A7D4C2F",
# "consultation_id": "b0f1c2d3-...",
# "status": "COMPLETED",
# "detail_status": "drafted",
# "updated_at": "2026-10-06T22:41:07Z"
# }Webhook deliveries are HMAC-signed over {timestamp}.{rawBody} and carry an x-scribemd-signature header — verify them exactly as shown in webhooks. Once completed, fetch the full note — including the complete triage and billing structures — with GET /clinical/notes/{encounter_id}.
Response structure reference
soap_note
- subjective
- Reported symptoms and history, in the patient's own framing after terminology normalisation. Never contains age, sex or other demographics.
- objective
- Only stated examination findings; otherwise a fixed placeholder sentence.
- assessment
- Clinical impression phrased as suggestions when not confirmed in the consultation.
- plan
- Only items discussed in the consultation; otherwise a fixed placeholder sentence.
- state
- Always "draft" until a clinician approves the note; "approved" afterwards. Drafts are never presented as signed clinical records.
icd10_suggestions
- concept
- A plain clinical concept to code, extracted from the transcript with verbatim evidence.
- codes
- Matching ICD-10-CM entries from the curated code table (code and title). Empty when no confident match exists — candidates are never guessed.
triage
- level
- One of emergency, urgent, priority, routine. A WHO general danger sign always forces emergency.
- danger_signs
- The WHO/IMCI general danger signs matched in the consultation (for example convulsion, unable to drink or feed, vomiting everything).
- protocols
- Matching WHO and national protocols with source, matched triggers, ordered actions, confirmatory tests and explicit cautions. Age-specific protocols apply only when age_group was supplied.
- actions
- Ordered, deduplicated next steps for the clinician.
- notifiable
- True when a protocol matches a notifiable disease (for example suspected VHF, measles or meningitis) and your surveillance programme should be alerted.
billing
- scheme
- Currently "NHIS". Claim items carry per-scheme coverage notes from NHIS Nigeria and NHIF Kenya practice.
- claim_items
- Proposed billable items: id, label, scheme and a note on bundling or documentation the scheme normally requires.
- claim_checks
- Claim-readiness checks — codable diagnosis, documented indication for investigations, a management plan, clinician review recorded, referral authorisation code, capitation double-billing. Each check carries passed and an explanatory detail.
- Nothing is auto-submitted
- Billing output is a proposal for the clinician or biller to confirm. GELYPTIC MD never files a claim or charges an insurer.
Working example, end to end
import crypto from "node:crypto";
// 1. Submit the consultation — one call.
const submit = await fetch("https://gelypticmd.com/api/public/v1/soap", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GELYPTIC_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
external_consultation_id: "clinic-4821",
language: "pcm",
age_group: "child",
transcript: consultationTranscript,
}),
});
const { encounter_id, job_id } = await submit.json();
// 2. Verify and consume the signed soap.generated webhook.
app.post("/gelyptic/webhooks", (req, res) => {
const raw = rawBodyOf(req); // the exact bytes that arrived
const parts = Object.fromEntries(
(req.headers["x-scribemd-signature"] ?? "").split(",").map((p) => p.split("=")),
);
const expected = crypto
.createHmac("sha256", process.env.GELYPTIC_WEBHOOK_SECRET)
.update(`${parts.t}.${raw}`)
.digest("hex");
const a = Buffer.from(parts.v1 ?? "", "hex");
const b = Buffer.from(expected, "hex");
const ok = a.length === b.length && crypto.timingSafeEqual(a, b)
&& Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
if (!ok) return res.sendStatus(401);
if (req.body.type === "soap.generated") {
saveNote(req.body.data); // store the draft, queue clinician review
}
res.sendStatus(200);
});import os, requests
res = requests.post(
"https://gelypticmd.com/api/public/v1/soap",
headers={"Authorization": f"Bearer {os.environ['GELYPTIC_API_KEY']}"},
json={
"external_consultation_id": "clinic-4821",
"language": "pcm",
"age_group": "child",
"transcript": consultation_transcript,
},
timeout=30,
)
res.raise_for_status()
job = res.json() # {"encounter_id": ..., "job_id": ..., "status": "processing"}
print(job["job_id"])The typed SDKs wrap this endpoint: client.submitSoap({ transcript, externalConsultationId }) in TypeScript and client.submit_soap(transcript=…, external_consultation_id=…) in Python.
Clinical safety and data boundaries
- Clinician review is not bypassable
- Every generated note is a draft. Your application must present it for clinician approval before it becomes a clinical record, and interoperability exports are only produced after approval.
- No demographics
- The pipeline never mentions or infers age, sex, gender, race or ethnicity in generated notes. The age_group and pregnant fields only select triage protocols and are stored as coarse context, never copied into notes.
- Your records only
- Encounters filed through /soap belong to the calling application. There is no cross-tenant read path, and GELYPTIC MD clinician consultations are unreachable through the API.
- Browser session tokens cannot call /soap
- Session tokens are scope-reduced to embedded upload and read scopes. Only a server-held API key can create encounters and generate notes.
- No compliance claim
- These are security controls we implement — they are not, by themselves, a regulatory compliance certification.