POST
/api/public/v1/calendar-events

Create a calendar event

Schedules an event and invites people to it. This sends mail: every guest gets an invitation with an .ics attachment. Employees aren’t mailed — the event is already on their calendar in Pixelbase. Unless you set `includeVirtualMeeting` to false a virtual meeting room is provisioned and linked, reachable from Meetings as well as the calendar. The organizer, and the employee the token acts as, are both marked ACCEPTED — nobody confirms an event they scheduled.

Required scope

The access token must carry this scope. A token missing it gets 403 Forbidden. Grant them to an API client under Settings → Company → API, and to a teammate under Employee → Permissions.

calendar:write

Request Body

PropertyTypeDescription
titlestringUp to 255 characters.
startTimestringISO 8601.
endTimestringISO 8601.
descriptionstring
locationstringFree text — a room, an address, anything.
timezonestringIANA zone the event was scheduled in. Times are stored as UTC; this is the zone every invitation renders and labels them in.
allDaybooleanDefaults to false.
showAsstringHow the event shows to anyone scheduling around the attendees. FREE does not block their time. Defaults to DEFAULT.
organizerEmployeeIdstringAny employee of this company. Defaults to whoever the token acts as. Guests can never organize.
includeVirtualMeetingbooleanDefaults to true. Set false to skip provisioning a room — a room that cannot be provisioned fails the whole create rather than shipping a broken link.
recurrenceRulestringMakes it a series.
recurrenceEndDatestringISO 8601. Omit for a series with no end.
attendeesarrayObjects of `{ employeeId }` or `{ guestEmail, guestName }`, each optionally `{ optional: true }`. Everyone here starts PENDING; guests are emailed an invitation.
POSTExample request
curl
curl -X POST "https://www.pxb.app/api/public/v1/calendar-events" \
  -H "Authorization: Bearer your_access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Quarterly review",
    "startTime": "2026-09-02T16:00:00.000Z",
    "endTime": "2026-09-02T17:00:00.000Z",
    "timezone": "America/Chicago",
    "showAs": "DEFAULT",
    "attendees": [
      {
        "employeeId": "emp_44f1"
      },
      {
        "guestEmail": "advisor@example.com",
        "optional": true
      }
    ]
  }'
200Example response
json
{
  "message": "Calendar event created!",
  "content": {
    "event": {
      "id": "cal_5150",
      "title": "Quarterly review",
      "description": "Numbers and what we do about them.",
      "location": "Boardroom",
      "startTime": "2026-09-02T16:00:00.000Z",
      "endTime": "2026-09-02T17:00:00.000Z",
      "timezone": "America/Chicago",
      "allDay": false,
      "showAs": "DEFAULT",
      "includeVirtualMeeting": true,
      "meetingRoomId": "room_7a21",
      "recurrenceRule": null,
      "recurrenceEndDate": null,
      "recurrenceExclusions": [],
      "createdByEmployeeId": "emp_12ab",
      "attendees": [
        {
          "id": "att_01",
          "employeeId": "emp_12ab",
          "status": "ACCEPTED",
          "optional": false,
          "note": null,
          "declinedOccurrences": []
        },
        {
          "id": "att_02",
          "employeeId": null,
          "guestEmail": "advisor@example.com",
          "guestName": "Jo Advisor",
          "status": "PENDING",
          "optional": true,
          "note": null,
          "declinedOccurrences": []
        }
      ],
      "createdAt": "2026-08-14T10:00:00.000Z",
      "updatedAt": "2026-08-14T10:00:00.000Z"
    }
  }
}

In the console

The same thing done by hand, for anyone comparing the API against the screen they already use.

Calendar
/calendar
  1. Open the Calendar.
  2. Pick a slot, or New event.
  3. Add attendees and save.