GoliathDevelopersGet an API key
Reference/Appointmentsgenerated from the gateway manifest

createAppointmentReminder

A reminder TEXTS REAL CONTACTS automatically.

POST/api/v1/callWRITEidempotent · 24 hruns as the key's owner
View as Markdown

A reminder TEXTS REAL CONTACTS automatically. Before calling, show the user every step's exact message and timing and wait for them to confirm that copy; never invent or reword it and send it unseen. Messages may use {{merge fields}} (the APPOINTMENT keys under MERGE FIELDS in updateWorkflowGraph's description); a step with a field an appointment cannot fill is NOT sent for it, so keep to fields every appointment has. Create a reminder: one SMS to the appointment's linked contacts per step, each sent amountBefore + unitBefore (MINUTES | HOURS | DAYS; amountBefore > 0) before its start, e.g. steps: [{message, amountBefore: 30, unitBefore: MINUTES}] for "30 minutes before". isGlobal: true makes it the org default, replacing any prior one. The org DEFAULT reminder ("Run for every appointment") is attached automatically to booking-page and AI-employee bookings and preselected in the app's appointment form; NOT to appointments created through this API (pass its id as appointmentReminderWorkflowGroupId on createAppointment) nor to existing ones (updateAppointment attaches it). With none flagged and exactly ONE reminder, that one is the default anyway. So the org's FIRST reminder texts new bookings even without isGlobal; any other without it is a preset that sends for nothing until attached. listAppointmentReminders first: when one with the same timing exists, offer to make it the default (setDefaultAppointmentReminder) or edit it rather than add a duplicate.

curl https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer $GOLIATH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "operationId": "createAppointmentReminder",
    "variables": {
      "steps": [
        {
          "message": "<String>",
          "amountBefore": 10,
          "unitBefore": "MINUTES"
        }
      ]
    }
  }'
import { GoliathClient } from '@goliath-data/sdk'

const goliath = new GoliathClient({
  apiKey: process.env.GOLIATH_API_KEY!,
  baseUrl: 'https://server.goliathdata.com',
})

// Enum values as strings: the SDK's enum types aren't exported yet, so assert to the method's variables type.
const variables = {
  steps: [
    {
      message: '<String>',
      amountBefore: 10,
      unitBefore: 'MINUTES'
    }
  ]
} as Parameters<typeof goliath.appointments.createAppointmentReminder>[0]

const result = await goliath.appointments.createAppointmentReminder(variables, { idempotencyKey: crypto.randomUUID() })
const res = await fetch('https://server.goliathdata.com/api/v1/call', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.GOLIATH_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({
    operationId: 'createAppointmentReminder',
    variables: {
      steps: [
        {
          message: '<String>',
          amountBefore: 10,
          unitBefore: 'MINUTES'
        }
      ]
    }
  }),
})
const { data, errors } = await res.json()

Variables

The example sends only what the schema requires. Some operations also need one of several optional variables (one filter or another, say); the description above says which.

steps[AppointmentReminderStepInput!]!required

One step of a reminder: a single SMS and how far ahead of the appointment's `startDate` to send it.

messageString!required
amountBeforeInt!required
unitBeforeAppointmentReminderTimeUnit!required

Unit for `AppointmentReminder.amountBefore`. Capped at DAYS: a reminder more than a day before the appointment isn't a meaningful product use case.

MINUTESHOURSDAYS
isGlobalBoolean

Response

What comes back under data: a list shows as one entry, and a value as its type.

response shape
{
  "data": {
    "appointmentReminderMutation": {
      "createAppointmentReminder": {
        "id": "<ID>",
        "steps": [
          {
            "message": "…",
            "amountBefore": 0,
            "unitBefore": "MINUTES"
          }
        ],
        "isGlobal": true,
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    }
  }
}

Errors

Idempotency

Send an Idempotency-Key of 1 to 255 characters. A finished request retried with the same key replays its stored response, marked Idempotency-Replayed: true; one still in flight returns 409 idempotency_conflict. Keys expire after 24 hours. Write without fear →