> ## 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.

# Why the agent found no times

> An empty diary is almost always the opening hours or the notice window. How to check in one request, and what the agent is actually reading on the call.

"The agent said there was nothing available" almost always means the calendar
really had nothing to offer. This
page is how to find out which rule emptied it.

## Check the calendar itself, not the call

[Free slots](/api-reference/native-calendar/get-free-slots) answers the exact
question the agent asks, from outside the call:

```bash theme={"dark"}
curl "https://api.teamfollowup.ai/api/native-calendar/calendars/{calendarId}/free-slots?locationId={locationId}" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

An empty `slots` object is a real answer, and it is the answer the agent got.
Now change one thing at a time.

## The two settings that empty a diary

<Steps>
  <Step title="Notice: minNoticeMinutes">
    The default is **180 minutes**. On a calendar that closes at 17:00, nothing
    is offered for today after 14:00, and a lead called at 16:00 hears about
    tomorrow at the earliest. Re-read with `?minNoticeMinutes=30` to confirm
    that is what is doing it.
  </Step>

  <Step title="Hours: weeklyHours">
    A day left out of `weeklyHours` is closed, not open. A calendar carrying
    only `mon` offers Monday and nothing else, forever. Check the days as well
    as the times.
  </Step>

  <Step title="Then the rest">
    `maxDaysOut` caps how far ahead it will look, `slotDurationMinutes` has to
    fit inside a window (a 60-minute appointment never fits a 09:00 to 09:30
    window), `slotBufferMinutes` widens every booking, and `dateOverrides` can
    close a specific day.
  </Step>
</Steps>

<Tip>
  `?lookaheadDays=` and `?minNoticeMinutes=` override the calendar for one read
  only. That makes the loosened read a question rather than a change: you learn
  what would open up before you change anything for real callers.
</Tip>

## Timezones

A calendar has its own `timezone`, and that is what the opening hours mean.
Slots come back in it unless you ask for another with `?timezone=`.

This matters most when the calendar's zone and the contact's differ. Hours of
09:00 to 17:00 on a calendar in `America/Chicago` are 15:00 to 23:00 for a
contact in `Europe/London`, and both are correct. Set the contact's `timezone`
so calling windows and spoken times are theirs, and leave the calendar's zone
as the business's.

<Warning>
  A calendar connected from another product reports its own zone, and not every
  product exposes it on every endpoint. When a linked calendar's times look
  shifted by a whole number of hours, check the zone that product has, not the
  slot arithmetic here.
</Warning>

## What the agent is reading on the call

Two different things, and the difference explains most "but the slot was free"
reports.

* **`{{availability}}` in the prompt** is a snapshot, formatted and injected
  when the call starts. It does not change during the call.
* **The slot-finder tool**, when the agent has it, reads a store refreshed
  around the call rather than that snapshot. A slot the agent locks mid-call is
  held immediately, so another call in progress stops offering it.

So an agent without the tool is reading a moment that has passed, and one with
it is reading something close to live. Either way the booking itself is the
authority: the seat is claimed as the appointment is written, and a slot that
went in between comes back `409`.

## When it is not availability

* **The contact is on do-not-call.** Nothing is dialled at all, so no
  availability is ever read. Check `doNotCall` on the contact, in
  [Contacts without a CRM](/contacts/native-contacts).
* **The campaign names no calendar.** An agent with nowhere to book does not
  offer times. The calendar a campaign uses is set on the campaign; see
  [Calendars and booking](/calendars/overview).
* **The appointment was refused, not the slot.** A booking outside the hours
  comes back `invalid_time`, which is a different failure from `slot_unavailable`
  and points at your `startTime`, not at the diary.
