openapi: 3.1.0
info:
  title: Dont4get Appointment Intake API
  version: 0.1.0
  description: >
    Public API contract for software vendors that want to send definitive
    appointments into Dont4get at platform-holder or organization level.
servers:
  - url: https://platform.dont4get.io
security:
  - bearerApiKey: []
paths:
  /api/v1/platform-holders/{platformHolderId}/appointments/intake:
    post:
      operationId: intakePlatformHolderAppointment
      summary: Send a definitive appointment to Dont4get
      description: >
        Creates or updates a definitive appointment from an external package.
        Recipient confirmation is not required before the appointment is stored.
      parameters:
        - name: platformHolderId
          in: path
          required: true
          schema:
            type: string
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AppointmentIntakeRequest"
      responses:
        "201":
          description: Appointment accepted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AppointmentIntakeResponse"
        "400":
          description: Invalid request
        "401":
          description: Missing or invalid API key
        "403":
          description: Platform holder is inactive or key does not have scope
components:
  securitySchemes:
    bearerApiKey:
      type: http
      scheme: bearer
      description: Platform-holder API key issued by Dont4get.
  schemas:
    AppointmentIntakeRequest:
      type: object
      required:
        - sourceSystem
        - externalAppointmentId
        - startsAt
        - endsAt
        - timezone
        - recipient
      properties:
        sourceSystem:
          type: string
          example: example_ehr
        externalAppointmentId:
          type: string
          example: appt_123
        externalCalendarId:
          type: string
          example: primary
        organizationId:
          type: string
          example: org_123
        locationId:
          type: string
          example: loc_123
        title:
          type: string
          example: Controleafspraak
        startsAt:
          type: string
          format: date-time
        endsAt:
          type: string
          format: date-time
        timezone:
          type: string
          example: Europe/Amsterdam
        locationText:
          type: string
          example: Vestiging Amsterdam
        recipient:
          $ref: "#/components/schemas/AppointmentRecipient"
        metadata:
          type: object
          additionalProperties:
            type: string
    AppointmentRecipient:
      type: object
      description: At least email or phoneNumberE164 is required.
      properties:
        displayName:
          type: string
        email:
          type: string
          format: email
        phoneNumberE164:
          type: string
          example: "+31612345678"
        externalRecipientId:
          type: string
    AppointmentIntakeResponse:
      type: object
      properties:
        appointmentId:
          type: string
        status:
          type: string
          enum: [accepted]
        sourceAppointmentState:
          type: string
          enum: [definitive]
