---
title: "How do I Schedule Chili Piper Meetings Programmatically?"
source_url: https://help.chilipiper.com/hc/en-us/articles/50860790980627-How-do-I-Schedule-Chili-Piper-Meetings-Programmatically
article_id: 50860790980627
updated_at: 2026-04-28T07:55:40Z
---

## Who can use this feature?

Available on All Products or Routing & Scheduling

Available to Only Admins

[Billing Center](https://fire.chilipiper.com/fire/admin/billing/overview) [Get a Demo](https://www.chilipiper.com/request-demo?utm_source=zendesk&utm_medium=help-center&utm_campaign=chili-hub)

**Programmatic scheduling** means booking a Chili Piper meeting without sending the lead through any Chili Piper UI. Your own code – a backend process, a custom frontend, an AI assistant – calls the Chili Piper API, picks a time, and books the meeting directly.

You have three starting points:

  * A **Concierge router** – routes a lead using data you submit (plus CRM data when the guest matches an existing record);
  * A **ChiliCal scheduling link** – books against a link or user you've already identified;
  * A **Handoff router** – routes from an existing CRM lead or contact.



All three use the same two-step pattern.

* * *

#### Table of Contents

  * The two-step pattern
  * Before you start
  * Concierge
  * Scheduling links
  * Handoff
  * Running it via MCP instead
  * Good to Know
  * Related articles



* * *

## The two-step pattern

Every programmatic booking follows the same shape:

  1. **Discover or route** – a first call returns a session with a list of available time slots and an identifier for the session (`routeId`);
  2. **Book** – a second call passes the `routeId` and a chosen `startTime` to commit the meeting. Calendar invites are sent immediately.



The session is short-lived and single-use. If the book call fails (for example, the slot is no longer available), start again with a fresh discover or route call.

* * *

## Before you start

Generate an API token with the permissions for the patterns you need:

  * **Concierge** : **Schedule** under the **Concierge** section;
  * **Scheduling links** : **Schedule** under the **Scheduling-links** section;
  * **Handoff** : **Schedule** under the **Handoff** section.



Add the **Read** permission in any section where you also need to list assets via API – for example, listing scheduling links by type (as this guide does in the Scheduling links example) or listing Concierge routers.

Steps for generating tokens are in the [Edge API References](https://help.chilipiper.com/hc/en-us/articles/35576029581971-Edge-API-References#h_01JEBR95Q9TNCM0VK249BCWARM) article.

Store the token securely – it is shown **only once** at generation. The examples below use `$CHILI_PIPER_API_KEY` as a placeholder; replace it with your token or reference it from your environment.

* * *

## Concierge

**When to use:** you want Chili Piper to evaluate routing rules and assign the meeting to the right team or user based on the lead's data.

**The two calls:**

  1. `POST /concierge/routers/[routerSlug]/rest` with an `interval` – routes the lead and returns available slots;
  2. `POST /concierge/routing/[routeId]/schedule-simple` – books one of the slots.



You need a Concierge router configured with a trigger (**Third-party Form** , **In-app Button** , or **Router Link**). See [Using Concierge via the Edge API](https://help.chilipiper.com/hc/en-us/articles/30935152032275) for the full Concierge-specific guide.

### Example

**Step 1 – route a lead and get available slots:**
    
    
    curl -X POST \
      "https://fire.chilipiper.com/api/fire-edge/v1/org/concierge/routers/[routerSlug]/rest" \
      -H "Authorization: Bearer $CHILI_PIPER_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "form": { "PersonEmail": "lead@example.com", "PersonFirstName": "Jamie" },
        "options": { "trigger": "InAppButton" },
        "interval": { "startsAt": "2026-04-14T00:00:00Z", "duration": "7 days" }
      }'
    

The response includes a `routeId` and a list of `startTimes` under `schedulingData`. Pick one.

**Step 2 – book the chosen slot:**
    
    
    curl -X POST \
      "https://fire.chilipiper.com/api/fire-edge/v1/org/concierge/routing/[routeId]/schedule-simple" \
      -H "Authorization: Bearer $CHILI_PIPER_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "startTime": "2026-04-14T17:00:00Z" }'
    

The response includes a `meetingId`. The lead and assignee receive calendar invites immediately.

* * *

## Scheduling links

**When to use:** you already know which scheduling link to book against – for example, a lead-owner link resolved from your CRM, or a specific group link tied to a team.

**The two calls:**

  1. `POST /schedulingLinks/init-simple` with a `link` reference and an `interval` – initializes a session and returns available slots;
  2. `POST /schedulingLinks/routing/[routeId]/schedule-simple` – books one of the slots.



Link types supported:

  * **Personal** – a link created by a user in ChiliCal for a specific meeting type;
  * **Admin (one-on-one)** – the same as Personal, but created by an admin on behalf of a user;
  * **Round Robin** – a team link that rotates assignment across members, either strict (equal turns) or flexible (weighted by availability);
  * **Group** – a link with a fixed set of multiple attendees (availability is the intersection of all required attendees);
  * **Ownership** – routes to the owner of the guest's CRM record (lead, contact, or account owner), resolved at booking time.



Use the scheduling link list endpoints (`scheduling-link-list-round-robin`, `scheduling-link-list-ownership`, `scheduling-link-list-group`, `scheduling-link-list-admin-one-on-one`) to discover available links programmatically.

### Example

**Step 1 – initialize a scheduling session:**
    
    
    curl -X POST \
      "https://fire.chilipiper.com/api/fire-edge/v1/org/schedulingLinks/init-simple" \
      -H "Authorization: Bearer $CHILI_PIPER_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "link": { "type": "RoundRobin", "linkId": "[linkId]" },
        "interval": { "startsAt": "2026-04-14T00:00:00Z", "duration": "7 days" }
      }'
    

The response includes a `routeId` and a list of `startTimes`. Pick one.

For **Ownership** links, also pass `guestEmail` in the init call – it is required so Chili Piper can resolve the owner from your CRM.

**Step 2 – book the chosen slot:**
    
    
    curl -X POST \
      "https://fire.chilipiper.com/api/fire-edge/v1/org/schedulingLinks/routing/[routeId]/schedule-simple" \
      -H "Authorization: Bearer $CHILI_PIPER_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "startTime": "2026-04-14T17:00:00Z",
        "guestEmail": "lead@example.com"
      }'
    

The response includes a `meetingId`. Calendar invites go out immediately.

* * *

## Handoff

**When to use:** a rep is handing off a lead to another team member – for example, an SDR booking a discovery call with an AE. Handoff uses the rules in a Handoff router to evaluate availability and returns time slots per routing path.

**The two calls:**

  1. `POST /handoff/workspace/{workspaceId}/booker/{userId}/init-simple` with the guest's email or CRM record and an `interval` – evaluates routing paths and returns available slots per path;
  2. `POST /handoff/routing/{routingId}/router/{routerId}/path/{pathId}/booker/{userId}/schedule-simple` – books one of the returned slots.



The init request body has two forms:

  * `{type: "GuestEmailRequest", guestEmail, interval}` – when you have the guest's email address;
  * `{type: "CrmRequest", id, interval}` – when you have the CRM record ID (lead or contact) and want Chili Piper to resolve from there.



Both accept optional fields:

  * `routerId` – target a specific router in the workspace instead of evaluating all routers;
  * `crmExplicits` – additional CRM context to pass through to routing rules.



The init response returns one or more routing paths, each with its own `pathId` and `startTimes`. Pick a path and a slot, then pass the corresponding `routingId`, `routerId`, `pathId`, and `startTime` to the schedule call.

### Example

Handoff requires a `workspaceId` and the Chili Piper `userId` of the rep initiating the handoff. Use the `workspace-list` and `user-find` endpoints (or MCP tools) to look these up.

**Step 1 – initialize the handoff and get available slots:**
    
    
    curl -X POST \
      "https://fire.chilipiper.com/api/fire-edge/v1/org/handoff/workspace/[workspaceId]/booker/[userId]/init-simple" \
      -H "Authorization: Bearer $CHILI_PIPER_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "type": "GuestEmailRequest",
        "guestEmail": "lead@example.com",
        "interval": { "startsAt": "2026-04-14T00:00:00Z", "duration": "7 days" }
      }'
    

The response includes a `routingId` and one or more `routers`, each containing `pathResults` with `startTimes`. Pick a path and a slot.

**Step 2 – book the chosen slot:**
    
    
    curl -X POST \
      "https://fire.chilipiper.com/api/fire-edge/v1/org/handoff/routing/[routingId]/router/[routerId]/path/[pathId]/booker/[userId]/schedule-simple" \
      -H "Authorization: Bearer $CHILI_PIPER_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "startTime": "2026-04-14T17:00:00Z" }'
    

The response includes a `meetingId`. Calendar invites are sent immediately.

* * *

## Running it via MCP instead

All three patterns are exposed as MCP tools. If you are building an AI assistant that reasons over Chili Piper – for example, a workflow that says "find the right scheduling link and book a slot this week" – MCP is the right surface. The tool names mirror the Edge operation IDs (`concierge-route-by-slug`, `concierge-schedule`, `scheduling-link-init`, `scheduling-link-schedule`, `handoff-init`, `handoff-schedule`, and the list discovery tools).

See [Connecting Chili Piper via MCP](https://help.chilipiper.com/hc/en-us/articles/50430350863635-Connecting-Chili-Piper-via-MCP) for setup.

The Edge API and MCP resolve to the same backend. Choose MCP when you want an assistant to pick the tool dynamically; choose Edge when you are writing deterministic integration code.

* * *

## Good to Know

  * **Sessions are single-use.** On a schedule failure, do not retry the schedule call with the same `routeId` – start again from the discover or route step;
  * **Sessions expire.** For Concierge, the timeout is configured per router path and returned in the response as `timeoutInMS`. For scheduling links and Handoff, sessions have a server-side TTL. In all cases, if the session expires before you book, call the first step again to get a fresh session;
  * **Pass**`**options.trigger**`**explicitly on Concierge calls.** If a router has multiple triggers configured, omitting this can cause the API to pick a different trigger than your `form` keys were written for. Accepted values: `ThirdPartyForm`, `InAppButton`, `RouterLink`;
  * **Token permissions matter.** Each pattern needs the **Schedule** permission in its section (**Concierge** , **Scheduling-links** , or **Handoff**). Add **Read** in any section where you also need to list assets via API – for example, listing scheduling links by type, or listing Concierge routers. Generate tokens with only the permissions you need;

  * **Slot times are UTC.** The `startTime` in responses is ISO-8601 UTC; pass it back verbatim on the book call.



* * *

## Related articles

  * [Edge API References](https://help.chilipiper.com/hc/en-us/articles/35576029581971-Edge-API-References) – complete list of Edge API operations and token generation steps;
  * [Using Concierge via the Edge API](https://help.chilipiper.com/hc/en-us/articles/30935152032275) – detailed Concierge-specific guide covering both URL-embed and programmatic booking;
  * [Connecting Chili Piper via MCP](https://help.chilipiper.com/hc/en-us/articles/50430350863635-Connecting-Chili-Piper-via-MCP) – setup for AI-assistant-driven booking via Claude Code and other MCP clients.



* * *
