Patient (FHIR R4)

FHIR You're viewing the FHIR R4 reference.

Demographic and administrative information about an individual receiving healthcare services. Maps to HuliPractice patient records including name, birth date, gender, contact information, and identifiers such as CURP.

This reference is generated from the canonical Huli Public API OpenAPI specification and the server's FHIR R4 CapabilityStatement — do not edit it directly.

FHIR R4 Specification

Official spec: Patient — HL7 FHIR R4

Supported Interactions

  • read — Read a single resource by ID (GET /fhir/R4/{Resource}/{id})
  • search-type — Search resources with query parameters (GET /fhir/R4/{Resource}?...)
  • create — Create a new resource (POST /fhir/R4/{Resource})
  • update — Update an existing resource (PUT /fhir/R4/{Resource}/{id})
  • $everything — operation

Scopes

Scopes are shared across FHIR releases — the same system/Patient.* scope grants Patient access on both /fhir/R4 and /fhir/R5.

Search Parameters

ParameterTypeNotes
_idtokenExact match. For identifiers use `system
identifiertokenExact match. For identifiers use `system
namestringCase-insensitive partial match.
gendertokenExact match. For identifiers use `system
birthdatedateSupports FHIR date prefixes: eq, ne, gt, ge, lt, le. Format: [prefix]YYYY-MM-DD.
activetokenExact match. For identifiers use `system
_countnumberInteger. For _count: default 20, max 100.
_cursorstringCase-insensitive partial match.

Endpoints

Read Patient

Retrieve a single Patient resource by its ID.

GET/fhir/R4/Patient/{id}

Required scope: system/Patient.rs

Response — 200

{
  "resourceType": "Patient",
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "meta": {
    "lastUpdated": "2026-01-15T10:30:00Z"
  },
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Garcia",
      "given": [
        "Maria"
      ]
    }
  ],
  "gender": "female",
  "birthDate": "1990-03-15",
  "telecom": [
    {
      "system": "phone",
      "value": "+52-555-0100",
      "use": "mobile"
    },
    {
      "system": "email",
      "value": "maria.garcia@example.com"
    }
  ],
  "address": [
    {
      "use": "home",
      "line": [
        "Av. Reforma 222"
      ],
      "city": "Ciudad de Mexico",
      "state": "CDMX",
      "postalCode": "06600",
      "country": "MX"
    }
  ],
  "identifier": [
    {
      "system": "https://huli.ai/identifiers/curp",
      "value": "GARM900315MDFRRL09"
    }
  ]
}

Code Samples

TOKEN=$(curl -s -X POST https://api.huli.ai/auth/token \
  -d "grant_type=client_credentials" \
  -d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
  -d "client_assertion=${CLIENT_ASSERTION}" \
  -d "scope=system/Patient.rs" \
  | jq -r .access_token)

curl -X GET https://api.huli.ai/fhir/R4/Patient/${RESOURCE_ID} \
  -H "Authorization: Bearer ${TOKEN}"
const token = process.env.HULI_ACCESS_TOKEN ?? "";

const response = await fetch(
  `https://api.huli.ai/fhir/R4/Patient/${id}`,
  {
    method: "GET",
    headers: {
      "Authorization": `Bearer ${token}`,
    },

  }
);

if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
const data: unknown = await response.json();
import os
import requests

token = os.environ["HULI_ACCESS_TOKEN"]
headers = {"Authorization": f"Bearer {token}"}

resp = requests.get(
    f"https://api.huli.ai/fhir/R4/Patient/{resource_id}",
    headers=headers,
)
resp.raise_for_status()
print(resp.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class getPatientExample {
    public static void main(String[] args) throws Exception {
        String token = System.getenv("HULI_ACCESS_TOKEN");
        String resourceId = "RESOURCE_ID";

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.huli.ai/fhir/R4/Patient/" + resourceId))
        .header("Authorization", "Bearer " + token)
        .header("Accept", "application/fhir+json")
        .method("GET", HttpRequest.BodyPublishers.noBody())
        .build();

        HttpResponse<String> response =
        client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("status: " + response.statusCode());
        System.out.println(response.body());
    }
}
import (
    "fmt"
    "net/http"
    "os"
)

func getPatientExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("GET", "https://api.huli.ai/fhir/R4/Patient/"+resourceID+"", nil)
    req.Header.Set("Authorization", "Bearer "+token)

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    fmt.Println("status:", resp.Status)
}

Errors

CodeStatusDescription
HPB-00106401Authentication failed
HPB-00104403Insufficient scope
HPB-00102404Resource not found
HPB-00105429Rate limit exceeded

Update Patient

Update an existing Patient resource. The request body must include resourceType: "Patient". Deceased patients cannot be updated (returns 422).

PUT/fhir/R4/Patient/{id}

Required scope: system/Patient.cru

Request Body

nametyperequireddescription
resourceTypestringrequired
idstring(uuid)optionalServer-assigned resource ID. Do not include on create.
metaobjectoptional
activebooleanoptionalWhether this patient record is active.
namearrayoptional
genderstringoptionalAdministrative gender.
birthDatestring(date)optionalDate of birth (YYYY-MM-DD).
deceasedBooleanbooleanoptionalWhether the patient is deceased.
telecomarrayoptional
addressarrayoptional
maritalStatusobjectoptional
contactarrayoptionalEmergency contacts or next of kin.
identifierarrayoptional
extensionarrayoptionalFHIR extensions, rooted at the IG canonical base (`https://fhir.huli.ai/r4` on R4 operations, `https://fhir.huli.ai/r5` on R5 operations). Huli supports: - `second-lastname` (second/maternal surname) - `huli-blood-type` - `huli-private-insurance`

Request Example

{
  "resourceType": "Patient",
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Garcia Lopez",
      "given": [
        "Maria"
      ]
    }
  ],
  "gender": "female",
  "birthDate": "1990-03-15",
  "telecom": [
    {
      "system": "phone",
      "value": "+52-555-0101",
      "use": "mobile"
    }
  ]
}

Code Samples

TOKEN=$(curl -s -X POST https://api.huli.ai/auth/token \
  -d "grant_type=client_credentials" \
  -d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
  -d "client_assertion=${CLIENT_ASSERTION}" \
  -d "scope=system/Patient.cru" \
  | jq -r .access_token)

curl -X PUT https://api.huli.ai/fhir/R4/Patient/${RESOURCE_ID} \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/fhir+json" \
  -d @resource.json
const token = process.env.HULI_ACCESS_TOKEN ?? "";

const response = await fetch(
  `https://api.huli.ai/fhir/R4/Patient/${id}`,
  {
    method: "PUT",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/fhir+json",
    },
    body: JSON.stringify(payload),
  }
);

if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
const data: unknown = await response.json();
import os
import requests

token = os.environ["HULI_ACCESS_TOKEN"]
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/fhir+json"}

resp = requests.put(
    f"https://api.huli.ai/fhir/R4/Patient/{resource_id}",
    headers=headers,
    json=payload,
)
resp.raise_for_status()
print(resp.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class updatePatientExample {
    public static void main(String[] args) throws Exception {
        String token = System.getenv("HULI_ACCESS_TOKEN");
        String resourceId = "RESOURCE_ID";
        String payload = "{}"; // your serialized FHIR resource

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.huli.ai/fhir/R4/Patient/" + resourceId))
        .header("Authorization", "Bearer " + token)
        .header("Accept", "application/fhir+json")
        .header("Content-Type", "application/fhir+json")
        .method("PUT", HttpRequest.BodyPublishers.ofString(payload))
        .build();

        HttpResponse<String> response =
        client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("status: " + response.statusCode());
        System.out.println(response.body());
    }
}
import (
    "fmt"
    "net/http"
    "os"
)

func updatePatientExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("PUT", "https://api.huli.ai/fhir/R4/Patient/"+resourceID+"", body)
    req.Header.Set("Authorization", "Bearer "+token)
    req.Header.Set("Content-Type", "application/fhir+json")
    // set req.Body to your serialized resource
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    fmt.Println("status:", resp.Status)
}

Errors

CodeStatusDescription
HPB-00101400Validation error
HPB-00106401Authentication failed
HPB-00104403Insufficient scope
HPB-00102404Resource not found
HPB-00101422Unprocessable entity
HPB-00105429Rate limit exceeded

Patient $everything

Aggregate a patient's clinical record across Patient, Encounter, Observation, Composition, DocumentReference, MedicationRequest, and ServiceRequest into a single searchset Bundle. Each additional resource type is included only when the access token's SMART scopes grant read on it; withheld types are listed in an information OperationOutcome and signalled via a scope-filtered meta.tag. Optional start/end bound the date range; _count caps each per-type page; _type restricts the included resource types. Baseline scope: system/Patient.r.

GET/fhir/R4/Patient/{id}/$everything

Required scope: system/Patient.r

Query Parameters

nametyperequireddescription
startstringoptionalInclusive lower date bound (YYYY-MM-DD).
endstringoptionalInclusive upper date bound (YYYY-MM-DD).
_typestringoptionalComma-separated list of resource types to include.
_countintegeroptionalNumber of results per page (default: 20, max: 100).

Code Samples

TOKEN=$(curl -s -X POST https://api.huli.ai/auth/token \
  -d "grant_type=client_credentials" \
  -d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
  -d "client_assertion=${CLIENT_ASSERTION}" \
  -d "scope=system/Patient.r" \
  | jq -r .access_token)

curl -X GET https://api.huli.ai/fhir/R4/Patient/${RESOURCE_ID}/$everything \
  -H "Authorization: Bearer ${TOKEN}"
const token = process.env.HULI_ACCESS_TOKEN ?? "";

const response = await fetch(
  `https://api.huli.ai/fhir/R4/Patient/${id}/$everything`,
  {
    method: "GET",
    headers: {
      "Authorization": `Bearer ${token}`,
    },

  }
);

if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
const data: unknown = await response.json();
import os
import requests

token = os.environ["HULI_ACCESS_TOKEN"]
headers = {"Authorization": f"Bearer {token}"}

resp = requests.get(
    f"https://api.huli.ai/fhir/R4/Patient/{resource_id}/$everything",
    headers=headers,
)
resp.raise_for_status()
print(resp.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class patientEverythingExample {
    public static void main(String[] args) throws Exception {
        String token = System.getenv("HULI_ACCESS_TOKEN");
        String resourceId = "RESOURCE_ID";

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.huli.ai/fhir/R4/Patient/" + resourceId + "/$everything"))
        .header("Authorization", "Bearer " + token)
        .header("Accept", "application/fhir+json")
        .method("GET", HttpRequest.BodyPublishers.noBody())
        .build();

        HttpResponse<String> response =
        client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("status: " + response.statusCode());
        System.out.println(response.body());
    }
}
import (
    "fmt"
    "net/http"
    "os"
)

func patientEverythingExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("GET", "https://api.huli.ai/fhir/R4/Patient/"+resourceID+"/$everything", nil)
    req.Header.Set("Authorization", "Bearer "+token)

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    fmt.Println("status:", resp.Status)
}

Errors

CodeStatusDescription
HPB-00106401Authentication failed
HPB-00104403Insufficient scope
HPB-00102404Resource not found
HPB-00105429Rate limit exceeded

Search Patients

Search for Patient resources using FHIR search parameters. Results are returned as a FHIR Bundle with cursor-based pagination.

GET/fhir/R4/Patient

Required scope: system/Patient.rs

Query Parameters

nametyperequireddescription
namestringoptionalPatient name (case-insensitive partial match).
genderstringoptionalAdministrative gender. Values: `male`, `female`, `other`, `unknown`.
birthdatestringoptionalDate of birth. Supports FHIR date prefixes: `eq`, `ne`, `gt`, `ge`, `lt`, `le`. Format: `[prefix]YYYY-MM-DD`.
identifierstringoptionalPatient identifier in `system|value` format.
activestringoptionalWhether the patient record is active.
_idstringoptionalPatient resource ID (UUID).
_countintegeroptionalNumber of results per page (default: 20, max: 100).
_cursorstringoptionalOpaque pagination cursor from the `next` link of a previous search result.

Response — 200

{
  "resourceType": "Bundle",
  "type": "searchset",
  "total": 2,
  "link": [
    {
      "relation": "self",
      "url": "https://api.huli.ai/fhir/R4/Patient?name=Garcia&_count=20"
    },
    {
      "relation": "next",
      "url": "https://api.huli.ai/fhir/R4/Patient?name=Garcia&_count=20&_cursor=eyJ0IjoiMjAyNi0wMS0xNVQxMDozMDowMFoiLCJpIjoiNTUwZTg0MDAtZTI5Yi00MWQ0LWE3MTYtNDQ2NjU1NDQwMDAxIn0"
    }
  ],
  "entry": [
    {
      "fullUrl": "Patient/550e8400-e29b-41d4-a716-446655440001",
      "resource": {
        "resourceType": "Patient",
        "id": "550e8400-e29b-41d4-a716-446655440001",
        "active": true,
        "name": [
          {
            "use": "official",
            "family": "Garcia",
            "given": [
              "Maria"
            ]
          }
        ],
        "gender": "female",
        "birthDate": "1990-03-15"
      },
      "search": {
        "mode": "match"
      }
    }
  ]
}

Code Samples

TOKEN=$(curl -s -X POST https://api.huli.ai/auth/token \
  -d "grant_type=client_credentials" \
  -d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
  -d "client_assertion=${CLIENT_ASSERTION}" \
  -d "scope=system/Patient.rs" \
  | jq -r .access_token)

curl -X GET https://api.huli.ai/fhir/R4/Patient \
  -H "Authorization: Bearer ${TOKEN}"
const token = process.env.HULI_ACCESS_TOKEN ?? "";

const response = await fetch(
  `https://api.huli.ai/fhir/R4/Patient`,
  {
    method: "GET",
    headers: {
      "Authorization": `Bearer ${token}`,
    },

  }
);

if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
const data: unknown = await response.json();
import os
import requests

token = os.environ["HULI_ACCESS_TOKEN"]
headers = {"Authorization": f"Bearer {token}"}

resp = requests.get(
    f"https://api.huli.ai/fhir/R4/Patient",
    headers=headers,
)
resp.raise_for_status()
print(resp.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class searchPatientsExample {
    public static void main(String[] args) throws Exception {
        String token = System.getenv("HULI_ACCESS_TOKEN");

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.huli.ai/fhir/R4/Patient"))
        .header("Authorization", "Bearer " + token)
        .header("Accept", "application/fhir+json")
        .method("GET", HttpRequest.BodyPublishers.noBody())
        .build();

        HttpResponse<String> response =
        client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("status: " + response.statusCode());
        System.out.println(response.body());
    }
}
import (
    "fmt"
    "net/http"
    "os"
)

func searchPatientsExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("GET", "https://api.huli.ai/fhir/R4/Patient", nil)
    req.Header.Set("Authorization", "Bearer "+token)

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    fmt.Println("status:", resp.Status)
}

Errors

CodeStatusDescription
HPB-00106401Authentication failed
HPB-00104403Insufficient scope
HPB-00105429Rate limit exceeded

Create Patient

Create a new Patient resource. The server assigns the resource ID; do not include id in the request body.

POST/fhir/R4/Patient

Required scope: system/Patient.cru

Request Body

nametyperequireddescription
resourceTypestringrequired
idstring(uuid)optionalServer-assigned resource ID. Do not include on create.
metaobjectoptional
activebooleanoptionalWhether this patient record is active.
namearrayoptional
genderstringoptionalAdministrative gender.
birthDatestring(date)optionalDate of birth (YYYY-MM-DD).
deceasedBooleanbooleanoptionalWhether the patient is deceased.
telecomarrayoptional
addressarrayoptional
maritalStatusobjectoptional
contactarrayoptionalEmergency contacts or next of kin.
identifierarrayoptional
extensionarrayoptionalFHIR extensions, rooted at the IG canonical base (`https://fhir.huli.ai/r4` on R4 operations, `https://fhir.huli.ai/r5` on R5 operations). Huli supports: - `second-lastname` (second/maternal surname) - `huli-blood-type` - `huli-private-insurance`

Request Example

{
  "resourceType": "Patient",
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Hernandez",
      "given": [
        "Carlos"
      ]
    }
  ],
  "gender": "male",
  "birthDate": "1985-07-20",
  "telecom": [
    {
      "system": "phone",
      "value": "+52-555-0200",
      "use": "mobile"
    },
    {
      "system": "email",
      "value": "carlos.hernandez@example.com"
    }
  ],
  "address": [
    {
      "use": "home",
      "line": [
        "Calle Madero 50"
      ],
      "city": "Guadalajara",
      "state": "Jalisco",
      "postalCode": "44100",
      "country": "MX"
    }
  ]
}

Code Samples

TOKEN=$(curl -s -X POST https://api.huli.ai/auth/token \
  -d "grant_type=client_credentials" \
  -d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
  -d "client_assertion=${CLIENT_ASSERTION}" \
  -d "scope=system/Patient.cru" \
  | jq -r .access_token)

curl -X POST https://api.huli.ai/fhir/R4/Patient \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/fhir+json" \
  -d @patient.json
const token = process.env.HULI_ACCESS_TOKEN ?? "";

const response = await fetch(
  `https://api.huli.ai/fhir/R4/Patient`,
  {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/fhir+json",
    },
    body: JSON.stringify(payload),
  }
);

if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
const data: unknown = await response.json();
import os
import requests

token = os.environ["HULI_ACCESS_TOKEN"]
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/fhir+json"}

resp = requests.post(
    f"https://api.huli.ai/fhir/R4/Patient",
    headers=headers,
    json=payload,
)
resp.raise_for_status()
print(resp.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class createPatientExample {
    public static void main(String[] args) throws Exception {
        String token = System.getenv("HULI_ACCESS_TOKEN");
        String payload = "{}"; // your serialized FHIR resource

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.huli.ai/fhir/R4/Patient"))
        .header("Authorization", "Bearer " + token)
        .header("Accept", "application/fhir+json")
        .header("Content-Type", "application/fhir+json")
        .method("POST", HttpRequest.BodyPublishers.ofString(payload))
        .build();

        HttpResponse<String> response =
        client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("status: " + response.statusCode());
        System.out.println(response.body());
    }
}
import (
    "fmt"
    "net/http"
    "os"
)

func createPatientExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("POST", "https://api.huli.ai/fhir/R4/Patient", body)
    req.Header.Set("Authorization", "Bearer "+token)
    req.Header.Set("Content-Type", "application/fhir+json")
    // set req.Body to your serialized resource
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    fmt.Println("status:", resp.Status)
}

Errors

CodeStatusDescription
HPB-00101400Validation error
HPB-00106401Authentication failed
HPB-00104403Insufficient scope
HPB-00101422Unprocessable entity
HPB-00105429Rate limit exceeded