> ## Documentation Index
> Fetch the complete documentation index at: https://omni.fireflo.au/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /v1/calendar/appointments/{appointment_id}/cancel

> Cancel an upcoming appointment, with an optional note.

Cancels an upcoming appointment — `requested` or `confirmed`. Its time is free again, reminders not yet sent are dropped, and the contact and the teammate are told as when the team cancels it. The change is added to the appointment's history, and `appointment.canceled` is sent.

<Note>Needs the `calendar:write` scope.</Note>

## Path parameters

| Field | Type | Required | Notes |
| :- | :- | :- | :- |
| `appointment_id` | string | Yes | The appointment's id. |

## Body

| Field | Type | Required | Notes |
| :- | :- | :- | :- |
| `note` | string | No | Why — added to the history. Up to 200 characters. |

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.fireflo.au/v1/calendar/appointments/5b0e7d3c-9a2f-4c61-8e47-1f3a6c9d2b84/cancel" \
    -H "Authorization: Bearer $OMNI_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "note": "Ravi will come back after Diwali"
  }'
  ```

  ```python Python theme={null}
  import os

  import requests

  response = requests.post(
      "https://api.fireflo.au/v1/calendar/appointments/5b0e7d3c-9a2f-4c61-8e47-1f3a6c9d2b84/cancel",
      headers={"Authorization": f"Bearer {os.environ['OMNI_API_KEY']}"},
      json={
          "note": "Ravi will come back after Diwali"
      },
  )
  print(response.status_code, response.json())
  ```

  ```javascript Node theme={null}
  const response = await fetch("https://api.fireflo.au/v1/calendar/appointments/5b0e7d3c-9a2f-4c61-8e47-1f3a6c9d2b84/cancel", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.OMNI_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      "note": "Ravi will come back after Diwali"
    }),
  });
  console.log(response.status, await response.json());
  ```
</CodeGroup>

## Response

`200 OK` — the appointment, now `cancelled`.

```json theme={null}
{
  "id": "5b0e7d3c-9a2f-4c61-8e47-1f3a6c9d2b84",
  "title": "Home loan consultation",
  "status": "cancelled",
  "booking_type": {
    "id": 3,
    "name": "Home loan consultation"
  },
  "contact": {
    "id": "3f6b2a1e-8c4d-4e2a-9b7f-5d1c0e8a9f42",
    "name": "Ravi Kumar",
    "phone": "+919876500101"
  },
  "staff": {
    "name": "Priya Sharma",
    "email": "priya@acme.in"
  },
  "starts_at": "2026-10-08T10:30:00+05:30",
  "ends_at": "2026-10-08T11:00:00+05:30",
  "mode": "online",
  "location": "",
  "meeting_link": "https://meet.google.com/kfr-ptqw-xya",
  "notes": "Salaried, looking at a ₹45 lakh loan. Bring Form 16.",
  "source": "api",
  "deal": null,
  "created_at": "2026-10-06T04:12:04.512903+00:00",
  "updated_at": "2026-10-08T05:41:12.630845+00:00"
}
```

## Errors

Every refusal is `{"error": {"code", "message", "field"}}`; `field` is there when one input is at fault.

| Status | Error code | When |
| :- | :- | :- |
| 404 | `not_found` | No appointment of this account's has that id. |
| 409 | `invalid_state` | Only an upcoming appointment can be canceled: this one is completed, canceled or a no-show. |
| 404 | `module_off` | The account's plan doesn't include Calendar. |
| 403 | `scope_missing` | The key doesn't have the `calendar:write` scope. |

Any request can also be refused for its key, its account or its rate (`key_required`, `invalid_key`, `account_suspended`, `plan_excludes_api`, `address_not_allowed`, `rate_limited`); see [the overview](/api-reference/overview).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.