Reonic Appointments API

Appointments on Reonic-hosted calendars only. External calendars (Google, Microsoft) cannot be read or written through the API.

OpenAPI Specification

reonic-appointments-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Reonic REST Api v3 Activities Appointments API
  description: 'The Reonic REST API v3 provides programmatic access to create and manage resources. The API follows REST principles and returns responses in JSON format. Authentication is required via an API key passed in the X-Authorization header.


    ## Errors


    All endpoints return errors with the same JSON shape:


    ```json

    { "message": "human-readable description" }

    ```


    `400` responses additionally include an `errors` field with per-field validation details.


    The HTTP status code identifies the cause:


    | Status  | Meaning | When |

    |--------|---------|------|

    | `400` | Bad Request | Path params, query string, or request body failed validation. Inspect `errors` for the field-level breakdown. |

    | `401` | Unauthorized | The `X-Authorization` header is missing, malformed, does not match an active API key, or belongs to a different API version. The response never indicates which check failed; check that the key matches the endpoint version. API v3 endpoints require a v3 key with the `rnc_v3_` prefix. |

    | `403` | Forbidden | The API key is read-only and the request targeted a write endpoint (`POST`). Issue a key with write access. |

    | `404` | Not Found | A resource referenced by a path id does not exist or is not visible to your workspace. |

    | `429` | Too Many Requests | The per-client rate limit was exceeded. See **Rate limiting** below. |

    | `500` | Internal Server Error | Unexpected failure. Safe to retry once; if it persists, contact support. |

    | `503` | Service Unavailable | A backing dependency is temporarily unavailable. Retry with exponential backoff. |


    ## Rate limiting


    Limits are shared across all API keys you hold and reset on a 1-minute window. Two buckets:


    | Bucket | Limit | Applies to |

    |--------|-------|------------|

    | `cached` | 500 / min | `GET` requests served from the response cache |

    | `uncached` | 30 / min | Cache misses, `GET` requests sent with `Reonic-Cache-Control: no-cache`, and all `POST` requests |


    Every response includes:


    - `X-RateLimit-Bucket` — `cached` or `uncached`

    - `X-RateLimit-Limit` — the bucket''s ceiling (`500` or `30`)

    - `X-RateLimit-Remaining` — calls left in the current window

    - `X-RateLimit-Reset` — Unix epoch seconds at which the window resets

    - `X-RateLimit-Policy` — `<limit>;w=60`


    `429` responses additionally set `Retry-After` (in seconds). Wait at least that long before retrying.


    ## Caching and Reonic-Cache-Control


    `GET` responses are cached for up to 1 hour. Identical requests (same path and query) on the same API key return the cached result. To force a fresh read, send `Reonic-Cache-Control: no-cache`; the response is then refreshed and re-cached. Forced refreshes count against the `uncached` rate-limit bucket.


    The standard `Cache-Control` header is not honored. Use `Reonic-Cache-Control` to control caching behavior.


    ## Authentication


    Every request must include your API key in the `X-Authorization` header:


    ```

    X-Authorization: <your-api-key>

    ```


    API keys are issued from the Reonic web app and look like `rnc_v3_…`. Send the full value, including the prefix.

    '
  version: 3.2.0
  contact:
    email: kontakt@reonic.de
    url: https://reonic.com
    name: Reonic GmbH
servers:
- url: '{apiBaseUrl}/rest/v3/'
security:
- X-Authorization: []
tags:
- name: Appointments
  description: Appointments on Reonic-hosted calendars only. External calendars (Google, Microsoft) cannot be read or written through the API.
paths:
  /appointments:
    get:
      summary: List appointments
      description: 'Lists appointments on Reonic calendars in a paginated format.


        **Allowed API keys:** Read-only, Read and Write'
      tags:
      - Appointments
      parameters:
      - schema:
          type:
          - array
          - 'null'
          items:
            type: string
            format: uuid
          minItems: 1
          maxItems: 100
          description: Comma-separated list or repeated query param of calendar IDs to fetch appointments for.
          examples:
          - 123e4567-e89b-12d3-a456-426614174000
          - 123e4567-e89b-12d3-a456-426614174000, 123e4567-e89b-12d3-a456-426614174002
        required: false
        description: Comma-separated list or repeated query param of calendar IDs to fetch appointments for.
        name: calendarIds
        in: query
      - schema:
          type: string
          format: uuid
          description: Return only appointments linked to the given residential project. Mutually exclusive with `commercialProjectId`. Reference to [**Residential Projects**](#tag/residential-projects)
        required: false
        description: Return only appointments linked to the given residential project. Mutually exclusive with `commercialProjectId`. Reference to [**Residential Projects**](#tag/residential-projects)
        name: residentialProjectId
        in: query
      - schema:
          type: string
          format: uuid
          description: Return only appointments linked to the given commercial project. Mutually exclusive with `residentialProjectId`. Reference to [**Commercial Projects**](#tag/commercial-projects)
        required: false
        description: Return only appointments linked to the given commercial project. Mutually exclusive with `residentialProjectId`. Reference to [**Commercial Projects**](#tag/commercial-projects)
        name: commercialProjectId
        in: query
      - schema:
          type:
          - string
          - 'null'
          format: date-time
          description: Filter records where start is after this datetime (exclusive)
          example: '2026-01-01T15:30:00.000Z'
        required: false
        description: Filter records where start is after this datetime (exclusive)
        name: start.gt
        in: query
      - schema:
          type:
          - string
          - 'null'
          format: date-time
          description: Defaults to the day one year from now.
          example: '2026-01-01T15:30:00.000Z'
        required: false
        description: Defaults to the day one year from now.
        name: start.lt
        in: query
      - schema:
          type:
          - string
          - 'null'
          format: date-time
          description: Defaults to now, so that by default only upcoming appointments are returned.
          example: '2026-01-01T15:30:00.000Z'
        required: false
        description: Defaults to now, so that by default only upcoming appointments are returned.
        name: end.gt
        in: query
      - schema:
          type:
          - string
          - 'null'
          format: date-time
          description: Filter records where end is before this datetime (exclusive)
          example: '2026-01-01T15:30:00.000Z'
        required: false
        description: Filter records where end is before this datetime (exclusive)
        name: end.lt
        in: query
      - schema:
          type: integer
          minimum: 1
          default: 1
          description: 'Page number, starting from 1. Default: 1.'
        required: false
        description: 'Page number, starting from 1. Default: 1.'
        name: page
        in: query
      - schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
          description: 'Number of items per page. Default: 50. Max: 200.'
        required: false
        description: 'Number of items per page. Default: 50. Max: 200.'
        name: itemsPerPage
        in: query
      - schema:
          type:
          - string
          - 'null'
          default: start
          description: 'Sort order. Use field names for ascending (e.g. "createdAt"), minus sign for descending (e.g. "-createdAt"). Chain with commas (e.g. "createdAt,editedAt"). Sortable fields: start, end. Defaults to start.'
          examples:
          - start
          - -start
          - end,-start
        required: false
        description: 'Sort order. Use field names for ascending (e.g. "createdAt"), minus sign for descending (e.g. "-createdAt"). Chain with commas (e.g. "createdAt,editedAt"). Sortable fields: start, end. Defaults to start.'
        name: sort
        in: query
      - schema:
          type: string
          example: no-cache
        required: false
        name: Reonic-Cache-Control
        in: header
        description: Set to 'no-cache' to bypass the 1-hour response cache and force a fresh read. The fresh response is then written back to the cache for subsequent callers. Forced refreshes count against the uncached rate-limit bucket (30/min); only cache hits count against the cached bucket (500/min).
      responses:
        '200':
          description: Paginated list of appointments
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                          example: 123e4567-e89b-12d3-a456-426614174000
                        calendarId:
                          type: string
                          format: uuid
                          example: 123e4567-e89b-12d3-a456-426614174000
                        title:
                          type: string
                          default: ''
                        customerPortalTitle:
                          type:
                          - string
                          - 'null'
                        description:
                          type:
                          - string
                          - 'null'
                        customerPortalDescription:
                          type:
                          - string
                          - 'null'
                        visibleInCustomerPortal:
                          type: boolean
                          description: Whether this appointment is visible in the customer portal or not.
                        start:
                          type: string
                          format: date-time
                          example: '2026-01-01T15:30:00.000Z'
                        end:
                          type: string
                          format: date-time
                          example: '2026-01-01T15:30:00.000Z'
                        allDay:
                          type: boolean
                        location:
                          type:
                          - string
                          - 'null'
                        residentialProjectId:
                          type:
                          - string
                          - 'null'
                          format: uuid
                        commercialProjectId:
                          type:
                          - string
                          - 'null'
                          format: uuid
                        attendeeIds:
                          type: array
                          items:
                            type: string
                            format: uuid
                          description: List of users attending this appointment. Reference to [**Users**](#tag/users)
                      required:
                      - id
                      - calendarId
                      - customerPortalTitle
                      - description
                      - customerPortalDescription
                      - visibleInCustomerPortal
                      - start
                      - end
                      - allDay
                      - location
                      - residentialProjectId
                      - commercialProjectId
                      - attendeeIds
                  pagination:
                    type: object
                    properties:
                      page:
                        type: integer
                        minimum: 1
                        description: Current page number
                      perPage:
                        type: integer
                        minimum: 1
                        description: Number of items per page
                      total:
                        type: integer
                        minimum: 0
                        description: Total number of items across all pages
                      totalPages:
                        type: integer
                        minimum: 1
                      next:
                        type:
                        - string
                        - 'null'
                        description: Path to the next page, or null if there is no next page
                      prev:
                        type:
                        - string
                        - 'null'
                        description: Path to the previous page, or null if there is no previous page
                    required:
                    - page
                    - perPage
                    - total
                    - totalPages
                    - next
                    - prev
                required:
                - data
                - pagination
  /appointments/create:
    post:
      summary: Create appointment
      description: 'Create an appointment on a Reonic calendar.


        **Allowed API keys:** Read and Write'
      tags:
      - Appointments
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                calendarId:
                  type: string
                  format: uuid
                title:
                  type: string
                  minLength: 1
                  maxLength: 2000
                customerPortalTitle:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  maxLength: 2000
                description:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  maxLength: 5000
                customerPortalDescription:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  maxLength: 5000
                visibleInCustomerPortal:
                  type: boolean
                  default: false
                  description: 'Whether this appointment is visible in the customer portal or not. Default: `false`'
                start:
                  type: string
                  format: date-time
                  example: '2026-01-01T15:30:00.000Z'
                  description: Appointment start. When `allDay` is `true`, only the date portion is used and the time component is ignored.
                end:
                  type: string
                  format: date-time
                  example: '2026-01-01T15:30:00.000Z'
                  description: Appointment end. When `allDay` is `true`, only the date portion is used and the time component is ignored.
                allDay:
                  type: boolean
                  description: When `true`, `start` and `end` are treated as dates only — the time component is ignored and `end` must be at least one full day after `start`. When `false`, `start` and `end` are treated as exact datetimes.
                attendeeIds:
                  type:
                  - array
                  - 'null'
                  items:
                    type: string
                    format: uuid
                  maxItems: 100
                  description: Users attending this appointment. Reference to [**Users**](#tag/users)
                location:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  maxLength: 2000
                residentialProjectId:
                  type:
                  - string
                  - 'null'
                  format: uuid
                  description: Mutually exclusive with `commercialProjectId`. Reference to [**Residential Projects**](#tag/residential-projects)
                commercialProjectId:
                  type:
                  - string
                  - 'null'
                  format: uuid
                  description: Mutually exclusive with `residentialProjectId`. Reference to [**Commercial Projects**](#tag/commercial-projects)
              required:
              - calendarId
              - title
              - start
              - end
              - allDay
              additionalProperties: false
      responses:
        '201':
          description: The created appointment
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                    example: 123e4567-e89b-12d3-a456-426614174000
                  calendarId:
                    type: string
                    format: uuid
                    example: 123e4567-e89b-12d3-a456-426614174000
                  title:
                    type: string
                    default: ''
                  customerPortalTitle:
                    type:
                    - string
                    - 'null'
                  description:
                    type:
                    - string
                    - 'null'
                  customerPortalDescription:
                    type:
                    - string
                    - 'null'
                  visibleInCustomerPortal:
                    type: boolean
                    description: Whether this appointment is visible in the customer portal or not.
                  start:
                    type: string
                    format: date-time
                    example: '2026-01-01T15:30:00.000Z'
                  end:
                    type: string
                    format: date-time
                    example: '2026-01-01T15:30:00.000Z'
                  allDay:
                    type: boolean
                  location:
                    type:
                    - string
                    - 'null'
                  residentialProjectId:
                    type:
                    - string
                    - 'null'
                    format: uuid
                  commercialProjectId:
                    type:
                    - string
                    - 'null'
                    format: uuid
                  attendeeIds:
                    type: array
                    items:
                      type: string
                      format: uuid
                    description: List of users attending this appointment. Reference to [**Users**](#tag/users)
                required:
                - id
                - calendarId
                - customerPortalTitle
                - description
                - customerPortalDescription
                - visibleInCustomerPortal
                - start
                - end
                - allDay
                - location
                - residentialProjectId
                - commercialProjectId
                - attendeeIds
  /appointments/{appointmentId}/update:
    post:
      summary: Update appointment
      description: 'Update fields of an appointment on a Reonic calendar. Omit fields to leave them untouched, send `null` to clear them (where possible) or send a value to replace it.


        **Allowed API keys:** Read and Write'
      tags:
      - Appointments
      parameters:
      - schema:
          type: string
          format: uuid
        required: true
        name: appointmentId
        in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  minLength: 1
                  maxLength: 2000
                customerPortalTitle:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  maxLength: 2000
                description:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  maxLength: 5000
                customerPortalDescription:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  maxLength: 5000
                visibleInCustomerPortal:
                  type: boolean
                  description: Whether this appointment is visible in the customer portal or not.
                start:
                  type: string
                  format: date-time
                  example: '2026-01-01T15:30:00.000Z'
                  description: Appointment start. When `allDay` is `true`, only the date portion is used and the time component is ignored.
                end:
                  type: string
                  format: date-time
                  example: '2026-01-01T15:30:00.000Z'
                  description: Appointment end. When `allDay` is `true`, only the date portion is used and the time component is ignored.
                allDay:
                  type: boolean
                  description: When `true`, `start` and `end` are treated as dates only — the time component is ignored and `end` must be at least one full day after `start`. When `false`, `start` and `end` are treated as exact datetimes.
                attendeeIds:
                  type:
                  - array
                  - 'null'
                  items:
                    type: string
                    format: uuid
                  maxItems: 100
                  description: Users attending this appointment. Reference to [**Users**](#tag/users)
                location:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  maxLength: 2000
                residentialProjectId:
                  type:
                  - string
                  - 'null'
                  format: uuid
                  description: Mutually exclusive with `commercialProjectId`. Reference to [**Residential Projects**](#tag/residential-projects)
                commercialProjectId:
                  type:
                  - string
                  - 'null'
                  format: uuid
                  description: Mutually exclusive with `residentialProjectId`. Reference to [**Commercial Projects**](#tag/commercial-projects)
              additionalProperties: false
      responses:
        '200':
          description: The updated appointment
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                    example: 123e4567-e89b-12d3-a456-426614174000
                  calendarId:
                    type: string
                    format: uuid
                    example: 123e4567-e89b-12d3-a456-426614174000
                  title:
                    type: string
                    default: ''
                  customerPortalTitle:
                    type:
                    - string
                    - 'null'
                  description:
                    type:
                    - string
                    - 'null'
                  customerPortalDescription:
                    type:
                    - string
                    - 'null'
                  visibleInCustomerPortal:
                    type: boolean
                    description: Whether this appointment is visible in the customer portal or not.
                  start:
                    type: string
                    format: date-time
                    example: '2026-01-01T15:30:00.000Z'
                  end:
                    type: string
                    format: date-time
                    example: '2026-01-01T15:30:00.000Z'
                  allDay:
                    type: boolean
                  location:
                    type:
                    - string
                    - 'null'
                  residentialProjectId:
                    type:
                    - string
                    - 'null'
                    format: uuid
                  commercialProjectId:
                    type:
                    - string
                    - 'null'
                    format: uuid
                  attendeeIds:
                    type: array
                    items:
                      type: string
                      format: uuid
                    description: List of users attending this appointment. Reference to [**Users**](#tag/users)
                required:
                - id
                - calendarId
                - customerPortalTitle
                - description
                - customerPortalDescription
                - visibleInCustomerPortal
                - start
                - end
                - allDay
                - location
                - residentialProjectId
                - commercialProjectId
                - attendeeIds
  /appointments/{appointmentId}/delete:
    post:
      summary: Delete appointment
      description: 'Delete an appointment on a Reonic calendar.


        **Allowed API keys:** Read and Write'
      tags:
      - Appointments
      parameters:
      - schema:
          type: string
          format: uuid
        required: true
        name: appointmentId
        in: path
      responses:
        '200':
          description: ID of the deleted appointment
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                    required:
                    - id
                    additionalProperties: false
                required:
                - data
components:
  securitySchemes:
    X-Authorization:
      type: apiKey
      in: header
      name: X-Authorization
x-tagGroups:
- name: People
  tags:
  - Contacts
  - Users
  - Teams
- name: Projects
  tags:
  - Residential Projects
  - Commercial Projects
- name: Working on a project
  tags:
  - Notes
  - Tasks
  - Files
  - File Folders
  - Activities
  - Time Tracking
  - Checklists
  - Checklist Templates
  - Signature Requests
- name: Calendar
  tags:
  - Calendars
  - Calendar Categories
  - Appointments
- name: Catalog
  tags:
  - Components
  - Planning Templates
  - Planning Packages
  - Offer Templates
- name: Workspace setup
  tags:
  - Kanban Boards
  - Kanban Columns
  - Tags
  - Lead Sources
- name: Wiki
  tags:
  - Wiki
- name: Services
  tags:
  - Photogrammetry
- name: API helpers
  tags:
  - Upload
  - Links
- name: Integrations
  tags:
  - Webhooks
- name: Guides
  tags:
  - Migrating from API v2 to v3
  - Changelog