Opami developersAPI v1.0.0

Custom calendar

A custom app can offer the Calendar capability. Unlike actions, a calendar does not accept any shape: Opami defines eight operations and one event format, and you choose the URLs. In Opami, enter a method and an HTTPS URL template for each operation, on the host registered for the app. The templates take placeholders, filled URL-encoded at call time:

OperationPlaceholdersMethodsNeeded for
calendars.listnoneGETread
freebusy.querynonePOSTread
events.list{calendar_id} {from} {to}GETread
events.get{calendar_id} {event_id}GETread
events.create{calendar_id}POST, PUTwrite
events.update{calendar_id} {event_id}PATCH, PUT, POSTwrite
events.cancel{calendar_id} {event_id}POST, DELETE, PATCHwrite
events.respond{calendar_id} {event_id}POST, PUT, PATCHoptional

Each URL must contain exactly its placeholders, each once, in the path or query (never the host). Opami calls them through its locked-down executor with the app's credential; see Rules for your endpoints.

The event format

Every event is exchanged in this format. Fields outside it are ignored. start and end carry a time zone offset. updated_at must change with every change: Opami uses it to detect a stale copy.

{
  "id": "evt_123",
  "calendar_id": "team",
  "title": "Call with Ana",
  "start": "2026-11-03T14:00:00+01:00",
  "end": "2026-11-03T14:30:00+01:00",
  "all_day": false,
  "status": "confirmed",
  "attendees": [
    {
      "email": "ana@example.com",
      "name": "Ana Silva",
      "response": "accepted"
    }
  ],
  "location": null,
  "description": null,
  "updated_at": "2026-10-27T09:12:44Z"
}

Free/busy answers busy intervals only:

{ "calendars": { "team": [{ "start": "2026-11-03T13:00:00Z", "end": "2026-11-03T13:30:00Z" }] } }

events.get for an unknown event must answer 404, not a made-up event.

How Opami reads your statuses

Your statusOpami treats it as
401reauth
403reauth
404not_found
409precondition_failed
410gone
412precondition_failed
429unavailable (retried)
5xxunavailable (retried)
any other non-2xx, or a 2xx not in the formatinvalid

Telling Opami about changes

Push changed events to POST /v1/sources/{id}/calendar-events with the same API key as an inbox source:

curl -X POST https://app.opami.ai/v1/sources/$OPAMI_SOURCE_ID/calendar-events \
  -H "Authorization: Bearer $OPAMI_API_KEY" -H "Content-Type: application/json" \
  -d '{"events":[{"id":"evt_123","calendar_id":"team","title":"Call","start":"2026-11-03T14:00:00+01:00","end":"2026-11-03T14:30:00+01:00","status":"confirmed","updated_at":"2026-10-27T09:12:44Z"}]}'

If your app cannot push, Opami polls events.list on its regular schedule instead. A push is accepted only once the calendar has passed the conformance test (409 calendar_not_usable before).