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

> ## Agent Instructions
> Use the public API base URL: https://api.teamfollowup.ai/api.
> Authenticate public API requests with Authorization: Bearer YOUR_API_KEY.
> Use product-owned terms: agents, campaigns, projects (GoHighLevel sub-accounts), contacts, calls, outcomes, skills, cadences, phone numbers.
> Scope requests by locationId rather than projectName.
> Read the guide linked from each API reference group before recommending an endpoint.

# Add an event

> Puts something on the calendar that is not a lead: a meeting, a reminder, time held back.

It carries no contact, starts no confirmation campaign and sends nobody anything. What it does do is occupy the seats it covers, so the agent stops offering that time.

Give it `startTime` and `endTime`; `title`, `location` and `notes` are for the people reading the diary.

Cookie-auth callers must send the `x-csrf-token` header.

Required API key scope: `projects:write`.



## OpenAPI

````yaml /openapi.yaml post /api/native-calendar/events
openapi: 3.1.0
info:
  title: TFUAI Server API
  version: 1.0.0
  description: >-
    API reference for the TFUAI SaaS server.


    All published endpoints are mounted under `/api`. Responses use a standard
    envelope: `{ "success": true, ... }` on success and `{ "success": false,
    "error": "..." }` on failure.


    Product API modules are being launched module by module. This spec currently
    exposes only contracted public modules.


    Authenticate public API requests with an API key in the `Authorization`
    header: `Authorization: Bearer YOUR_API_KEY`.
servers:
  - url: https://api.teamfollowup.ai
    description: Production API origin. Public API paths are under /api.
security: []
tags:
  - name: Agents
    description: Manage voice agents, campaigns, workflows, and outcomes.
  - name: Analytics
    description: >-
      Minimal, non-billing performance summary: volume, conversion, and pickup
      metrics.
  - name: Billing
    description: >-
      Billing for your own agency: balance, spend, transaction history, invoices
      and sub-account wallets; auto-recharge, rebilling, Credit Guard and Stripe
      customers; and, with the billing:charge scope, purchases and charges.
  - name: Calls
    description: Review calls, test runs, and execution history.
  - name: Campaign Workflows
    description: >-
      What runs after a call lands: for each outcome (booked, opted out, asked
      for a callback…), an ordered chain of actions — tag the contact, move a
      pipeline stage, send an SMS, book an appointment. Stored as a graph:
      `nodes` are the actions, `edges` say what follows what, and
      `dispositionEntries` maps each outcome to the node its chain starts at.


      **Pick the narrowest endpoint that does the job.**


      | To | Call | |

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

      | See what fires per outcome | `GET .../workflow/digest` | Reads as plain
      text, no graph walking |

      | Add steps to an outcome | `POST .../outcomes/{outcome}/nodes` | Server
      derives node ids, edge ids, handles, layout |

      | Change a message, tag or setting | `PATCH .../workflow` | Merges;
      carries no graph, so it cannot damage one |

      | Remove one step | `DELETE .../nodes/{nodeId}` | Also re-links the chain
      around it |

      | Author or replace the whole graph | `PUT .../workflow` | Replaces
      everything you send |


      `PUT` is the only one that can re-wire, position nodes, build an `if`,
      save an unconfigured draft, or copy a whole workflow — and the only one
      that can overwrite a change someone else made after you read it. Use it
      when you are genuinely authoring the graph, and send `expectedVersion`
      when you do. For everything else the narrower endpoints are both easier
      and safer.
  - name: Contacts
    description: Contact list, filters, contact call history, and do-not-call actions.
  - name: GHL
    description: CRM variables and contact helpers used by agent and campaign setup flows.
  - name: Native Calendar
    description: >-
      The diary of a sub-account with no CRM: its bookable calendars, the free
      slots they offer, and the appointments on them. Availability is computed
      per request against live bookings and is never cached, because a cached
      slot is one somebody else has already taken.
  - name: Native Contacts
    description: >-
      The people a sub-account with no CRM calls, and the fields it keeps on
      them. This is the system of record for those contacts: there is nowhere
      else they exist. A sub-account with a CRM keeps its contacts there and
      every operation here answers 400 for it.
  - name: Phone Numbers
    description: >-
      Caller ID pool, number search, assignment, movement, and release
      endpoints.
  - name: Power Dialer
    description: >-
      Power Dialer queue, lead cadence, callback, parked lead, and campaign
      schedule endpoints.
  - name: Projects
    description: >-
      Project management endpoints: list, update, disconnect, configure project
      campaigns, and validate setup.
  - name: Skills and Tools
    description: Manage reusable agent behaviors and in-call tool descriptions.
  - name: Split Testing
    description: >-
      Split live campaign traffic across agent variants and shift the weights
      between them.
  - name: Voices
    description: Voice catalogue endpoints for choosing the voice used by an agent.
paths:
  /api/native-calendar/events:
    post:
      tags:
        - Native Calendar
      summary: Add an event
      description: >-
        Puts something on the calendar that is not a lead: a meeting, a
        reminder, time held back.


        It carries no contact, starts no confirmation campaign and sends nobody
        anything. What it does do is occupy the seats it covers, so the agent
        stops offering that time.


        Give it `startTime` and `endTime`; `title`, `location` and `notes` are
        for the people reading the diary.


        Cookie-auth callers must send the `x-csrf-token` header.


        Required API key scope: `projects:write`.
      operationId: create-native-calendar-event
      parameters:
        - name: locationId
          in: query
          required: true
          schema:
            type: string
          description: >-
            The sub-account this calendar belongs to. It is the only thing that
            identifies the tenant here, and access is re-checked against it on
            every call.
          example: nat_fd9e2a8dd4be4396b604
      requestBody:
        required: true
        description: The entry.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NativeCalendarEventRequest'
            examples:
              default:
                value:
                  calendarId: cal_6b1f2a7c90
                  startTime: '2026-09-23T13:00:00.000Z'
                  endTime: '2026-09-23T14:00:00.000Z'
                  title: Team meeting
                  notes: Hold the hour, no bookings.
      responses:
        '200':
          description: The entry, holding its seats.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeAppointmentMutationResponse'
              examples:
                default:
                  value:
                    success: true
                    data:
                      ok: true
                      appointmentId: apt_1c93f7ab20
                      status: confirmed
        '400':
          description: >-
            The request is malformed, or the calendar definition is invalid.
            `errors` carries every reason, not only the first.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeCalendarErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: timezone is required
        '401':
          description: Missing or invalid authentication.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeCalendarErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Unauthorized
        '403':
          description: >-
            Authenticated, but without access to this sub-account or this
            calendar.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeCalendarErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: calendar does not belong to this project
        '404':
          description: No such calendar or appointment in this sub-account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeCalendarErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: calendar not found
        '409':
          description: The slot is full, or the calendar still has upcoming appointments.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeCalendarErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: 'slot rejected: slot_full'
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeCalendarErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: TooManyRequests
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeCalendarErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Calendar request failed.
        '503':
          description: The calendar service is unreachable or not configured.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NativeCalendarErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Calendar service is unreachable.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request POST \
              --url https://api.teamfollowup.ai/api/native-calendar/events \
              --header 'Authorization: Bearer YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
              "calendarId": "cal_6b1f2a7c90",
              "startTime": "2026-09-23T13:00:00.000Z",
              "endTime": "2026-09-23T14:00:00.000Z",
              "title": "Team meeting",
              "notes": "Hold the hour, no bookings."
            }'
components:
  schemas:
    NativeCalendarEventRequest:
      type: object
      additionalProperties: {}
      required:
        - calendarId
        - startTime
        - endTime
      properties:
        calendarId:
          type: string
          example: cal_6b1f2a7c90
        startTime:
          type:
            - string
            - integer
          example: '2026-09-23T13:00:00.000Z'
        endTime:
          type:
            - string
            - integer
          example: '2026-09-23T14:00:00.000Z'
        title:
          type: string
          example: Team meeting
        location:
          type: string
        notes:
          type: string
        kind:
          type: string
          description: 'What it is, for the diary: a meeting, a reminder, time held.'
    NativeAppointmentMutationResponse:
      type: object
      additionalProperties: {}
      required:
        - success
        - data
      properties:
        success:
          type: boolean
        data:
          type: object
          additionalProperties: {}
          description: The appointment as it now stands.
    NativeCalendarErrorResponse:
      type: object
      additionalProperties: {}
      required:
        - success
        - error
      properties:
        success:
          type: boolean
        error:
          type: string
          example: timezone is required
        errors:
          type: array
          items:
            type: string
          description: Every reason a calendar definition was refused, not only the first.
        upcomingCount:
          type: integer
          description: >-
            On a refused delete: how many appointments are still ahead on this
            calendar.
          example: 3
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Send your API key as `Authorization: Bearer YOUR_API_KEY`.'

````