Group your data with the Helios API.
Send contacts from your own systems and get DRG groupings back as JSON — the same engine as Grouper in the portal.
Quick start
The Helios grouping API lets your own systems send patient contacts and receive the DRG grouping back as JSON — using exactly the same grouping engine as Grouper in the Helios portal.
- Ask Helios for an API key. You will receive it once, as a text starting with
hgk_. Keep it secret, like a password. - Send your contacts to
https://heliosgroup.dk/api/v1/groupwith the key in anAuthorizationheader. - Read the DRG code, name, tariff, trim point and length of stay from each result.
curl -X POST https://heliosgroup.dk/api/v1/group \
-H "Authorization: Bearer hgk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"primaryDiagnosis":"DJ189","ageYears":72,"sex":"F"}'
Base URL for everything below: https://heliosgroup.dk/api/v1
Authentication
Every endpoint except /health needs your API key. Send it in either header:
Authorization: Bearer hgk_YOUR_KEY
X-API-Key: hgk_YOUR_KEY
- Always use HTTPS. Never put the key in a web page, a mobile app or a URL — call the API from your own server or batch job.
- A key can have an expiry date and can be limited to certain logics. Helios can revoke it at any time; if you think it has leaked, tell us and we issue a new one.
- Use one key per system, so a single key can be switched off without stopping the others.
- On request Helios can limit a key to your servers' IP addresses. A request from any other address is refused with
403 ip_not_allowed.
Endpoints
| Method and path | What it does |
|---|---|
GET /health | Checks that the API is up. No key needed. |
GET /logics | Lists the logics your key may group against (id, name, year, whether it is the active one). |
GET /logics/{id} | One logic, including the coded values it accepts for admission priority, discharge disposition, contact reason and patient type. |
POST /group | Groups one contact or a batch of up to 500. |
POST /group
Send either a single contact as the body, or a batch:
{
"logic": "active",
"contacts": [
{ "id": "A-1001", "primaryDiagnosis": "DJ189", "ageYears": 72, "sex": "F" },
{ "id": "A-1002", "primaryDiagnosis": "DS720", "procedures": ["KNFB20"], "ageYears": 81, "sex": "M" }
]
}
logic is optional. Leave it out (or use "active") to use whichever logic is active at Helios right now. To group against a specific year, use the id from GET /logics. Only logics that have been fully approved by Helios are available.
Grouping against the default logic means your results change when Helios sets a new year's logic as the default. If you need results that never change, name a logic by id and store that id with your results.
The reply:
{
"apiVersion": "1",
"logic": { "id": "dk-drg-2026", "name": "DK-DRG 2026", "year": 2026, "isActive": true },
"count": 2,
"results": [
{ "index": 0, "id": "A-1001", "matched": true, "drgCode": "04MA13", "drgName": "…",
"price": 31250, "trimPoint": 9, "los": 4.2, "regel": 1234, "rtc": 0, "rtcMeaning": null,
"mdc": "04", "dgcat": "…", "icdValid": true, "effectivePrimaryDiagnosis": "DJ189" },
{ "index": 1, "id": "A-1002", "matched": true, "…": "…" }
]
}
The values above are illustrative. Results come back in the same order as the contacts you sent, and carry your own id back so you can match them without relying on position.
The contact object
All fields are optional in the sense that the API will always answer, but a contact with no primary diagnosis cannot be grouped to a meaningful DRG.
| Field | Type | Meaning |
|---|---|---|
id | string or number | Your own reference for the contact. Returned unchanged in the result. Not stored by Helios. |
primaryDiagnosis | string | Action diagnosis (aktionsdiagnose), SKS code with the leading letter, e.g. DJ189. |
secondaryDiagnoses | list of strings | Bi-diagnoses (bidiagnoser), SKS codes. Up to 100. |
procedures | list of strings | Procedure codes, e.g. KNFB20. Up to 100. |
supplementCodes | list of strings | Supplementary (tillægs-) codes belonging to the procedures. Up to 100. |
ageYears / ageDays | number | Age at admission. Send one of them; ageDays is more exact for newborns and wins if both are sent. |
sex | string | "M" or "F" (also accepted: "K", "male", "female", 1, 2). Empty if unknown. |
admissionPriority | string | Admission priority code (INDM). |
dischargeDisposition | string | Discharge disposition code (DISCDISP). |
contactReason | string | Contact reason code (KONTAARS). |
contactDays | number | Length of the contact in days. |
pattype | string | Patient type code (PATTYPE). |
The accepted values for the four coded fields differ slightly between logic years. Look them up with GET /logics/{id} — the reply contains an allowedValues object with admissionPriority, dischargeDisposition, contactReason and pattype.
Fields the API does not know are ignored and reported in a warnings list on that contact's result.
The result object
| Field | Meaning |
|---|---|
index | Position of the contact in your request (starting at 0). |
id | Your own id for the contact, or null if you sent none. |
matched | true when a DRG rule matched. When false the other grouping fields are empty. |
drgCode, drgName | The DRG the contact was grouped to. |
price | The DRG tariff, as given in the logic's tariff table. |
trimPoint, los | Trim point and average length of stay for the DRG. |
regel | Number of the rule that matched (the first matching rule wins) — useful when you want to look the decision up in Atlas. |
rtc, rtcMeaning | Return-to-caller code from the engine, with a plain-language meaning when there is one. |
mdc, dgcat | Major diagnostic category and diagnosis category derived from the primary diagnosis. |
icdValid | Whether the primary diagnosis exists in the logic's diagnosis table. |
effectivePrimaryDiagnosis | The diagnosis the grouping actually used (it can differ from the one you sent when the logic replaces it). |
warnings | Only present when something was ignored, e.g. an unknown field. |
error | Only present when this one contact was rejected (invalid_contact) — the rest of the batch is still grouped. |
Converting your data
Most hospital extracts come as several flat files: one row per contact (the stam file), one row per diagnosis (diag) and one row per procedure (proc), linked by a contact number. The API wants one JSON object per contact with the diagnoses and procedures gathered into lists. The steps are always the same:
- Read the contact file. One JSON object per row. Map your contact number to
id, the action diagnosis toprimaryDiagnosis, age and sex toageYears/ageDaysandsex, and the admission, discharge and reason codes toadmissionPriority,dischargeDispositionandcontactReason. - Read the diagnosis file. Group the rows by contact number. The row marked as the action diagnosis becomes
primaryDiagnosis(if it is not already in the contact file); all others go intosecondaryDiagnoses. - Read the procedure file. Group by contact number; the procedure codes go into
procedures, and any supplementary codes intosupplementCodes. - Send in batches of up to 500 contacts and match the results back by
id.
Check three things in your data before you blame the grouping:
- Codes must be the SKS codes including their leading letter (
DJ189, notJ189), with no dots, spaces or lower-case letters. Trim and upper-case them first. - Dates are not sent. Compute age and length of contact yourself (age at admission, in days or years).
- Coded fields (admission, discharge, reason, patient type) must use the codes listed by
GET /logics/{id}. An empty value is accepted and simply does not match rules that need it.
The Python example below does the whole conversion and sends the batches. Change the column names in the COLUMNS block to match your own files.
Code examples
curl — look up the logics your key can use
curl https://heliosgroup.dk/api/v1/logics \
-H "Authorization: Bearer hgk_YOUR_KEY"
curl https://heliosgroup.dk/api/v1/logics/dk-drg-2026 \
-H "Authorization: Bearer hgk_YOUR_KEY"
Python — group a stam / diag / proc extract
import csv, json, os, sys, urllib.request
from collections import defaultdict
API = "https://heliosgroup.dk/api/v1"
KEY = os.environ["HELIOS_API_KEY"] # never hard-code the key
LOGIC = "active" # or an id from GET /logics
# ---- adjust to your own files --------------------------------------
COLUMNS = {
"stam": {"id": "kontaktnr", "age": "alder_aar", "sex": "koen",
"admission": "indm", "discharge": "discdisp", "reason": "kontaars",
"primary": "aktionsdiagnose"},
"diag": {"id": "kontaktnr", "code": "diagnose"},
"proc": {"id": "kontaktnr", "code": "procedure"},
}
DELIM, ENC = ";", "utf-8"
# ---------------------------------------------------------------------
def rows(path):
with open(path, newline="", encoding=ENC) as f:
yield from csv.DictReader(f, delimiter=DELIM)
def clean(code):
return (code or "").strip().upper().replace(".", "").replace(" ", "")
def build(stam, diag, proc):
c = COLUMNS
contacts = {}
for r in rows(stam):
cid = r[c["stam"]["id"]]
contacts[cid] = {
"id": cid,
"primaryDiagnosis": clean(r[c["stam"]["primary"]]),
"ageYears": float(r[c["stam"]["age"]] or 0) if r[c["stam"]["age"]] else None,
"sex": r[c["stam"]["sex"]],
"admissionPriority": r[c["stam"]["admission"]],
"dischargeDisposition": r[c["stam"]["discharge"]],
"contactReason": r[c["stam"]["reason"]],
"secondaryDiagnoses": [], "procedures": [],
}
for r in rows(diag):
k = contacts.get(r[c["diag"]["id"]])
code = clean(r[c["diag"]["code"]])
if k and code and code != k["primaryDiagnosis"]:
k["secondaryDiagnoses"].append(code)
for r in rows(proc):
k = contacts.get(r[c["proc"]["id"]])
code = clean(r[c["proc"]["code"]])
if k and code:
k["procedures"].append(code)
return list(contacts.values())
def post(batch):
req = urllib.request.Request(
API + "/group",
data=json.dumps({"logic": LOGIC, "contacts": batch}).encode(),
headers={"Authorization": "Bearer " + KEY, "Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=120) as resp:
return json.load(resp)
if __name__ == "__main__":
stam, diag, proc, out = sys.argv[1:5]
contacts = build(stam, diag, proc)
fields = ["id", "matched", "drgCode", "drgName", "price", "trimPoint", "los", "regel"]
with open(out, "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=fields, delimiter=";", extrasaction="ignore")
w.writeheader()
for i in range(0, len(contacts), 500):
reply = post(contacts[i:i + 500])
for res in reply["results"]:
w.writerow(res)
print("Grouped", len(contacts), "contacts with", reply["logic"]["name"])
Run it with HELIOS_API_KEY=hgk_… python group.py stam.csv diag.csv proc.csv result.csv.
JavaScript (Node 18+) — one batch
const res = await fetch("https://heliosgroup.dk/api/v1/group", {
method: "POST",
headers: {
"Authorization": "Bearer " + process.env.HELIOS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
contacts: [
{ id: "A-1001", primaryDiagnosis: "DJ189", ageYears: 72, sex: "F" },
],
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error.code + ": " + data.error.message);
for (const r of data.results) console.log(r.id, r.drgCode, r.price);
Errors
Errors always have the same shape and a matching HTTP status:
{ "error": { "code": "invalid_key", "message": "The API key is not valid." } }
| Status | Code | Meaning and what to do |
|---|---|---|
| 400 | bad_json, bad_request | The body is not valid JSON, is not an object, or contacts is empty or not a list. |
| 401 | missing_key | No key was sent. Add the Authorization header. |
| 401 | invalid_key | The key is mistyped or unknown. Check for stray spaces or line breaks. |
| 401 | revoked_key | Helios has switched this key off. Ask for a new one. |
| 401 | expired_key | The key has passed its expiry date. Ask for a new one. |
| 403 | ip_not_allowed | The key is limited to certain IP addresses and this request came from another one. Ask Helios to add the address, or call from your registered server. |
| 403 | logic_not_allowed | Your key may not use the current default logic. Name an allowed logic in logic. |
| 404 | logic_not_found | That logic id does not exist, is not approved yet, or is not allowed for your key. List the available ones with GET /logics. |
| 404 | not_found | Unknown endpoint. |
| 405 | method_not_allowed | Wrong HTTP method (POST for /group, GET for the others). |
| 409 | no_active_logic | No logic is active at the moment. Name one by id, or try later. |
| 413 | too_many_contacts | More than 500 contacts in one request. Split the batch. |
| 503 | logic_unavailable | The logic's data is temporarily incomplete. Retry in a minute; contact Helios if it persists. |
A single bad contact does not fail the request: it comes back with matched: false and an error object (invalid_contact, with a message such as sex must be "M" or "F"), while the others are grouped normally. Always check each result.
Limits and good practice
- Up to 500 contacts per request, and up to 100 codes in each code list.
- Group large files in sequential batches of a few hundred. Parallel requests are fine in moderation; if you see HTTP 5xx or 429 responses, wait a few seconds and retry with a pause between attempts.
- Each key may send up to 120 requests per minute. Above that you get HTTP 429 with a
Retry-Afterheader (seconds to wait). Send contacts in batches rather than one request per contact. - The first request after a quiet period can take a few seconds while the logic is loaded; later requests are fast.
- Helios does not store the contacts you send. The API is meant for grouping, so send only what the fields above need — no names, no CPR numbers.
- When Helios corrects a logic, the correction reaches the API within about a minute.
- The response header
X-Helios-Api-Versiontells you the API version. Version 1 will not change in ways that break existing clients; new fields may be added, so ignore fields you do not know.
Status and alerts
- The public status page shows whether the grouping API is answering and how often it has over the last 90 days.
GET /api/v1/health(no key needed) is what it checks, and you can use it for your own monitoring. - If your errors for a day get unusually high, or a key is about to expire, your users get a notice in the bell of the client portal and, if email is set up, an email. Check API usage in the portal for details.
- For files too big to send as requests (thousands of contacts), use Bulk grouping in the Casemix Engine instead: upload the file, and download the result when it is ready.
Support
Need a key, a new key, a limit changed, or help with a mapping? Contact your Helios consultant, or write via the contact page. Mention which key name it concerns — never send the key itself.
Gruppér dine data med Helios API.
Send kontakter fra dine egne systemer, og få DRG-grupperinger tilbage som JSON — med samme motor som Grouper i portalen.
Kom i gang
Helios' grupperings-API lader dine egne systemer sende patientkontakter og få DRG-grupperingen tilbage som JSON — med præcis samme grupperingsmotor som Grouper i Helios-portalen.
- Bed Helios om en API-nøgle. Du modtager den én gang, som en tekst, der begynder med
hgk_. Hold den hemmelig, ligesom en adgangskode. - Send dine kontakter til
https://heliosgroup.dk/api/v1/groupmed nøglen i enAuthorization-header. - Aflæs DRG-kode, navn, takst, trimpunkt og liggetid i hvert resultat.
curl -X POST https://heliosgroup.dk/api/v1/group \
-H "Authorization: Bearer hgk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"primaryDiagnosis":"DJ189","ageYears":72,"sex":"F"}'
Basis-URL for alt nedenfor: https://heliosgroup.dk/api/v1
Autentificering
Alle endpoints undtagen /health kræver din API-nøgle. Send den i en af disse headers:
Authorization: Bearer hgk_YOUR_KEY
X-API-Key: hgk_YOUR_KEY
- Brug altid HTTPS. Læg aldrig nøglen på en webside, i en mobilapp eller i en URL — kald API'et fra din egen server eller dit eget batchjob.
- En nøgle kan have en udløbsdato og kan begrænses til bestemte logikker. Helios kan tilbagekalde den når som helst; hvis du tror, at den er kommet ud, så sig det til os, så udsteder vi en ny.
- Brug én nøgle pr. system, så en enkelt nøgle kan slås fra uden at stoppe de andre.
- Efter aftale kan Helios begrænse en nøgle til dine serveres IP-adresser. En forespørgsel fra en anden adresse afvises med
403 ip_not_allowed.
Endpoints
| Metode og sti | Hvad den gør |
|---|---|
GET /health | Kontrollerer, at API'et kører. Kræver ingen nøgle. |
GET /logics | Viser de logikker, din nøgle må gruppere mod (id, navn, år, og om den er den aktive). |
GET /logics/{id} | Én logik, inklusive de kodede værdier, den accepterer for indlæggelsesprioritet, udskrivningsmåde, kontaktårsag og patienttype. |
POST /group | Grupperer én kontakt eller en batch på op til 500. |
POST /group
Send enten en enkelt kontakt som body eller en batch:
{
"logic": "active",
"contacts": [
{ "id": "A-1001", "primaryDiagnosis": "DJ189", "ageYears": 72, "sex": "F" },
{ "id": "A-1002", "primaryDiagnosis": "DS720", "procedures": ["KNFB20"], "ageYears": 81, "sex": "M" }
]
}
logic er valgfri. Udelad den (eller brug "active") for at bruge den logik, der lige nu er aktiv hos Helios. Hvis du vil gruppere mod et bestemt år, skal du bruge id fra GET /logics. Kun logikker, der er fuldt godkendt af Helios, er tilgængelige.
Hvis du grupperer mod standardlogikken, ændrer dine resultater sig, når Helios gør et nyt års logik til standard. Hvis du har brug for resultater, der aldrig ændrer sig, skal du angive en logik med id og gemme dette id sammen med dine resultater.
Svaret:
{
"apiVersion": "1",
"logic": { "id": "dk-drg-2026", "name": "DK-DRG 2026", "year": 2026, "isActive": true },
"count": 2,
"results": [
{ "index": 0, "id": "A-1001", "matched": true, "drgCode": "04MA13", "drgName": "…",
"price": 31250, "trimPoint": 9, "los": 4.2, "regel": 1234, "rtc": 0, "rtcMeaning": null,
"mdc": "04", "dgcat": "…", "icdValid": true, "effectivePrimaryDiagnosis": "DJ189" },
{ "index": 1, "id": "A-1002", "matched": true, "…": "…" }
]
}
Værdierne ovenfor er eksempler. Resultaterne kommer tilbage i samme rækkefølge som de kontakter, du sendte, og de bærer dit eget id med tilbage, så du kan koble dem sammen uden at stole på placeringen.
Kontaktobjektet
Alle felter er valgfri i den forstand, at API'et altid svarer, men en kontakt uden aktionsdiagnose kan ikke grupperes til en meningsfuld DRG.
| Felt | Type | Betydning |
|---|---|---|
id | tekst eller tal | Din egen reference for kontakten. Returneres uændret i resultatet. Gemmes ikke af Helios. |
primaryDiagnosis | tekst | Aktionsdiagnose, SKS-kode med det foranstillede bogstav, fx DJ189. |
secondaryDiagnoses | liste af tekster | Bidiagnoser, SKS-koder. Op til 100. |
procedures | liste af tekster | Procedurekoder, fx KNFB20. Op til 100. |
supplementCodes | liste af tekster | Tillægskoder, der hører til procedurerne. Op til 100. |
ageYears / ageDays | tal | Alder ved indlæggelsen. Send en af dem; ageDays er mere præcis for nyfødte og gælder, hvis begge sendes. |
sex | tekst | "M" eller "F" (også accepteret: "K", "male", "female", 1, 2). Tom, hvis ukendt. |
admissionPriority | tekst | Kode for indlæggelsesprioritet (INDM). |
dischargeDisposition | tekst | Kode for udskrivningsmåde (DISCDISP). |
contactReason | tekst | Kode for kontaktårsag (KONTAARS). |
contactDays | tal | Kontaktens længde i dage. |
pattype | tekst | Kode for patienttype (PATTYPE). |
De accepterede værdier for de fire kodede felter varierer en smule mellem logikkens år. Slå dem op med GET /logics/{id} — svaret indeholder et allowedValues-objekt med admissionPriority, dischargeDisposition, contactReason og pattype.
Felter, som API'et ikke kender, ignoreres og rapporteres i en warnings-liste på den pågældende kontakts resultat.
Resultatobjektet
| Felt | Betydning |
|---|---|
index | Kontaktens placering i din forespørgsel (begynder ved 0). |
id | Dit eget id for kontakten, eller null, hvis du ikke sendte et. |
matched | true, når en DRG-regel matchede. Når den er false, er de øvrige grupperingsfelter tomme. |
drgCode, drgName | Den DRG, kontakten blev grupperet til. |
price | DRG-taksten, som den er angivet i logikkens taksttabel. |
trimPoint, los | Trimpunkt og gennemsnitlig liggetid for DRG'en. |
regel | Nummeret på den regel, der matchede (den første matchende regel vinder) — nyttigt, når du vil slå beslutningen op i Atlas. |
rtc, rtcMeaning | Returkode (return-to-caller) fra motoren, med en forklaring i klartekst, når der findes en. |
mdc, dgcat | Hoveddiagnosegruppe (MDC) og diagnosekategori udledt af aktionsdiagnosen. |
icdValid | Om aktionsdiagnosen findes i logikkens diagnosetabel. |
effectivePrimaryDiagnosis | Den diagnose, grupperingen faktisk brugte (den kan afvige fra den, du sendte, når logikken erstatter den). |
warnings | Er kun til stede, når noget blev ignoreret, fx et ukendt felt. |
error | Er kun til stede, når netop denne kontakt blev afvist (invalid_contact) — resten af batchen grupperes stadig. |
Konvertering af dine data
De fleste udtræk fra hospitaler kommer som flere flade filer: én række pr. kontakt (stam-filen), én række pr. diagnose (diag) og én række pr. procedure (proc), koblet sammen med et kontaktnummer. API'et vil have ét JSON-objekt pr. kontakt, hvor diagnoser og procedurer er samlet i lister. Trinnene er altid de samme:
- Læs kontaktfilen. Ét JSON-objekt pr. række. Map dit kontaktnummer til
id, aktionsdiagnosen tilprimaryDiagnosis, alder og køn tilageYears/ageDaysogsex, og koderne for indlæggelse, udskrivning og årsag tiladmissionPriority,dischargeDispositionogcontactReason. - Læs diagnosefilen. Gruppér rækkerne efter kontaktnummer. Rækken, der er markeret som aktionsdiagnose, bliver til
primaryDiagnosis(hvis den ikke allerede står i kontaktfilen); alle andre kommer isecondaryDiagnoses. - Læs procedurefilen. Gruppér efter kontaktnummer; procedurekoderne kommer i
proceduresog eventuelle tillægskoder isupplementCodes. - Send i batches på op til 500 kontakter og kobl resultaterne tilbage via
id.
Kontrollér tre ting i dine data, før du giver grupperingen skylden:
- Koderne skal være SKS-koderne inklusive det foranstillede bogstav (
DJ189, ikkeJ189), uden punktummer, mellemrum eller små bogstaver. Fjern overskydende mellemrum og skift til store bogstaver først. - Datoer sendes ikke. Beregn selv alder og kontaktlængde (alder ved indlæggelsen, i dage eller år).
- Kodede felter (indlæggelse, udskrivning, årsag, patienttype) skal bruge de koder, som
GET /logics/{id}viser. En tom værdi accepteres og matcher blot ikke regler, der kræver den.
Python-eksemplet nedenfor udfører hele konverteringen og sender batchene. Ret kolonnenavnene i COLUMNS-blokken, så de passer til dine egne filer.
Kodeeksempler
curl — slå op, hvilke logikker din nøgle kan bruge
curl https://heliosgroup.dk/api/v1/logics \
-H "Authorization: Bearer hgk_YOUR_KEY"
curl https://heliosgroup.dk/api/v1/logics/dk-drg-2026 \
-H "Authorization: Bearer hgk_YOUR_KEY"
Python — gruppér et stam-/diag-/proc-udtræk
import csv, json, os, sys, urllib.request
from collections import defaultdict
API = "https://heliosgroup.dk/api/v1"
KEY = os.environ["HELIOS_API_KEY"] # never hard-code the key
LOGIC = "active" # or an id from GET /logics
# ---- adjust to your own files --------------------------------------
COLUMNS = {
"stam": {"id": "kontaktnr", "age": "alder_aar", "sex": "koen",
"admission": "indm", "discharge": "discdisp", "reason": "kontaars",
"primary": "aktionsdiagnose"},
"diag": {"id": "kontaktnr", "code": "diagnose"},
"proc": {"id": "kontaktnr", "code": "procedure"},
}
DELIM, ENC = ";", "utf-8"
# ---------------------------------------------------------------------
def rows(path):
with open(path, newline="", encoding=ENC) as f:
yield from csv.DictReader(f, delimiter=DELIM)
def clean(code):
return (code or "").strip().upper().replace(".", "").replace(" ", "")
def build(stam, diag, proc):
c = COLUMNS
contacts = {}
for r in rows(stam):
cid = r[c["stam"]["id"]]
contacts[cid] = {
"id": cid,
"primaryDiagnosis": clean(r[c["stam"]["primary"]]),
"ageYears": float(r[c["stam"]["age"]] or 0) if r[c["stam"]["age"]] else None,
"sex": r[c["stam"]["sex"]],
"admissionPriority": r[c["stam"]["admission"]],
"dischargeDisposition": r[c["stam"]["discharge"]],
"contactReason": r[c["stam"]["reason"]],
"secondaryDiagnoses": [], "procedures": [],
}
for r in rows(diag):
k = contacts.get(r[c["diag"]["id"]])
code = clean(r[c["diag"]["code"]])
if k and code and code != k["primaryDiagnosis"]:
k["secondaryDiagnoses"].append(code)
for r in rows(proc):
k = contacts.get(r[c["proc"]["id"]])
code = clean(r[c["proc"]["code"]])
if k and code:
k["procedures"].append(code)
return list(contacts.values())
def post(batch):
req = urllib.request.Request(
API + "/group",
data=json.dumps({"logic": LOGIC, "contacts": batch}).encode(),
headers={"Authorization": "Bearer " + KEY, "Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=120) as resp:
return json.load(resp)
if __name__ == "__main__":
stam, diag, proc, out = sys.argv[1:5]
contacts = build(stam, diag, proc)
fields = ["id", "matched", "drgCode", "drgName", "price", "trimPoint", "los", "regel"]
with open(out, "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=fields, delimiter=";", extrasaction="ignore")
w.writeheader()
for i in range(0, len(contacts), 500):
reply = post(contacts[i:i + 500])
for res in reply["results"]:
w.writerow(res)
print("Grouped", len(contacts), "contacts with", reply["logic"]["name"])
Kør det med HELIOS_API_KEY=hgk_… python group.py stam.csv diag.csv proc.csv result.csv.
JavaScript (Node 18+) — én batch
const res = await fetch("https://heliosgroup.dk/api/v1/group", {
method: "POST",
headers: {
"Authorization": "Bearer " + process.env.HELIOS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
contacts: [
{ id: "A-1001", primaryDiagnosis: "DJ189", ageYears: 72, sex: "F" },
],
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error.code + ": " + data.error.message);
for (const r of data.results) console.log(r.id, r.drgCode, r.price);
Fejl
Fejl har altid samme form og en tilsvarende HTTP-status:
{ "error": { "code": "invalid_key", "message": "The API key is not valid." } }
| Status | Kode | Betydning og hvad du skal gøre |
|---|---|---|
| 400 | bad_json, bad_request | Body'en er ikke gyldig JSON, er ikke et objekt, eller contacts er tom eller ikke en liste. |
| 401 | missing_key | Der blev ikke sendt en nøgle. Tilføj Authorization-headeren. |
| 401 | invalid_key | Nøglen er skrevet forkert eller ukendt. Kontrollér for ekstra mellemrum eller linjeskift. |
| 401 | revoked_key | Helios har slået denne nøgle fra. Bed om en ny. |
| 401 | expired_key | Nøglen har overskredet sin udløbsdato. Bed om en ny. |
| 403 | ip_not_allowed | Nøglen er begrænset til bestemte IP-adresser, og denne forespørgsel kom fra en anden. Bed Helios tilføje adressen, eller kald fra din registrerede server. |
| 403 | logic_not_allowed | Din nøgle må ikke bruge den nuværende standardlogik. Angiv en tilladt logik i logic. |
| 404 | logic_not_found | Logik-id'et findes ikke, er endnu ikke godkendt eller er ikke tilladt for din nøgle. Se de tilgængelige med GET /logics. |
| 404 | not_found | Ukendt endpoint. |
| 405 | method_not_allowed | Forkert HTTP-metode (POST for /group, GET for de andre). |
| 409 | no_active_logic | Ingen logik er aktiv i øjeblikket. Angiv en med id, eller prøv senere. |
| 413 | too_many_contacts | Mere end 500 kontakter i én forespørgsel. Del batchen op. |
| 503 | logic_unavailable | Logikkens data er midlertidigt ufuldstændige. Prøv igen om et minut; kontakt Helios, hvis det fortsætter. |
En enkelt fejlbehæftet kontakt får ikke hele forespørgslen til at fejle: den kommer tilbage med matched: false og et error-objekt (invalid_contact, med en besked som sex must be "M" or "F"), mens de øvrige grupperes som normalt. Kontrollér altid hvert enkelt resultat.
Grænser og god praksis
- Op til 500 kontakter pr. forespørgsel og op til 100 koder i hver kodeliste.
- Gruppér store filer i sekventielle batches på nogle få hundrede. Parallelle forespørgsler er i orden med måde; hvis du ser HTTP 5xx- eller 429-svar, så vent nogle sekunder og prøv igen med en pause mellem forsøgene.
- Hver nøgle må sende op til 120 forespørgsler pr. minut. Derover får du HTTP 429 med en
Retry-After-header (sekunder at vente). Send kontakter i batches frem for én forespørgsel pr. kontakt. - Den første forespørgsel efter en stille periode kan tage nogle sekunder, mens logikken indlæses; senere forespørgsler er hurtige.
- Helios gemmer ikke de kontakter, du sender. API'et er beregnet til gruppering, så send kun det, som felterne ovenfor kræver — ingen navne, ingen CPR-numre.
- Når Helios retter en logik, når rettelsen API'et inden for cirka et minut.
- Svarheaderen
X-Helios-Api-Versionfortæller dig API-versionen. Version 1 ændres ikke på en måde, der bryder eksisterende klienter; der kan komme nye felter til, så ignorér felter, du ikke kender.
Status og advarsler
- Den offentlige statusside viser, om grupperings-API'et svarer, og hvor ofte det har gjort det de seneste 90 dage.
GET /api/v1/health(kræver ingen nøgle) er det, den kontrollerer, og du kan bruge den til din egen overvågning. - Hvis dine fejl for en dag bliver usædvanligt mange, eller en nøgle snart udløber, får dine brugere en besked i klokken i kundeportalen og, hvis e-mail er sat op, en e-mail. Se API-brug i portalen for detaljer.
- Til filer, der er for store til at sende som forespørgsler (tusindvis af kontakter), skal du i stedet bruge Massegruppering i Casemix Engine: upload filen, og download resultatet, når det er klar.
Support
Har du brug for en nøgle, en ny nøgle, en ændret grænse eller hjælp til et mapping? Kontakt din Helios-konsulent, eller skriv via kontaktsiden. Oplys, hvilket nøglenavn det drejer sig om — send aldrig selve nøglen.