---
title: 'Appointment (FHIR R4)'
description: 'A booking of a healthcare event between patient(s) and practitioner(s) for a specific date/time. Maps to HuliPractice ap'
nav: 'API / R4 / Appointment'
order: 40
version: v1
fhir: r4
source: generated
updated: '2026-09-23'
---

# Appointment (FHIR R4)

<FhirResourceHeader fhir="r4" slug="appointment" />

A booking of a healthcare event between patient(s) and practitioner(s) for a specific date/time. Maps to HuliPractice appointment slots with start/end times, status, and participant references.

> 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: [Appointment — HL7 FHIR R4](https://hl7.org/fhir/R4/appointment.html)

## 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}`)

## Scopes

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

- <Scope name="system/Appointment.rs" /> — see [scope reference](/v1/scopes#system-appointment-rs)
- <Scope name="system/Appointment.cru" /> — see [scope reference](/v1/scopes#system-appointment-cru)

## Search Parameters

| Parameter | Type | Notes |
|-----------|------|-------|
| `_id` | token | Exact match. For identifiers use `system|value` format. |
| `patient` | reference | Resource reference — supply the UUID of the referenced resource. |
| `practitioner` | reference | Resource reference — supply the UUID of the referenced resource. |
| `date` | date | Supports FHIR date prefixes: `eq`, `ne`, `gt`, `ge`, `lt`, `le`. Format: `[prefix]YYYY-MM-DD`. |
| `status` | token | Exact match. For identifiers use `system|value` format. |
| `appointment-type` | token | Exact match. For identifiers use `system|value` format. |
| `_count` | number | Integer. For `_count`: default 20, max 100. |
| `_cursor` | string | Case-insensitive partial match. |

## Endpoints

### Read Appointment

Retrieve a single Appointment resource by its ID.

<Endpoint method="GET" path="/fhir/R4/Appointment/{id}" />

**Required scope:** <Scope name="system/Appointment.rs" />

#### Response — 200

```json
{
  "resourceType": "Appointment",
  "id": "770e8400-e29b-41d4-a716-446655440010",
  "status": "booked",
  "start": "2026-06-01T09:00:00Z",
  "end": "2026-06-01T09:30:00Z",
  "participant": [
    {
      "actor": {
        "reference": "Patient/550e8400-e29b-41d4-a716-446655440001",
        "display": "Maria Garcia"
      },
      "status": "accepted"
    },
    {
      "actor": {
        "reference": "Practitioner/880e8400-e29b-41d4-a716-446655440020",
        "display": "Dr. Rodriguez"
      },
      "status": "accepted"
    }
  ]
}
```

#### Code Samples

:::CodeGroup

```bash {label="cURL"}
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/Appointment.rs" \
  | jq -r .access_token)

curl -X GET https://api.huli.ai/fhir/R4/Appointment/${RESOURCE_ID} \
  -H "Authorization: Bearer ${TOKEN}"
```

```typescript {label="TypeScript"}
const token = process.env.HULI_ACCESS_TOKEN ?? "";

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

  }
);

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

```python {label="Python"}
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/Appointment/{resource_id}",
    headers=headers,
)
resp.raise_for_status()
print(resp.json())
```

```java {label="Java"}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class getAppointmentExample {
    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/Appointment/" + 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());
    }
}
```

```go {label="Go"}
import (
    "fmt"
    "net/http"
    "os"
)

func getAppointmentExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("GET", "https://api.huli.ai/fhir/R4/Appointment/"+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

| Code | Status | Description |
|------|--------|-------------|
| [HPB-00106](/v1/errors#hpb-00106) | 401 | Authentication failed |
| [HPB-00104](/v1/errors#hpb-00104) | 403 | Insufficient scope |
| [HPB-00102](/v1/errors#hpb-00102) | 404 | Resource not found |
| [HPB-00105](/v1/errors#hpb-00105) | 429 | Rate limit exceeded |

---

### Update Appointment

Update an existing Appointment. The target `status` drives the operation:
- **`status: cancelled`** → cancels the appointment. Requires the
  `appointments.delete` permission and a `cancelationReason` that resolves
  to one of the organization's active cancellation reasons (matched by the
  coding `code` or a SNOMED coding). The cancel is **blocked (`409`)** when
  a clinical encounter is linked to the appointment, and rejected (`422`)
  when the reason is missing or unresolvable. `comment` maps to the
  cancellation note.
- **`status: entered-in-error`** → marks the appointment as a data-entry
  error (a correction, not a cancellation). Requires the
  `appointments.edit` permission; no cancellation reason is needed.
- **any other change** (reschedule / field edit) → re-runs the
  double-booking / availability / calendar-scope checks; an overlapping
  slot is rejected with `409`. Requires `appointments.edit`. A field edit
  carries the full appointment shape (`start`, `end`, participants,
  `serviceType`).
Supports optimistic concurrency: supply the `If-Match` header with the
`ETag` from the last read to make the update conditional. A stale
validator is rejected with a `409` version conflict (distinct from the
double-booking `409`, though both carry HPB-00103). The response carries
`ETag` + `Last-Modified` for the new version.

<Endpoint method="PUT" path="/fhir/R4/Appointment/{id}" />

**Required scope:** <Scope name="system/Appointment.cru" />

#### Request Body

<ParamTable :rows='[{&quot;name&quot;:&quot;resourceType&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:true,&quot;description&quot;:&quot;&quot;},{&quot;name&quot;:&quot;id&quot;,&quot;type&quot;:&quot;string(uuid)&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;&quot;},{&quot;name&quot;:&quot;meta&quot;,&quot;type&quot;:&quot;object&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;&quot;},{&quot;name&quot;:&quot;status&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:true,&quot;description&quot;:&quot;Appointment status. On create the appointment is always booked. A\nPUT with `cancelled` cancels (requires a resolvable\n`cancelationReason`); `entered-in-error` marks a data-entry error.\n&quot;},{&quot;name&quot;:&quot;serviceType&quot;,&quot;type&quot;:&quot;array&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;The organization service the appointment is booked for. **Required on\nwrite.** `serviceType[0].coding[0]` must use the\n`https://fhir.huli.ai/r4/CodeSystem/org-service` system with the Huli\nservice UUID as the `code`.\n&quot;},{&quot;name&quot;:&quot;cancelationReason&quot;,&quot;type&quot;:&quot;object&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Reason an appointment was cancelled. Required when `status` is\n`cancelled`; resolved against the organization&#39;s active cancellation\nreasons by coding `code` or SNOMED coding.\n&quot;},{&quot;name&quot;:&quot;start&quot;,&quot;type&quot;:&quot;string(date-time)&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Start time (RFC 3339).&quot;},{&quot;name&quot;:&quot;end&quot;,&quot;type&quot;:&quot;string(date-time)&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;End time (RFC 3339).&quot;},{&quot;name&quot;:&quot;priority&quot;,&quot;type&quot;:&quot;integer&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Priority (0 = routine).&quot;},{&quot;name&quot;:&quot;description&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Description or reason for the appointment.&quot;},{&quot;name&quot;:&quot;patientInstruction&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Detailed instructions for the patient.&quot;},{&quot;name&quot;:&quot;comment&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Additional comments. On cancel this carries the cancellation note.\n&quot;},{&quot;name&quot;:&quot;participant&quot;,&quot;type&quot;:&quot;array&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Appointment participants. The patient is a `Patient` actor;\npractitioners are `Practitioner` actors; the room is a `Location`\nactor; equipment are `Device` actors. On write, at least one\n`Practitioner` and one `Location` (room) participant are required.\n&quot;}]' />

#### Request Example

```json
{
  "resourceType": "Appointment",
  "status": "cancelled",
  "cancelationReason": {
    "coding": [
      {
        "system": "http://snomed.info/sct",
        "code": "185332005"
      }
    ],
    "text": "Patient request"
  },
  "comment": "Patient called to cancel"
}
```

#### Code Samples

:::CodeGroup

```bash {label="cURL"}
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/Appointment.cru" \
  | jq -r .access_token)

curl -X PUT https://api.huli.ai/fhir/R4/Appointment/${RESOURCE_ID} \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/fhir+json" \
  -d @resource.json
```

```typescript {label="TypeScript"}
const token = process.env.HULI_ACCESS_TOKEN ?? "";

const response = await fetch(
  `https://api.huli.ai/fhir/R4/Appointment/${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();
```

```python {label="Python"}
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/Appointment/{resource_id}",
    headers=headers,
    json=payload,
)
resp.raise_for_status()
print(resp.json())
```

```java {label="Java"}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class updateAppointmentExample {
    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/Appointment/" + 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());
    }
}
```

```go {label="Go"}
import (
    "fmt"
    "net/http"
    "os"
)

func updateAppointmentExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("PUT", "https://api.huli.ai/fhir/R4/Appointment/"+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

| Code | Status | Description |
|------|--------|-------------|
| [HPB-00101](/v1/errors#hpb-00101) | 400 | Validation error |
| [HPB-00106](/v1/errors#hpb-00106) | 401 | Authentication failed |
| [HPB-00104](/v1/errors#hpb-00104) | 403 | Insufficient scope |
| [HPB-00102](/v1/errors#hpb-00102) | 404 | Resource not found |
| [HPB-00103](/v1/errors#hpb-00103) | 409 | Version conflict |
| [HPB-00101](/v1/errors#hpb-00101) | 422 | Unprocessable entity |
| [HPB-00105](/v1/errors#hpb-00105) | 429 | Rate limit exceeded |

---

### Search Appointments

Search for Appointment resources using FHIR search parameters.

<Endpoint method="GET" path="/fhir/R4/Appointment" />

**Required scope:** <Scope name="system/Appointment.rs" />

#### Query Parameters

<ParamTable :rows='[{&quot;name&quot;:&quot;patient&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Patient reference (UUID).&quot;},{&quot;name&quot;:&quot;practitioner&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Practitioner reference (UUID).&quot;},{&quot;name&quot;:&quot;date&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Appointment date. Supports FHIR date prefixes: `eq`, `ne`, `gt`, `ge`, `lt`, `le`.\n\nRecommended for paginated reads: the appointment store is range-partitioned\nby start time, so supplying `date` lets the query prune to the relevant\npartitions. A date-less search must merge across every partition, which\ngets more expensive as the rolling partition window grows.\n&quot;},{&quot;name&quot;:&quot;status&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Appointment status: `proposed`, `booked`, `arrived`, `fulfilled`, `cancelled`, `noshow`.&quot;},{&quot;name&quot;:&quot;_count&quot;,&quot;type&quot;:&quot;integer&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Number of results per page (default: 20, max: 100).&quot;},{&quot;name&quot;:&quot;_cursor&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Opaque pagination cursor from the `next` link of a previous search result.&quot;}]' />

#### Code Samples

:::CodeGroup

```bash {label="cURL"}
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/Appointment.rs" \
  | jq -r .access_token)

curl -X GET https://api.huli.ai/fhir/R4/Appointment \
  -H "Authorization: Bearer ${TOKEN}"
```

```typescript {label="TypeScript"}
const token = process.env.HULI_ACCESS_TOKEN ?? "";

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

  }
);

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

```python {label="Python"}
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/Appointment",
    headers=headers,
)
resp.raise_for_status()
print(resp.json())
```

```java {label="Java"}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class searchAppointmentsExample {
    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/Appointment"))
        .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());
    }
}
```

```go {label="Go"}
import (
    "fmt"
    "net/http"
    "os"
)

func searchAppointmentsExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("GET", "https://api.huli.ai/fhir/R4/Appointment", 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

| Code | Status | Description |
|------|--------|-------------|
| [HPB-00106](/v1/errors#hpb-00106) | 401 | Authentication failed |
| [HPB-00104](/v1/errors#hpb-00104) | 403 | Insufficient scope |
| [HPB-00105](/v1/errors#hpb-00105) | 429 | Rate limit exceeded |

---

### Create Appointment

Create a new Appointment resource. The server assigns the resource ID and
always books the appointment in the `booked` state.
The create runs the full scheduling rule set, so the request body must
name the resources an appointment requires:
- **`serviceType`** (required) — `serviceType[0].coding[0]` must reference
  a Huli organization service via the
  `https://fhir.huli.ai/r4/CodeSystem/org-service` code system, with the
  service UUID as the `code`. The service drives appointment type,
  specialty, booking policy, and the per-service resource requirements.
  A missing or unresolvable `serviceType` is rejected (`400`) — it is a
  structural-validation failure (all of which return `400`; `422` is
  reserved for business-rule rejections).
- **At least one Practitioner participant** and **one Location (room)
  participant** — appointments are unschedulable without them. Equipment
  is supplied as `Device` participants.
The server runs double-booking / availability / calendar-scope checks: a
time slot that overlaps an existing booking for any participant is
rejected with `409`. Telehealth services auto-provision a telemedicine
session. Requires the `appointments.create` permission in addition to the
`system/Appointment.cru` scope.

<Endpoint method="POST" path="/fhir/R4/Appointment" />

**Required scope:** <Scope name="system/Appointment.cru" />

#### Request Body

<ParamTable :rows='[{&quot;name&quot;:&quot;resourceType&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:true,&quot;description&quot;:&quot;&quot;},{&quot;name&quot;:&quot;id&quot;,&quot;type&quot;:&quot;string(uuid)&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;&quot;},{&quot;name&quot;:&quot;meta&quot;,&quot;type&quot;:&quot;object&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;&quot;},{&quot;name&quot;:&quot;status&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:true,&quot;description&quot;:&quot;Appointment status. On create the appointment is always booked. A\nPUT with `cancelled` cancels (requires a resolvable\n`cancelationReason`); `entered-in-error` marks a data-entry error.\n&quot;},{&quot;name&quot;:&quot;serviceType&quot;,&quot;type&quot;:&quot;array&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;The organization service the appointment is booked for. **Required on\nwrite.** `serviceType[0].coding[0]` must use the\n`https://fhir.huli.ai/r4/CodeSystem/org-service` system with the Huli\nservice UUID as the `code`.\n&quot;},{&quot;name&quot;:&quot;cancelationReason&quot;,&quot;type&quot;:&quot;object&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Reason an appointment was cancelled. Required when `status` is\n`cancelled`; resolved against the organization&#39;s active cancellation\nreasons by coding `code` or SNOMED coding.\n&quot;},{&quot;name&quot;:&quot;start&quot;,&quot;type&quot;:&quot;string(date-time)&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Start time (RFC 3339).&quot;},{&quot;name&quot;:&quot;end&quot;,&quot;type&quot;:&quot;string(date-time)&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;End time (RFC 3339).&quot;},{&quot;name&quot;:&quot;priority&quot;,&quot;type&quot;:&quot;integer&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Priority (0 = routine).&quot;},{&quot;name&quot;:&quot;description&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Description or reason for the appointment.&quot;},{&quot;name&quot;:&quot;patientInstruction&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Detailed instructions for the patient.&quot;},{&quot;name&quot;:&quot;comment&quot;,&quot;type&quot;:&quot;string&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Additional comments. On cancel this carries the cancellation note.\n&quot;},{&quot;name&quot;:&quot;participant&quot;,&quot;type&quot;:&quot;array&quot;,&quot;required&quot;:false,&quot;description&quot;:&quot;Appointment participants. The patient is a `Patient` actor;\npractitioners are `Practitioner` actors; the room is a `Location`\nactor; equipment are `Device` actors. On write, at least one\n`Practitioner` and one `Location` (room) participant are required.\n&quot;}]' />

#### Request Example

```json
{
  "resourceType": "Appointment",
  "status": "booked",
  "start": "2026-06-15T14:00:00Z",
  "end": "2026-06-15T14:30:00Z",
  "serviceType": [
    {
      "coding": [
        {
          "system": "https://fhir.huli.ai/r4/CodeSystem/org-service",
          "code": "990e8400-e29b-41d4-a716-446655440030"
        }
      ]
    }
  ],
  "participant": [
    {
      "actor": {
        "reference": "Patient/550e8400-e29b-41d4-a716-446655440001"
      },
      "status": "accepted"
    },
    {
      "actor": {
        "reference": "Practitioner/880e8400-e29b-41d4-a716-446655440020"
      },
      "status": "accepted"
    },
    {
      "actor": {
        "reference": "Location/aa0e8400-e29b-41d4-a716-446655440040"
      },
      "status": "accepted"
    }
  ]
}
```

#### Code Samples

:::CodeGroup

```bash {label="cURL"}
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/Appointment.cru" \
  | jq -r .access_token)

curl -X POST https://api.huli.ai/fhir/R4/Appointment \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/fhir+json" \
  -d @appointment.json
```

```typescript {label="TypeScript"}
const token = process.env.HULI_ACCESS_TOKEN ?? "";

const response = await fetch(
  `https://api.huli.ai/fhir/R4/Appointment`,
  {
    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();
```

```python {label="Python"}
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/Appointment",
    headers=headers,
    json=payload,
)
resp.raise_for_status()
print(resp.json())
```

```java {label="Java"}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class createAppointmentExample {
    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/Appointment"))
        .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());
    }
}
```

```go {label="Go"}
import (
    "fmt"
    "net/http"
    "os"
)

func createAppointmentExample() {
    token := os.Getenv("HULI_ACCESS_TOKEN")
    req, _ := http.NewRequest("POST", "https://api.huli.ai/fhir/R4/Appointment", 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

| Code | Status | Description |
|------|--------|-------------|
| [HPB-00101](/v1/errors#hpb-00101) | 400 | Validation error |
| [HPB-00106](/v1/errors#hpb-00106) | 401 | Authentication failed |
| [HPB-00104](/v1/errors#hpb-00104) | 403 | Insufficient scope |
| [HPB-00103](/v1/errors#hpb-00103) | 409 | Version conflict |
| [HPB-00101](/v1/errors#hpb-00101) | 422 | Unprocessable entity |
| [HPB-00105](/v1/errors#hpb-00105) | 429 | Rate limit exceeded |

---
