npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-floyd

v0.1.4

Published

n8n community node for Floyd - atomic booking holds for AI agent workflows

Readme

n8n-nodes-floyd

n8n community node for Floyd — atomic booking holds for AI agent workflows.

Problem: Voice agents and booking workflows can double-book when two requests race for the same slot. Calendar APIs don't prevent this.

Solution: Create a short-lived hold that blocks the slot while your agent confirms with the user. Only one workflow can win; everyone else gets an explicit conflict.

Installation

npm install n8n-nodes-floyd

Or in n8n: Settings → Community Nodes → Install → n8n-nodes-floyd

Quickstart

  1. Get your API key: console.floyd.run → Organization → API Keys
  2. Get a resource ID: Console → Resources → Create → Copy ID
  3. Time format: ISO 8601 with timezone (e.g., 2026-01-12T14:00:00Z)
  4. Add Floyd node: In n8n, search for "Floyd" and select an action
  5. Three operations: Create Hold → Confirm Booking → Cancel Booking

The Floyd Node

The Floyd node provides three operations for atomic booking workflows:

Operation: Create Hold

Reserve a time slot with a TTL. The hold expires automatically if not confirmed.

Inputs

| Field | Type | Required | Description | | ---------------- | -------- | -------- | ----------------------------------------- | | resourceId | string | Yes | The resource to book | | startAt | datetime | Yes | Slot start time (ISO 8601) | | endAt | datetime | Yes | Slot end time (ISO 8601) | | ttlSeconds | number | No | Hold expiration in seconds (default: 300) | | idempotencyKey | string | No | For retry-safe workflows | | metadata | JSON | No | Arbitrary payload (customer info, etc.) |

Options

| Option | Default | Description | | ---------------------------- | ------- | --------------------------------------------------------------------------------- | | Return conflicts as output | ON | If ON, 409 conflicts flow as output (branchable). If OFF, node fails on conflict. |

Outputs

Success:

{
  "bookingId": "bk_abc123",
  "status": "pending",
  "expiresAt": "2026-01-11T10:05:00Z",
  "requestId": "req_xyz789"
}

Conflict (when another hold/booking exists):

{
  "outcome": "conflict_overlap",
  "message": "Booking overlaps with existing pending or confirmed booking",
  "requestId": "req_xyz789"
}

Operation: Confirm Booking

Finalize a pending hold to convert it to a confirmed booking. Clears the expiration timer.

Inputs

| Field | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------- | | bookingId | string | Yes | The booking ID from Floyd Create Hold |

Outputs

Success:

{
  "bookingId": "bk_abc123",
  "status": "confirmed",
  "resourceId": "res_xyz",
  "startAt": "2026-01-13T10:00:00Z",
  "endAt": "2026-01-13T11:00:00Z",
  "confirmedAt": "2026-01-12T16:00:00Z",
  "requestId": "req_xyz789"
}

Errors:

  • 404: Booking not found
  • 409: Hold expired or already confirmed

Operation: Cancel Booking

Cancel a pending hold or confirmed booking. Releases the time slot and makes it available.

Inputs

| Field | Type | Required | Description | | ----------- | ------ | -------- | ------------------------ | | bookingId | string | Yes | The booking ID to cancel |

Outputs

Success:

{
  "bookingId": "bk_abc123",
  "status": "cancelled",
  "resourceId": "res_xyz",
  "startAt": "2026-01-13T10:00:00Z",
  "endAt": "2026-01-13T11:00:00Z",
  "cancelledAt": "2026-01-12T16:00:00Z",
  "requestId": "req_xyz789"
}

Errors:

  • 404: Booking not found
  • 409: Already cancelled or cannot cancel

Usage Examples

Voice Agent Booking Flow

Complete workflow with user confirmation:

┌────────────────────────┐
│ Webhook (Vapi/Retell)  │
└────────────┬───────────┘
             │  User: "Book me at 2pm"
             ▼
┌────────────────────────┐
│ Floyd: Create Hold     │
└────────────┬───────────┘
             │  Reserve slot (TTL: 5 min)
             ▼
┌────────────────────────┐
│ IF: conflict?          │
└────────────┬──────┬────┘
             │      │
             No     Yes
             │      │                ┌────────────────────────┐
             │      └──────────────▶ │ Respond: "Try 3pm?"    │
             │                       └────────────────────────┘
             ▼
┌────────────────────────┐
│ Ask user to confirm    │
└────────────┬──────┬────┘
             │      │
             Yes    No
             │      │                ┌────────────────────────┐
             │      └──────────────▶ │ Floyd: Cancel Booking  │
             │                       └────────────┬───────────┘
             │                                    │
             │                                    ▼
             │                       ┌────────────────────────┐
             │                       │ Respond: "Cancelled"   │
             │                       └────────────────────────┘
             ▼
┌────────────────────────┐
│ Floyd: Confirm Booking │
└────────────┬───────────┘
             │
             ▼
┌────────────────────────┐
│ Respond: "Confirmed!"  │
└────────────────────────┘

Simple Confirmation Flow

  1. Floyd: Create Hold → Get bookingId
  2. User confirms → Floyd: Confirm Booking with bookingId
  3. User cancels → Floyd: Cancel Booking with bookingId

Hold Expiration (No Action)

If you don't confirm or cancel within ttlSeconds, the hold expires automatically:

Floyd: Create Hold (ttlSeconds: 300)
    │
    └─ 5 minutes pass...
    └─ Hold expires (no action needed)

Why holds instead of check-then-book?

The Problem with Check-Then-Book

The typical pattern:

  1. Check availability
  2. Ask user to confirm
  3. Book the slot

The problem: Between step 1 and step 3, another request can book the same slot. You get double-bookings.

The Floyd Solution

Three-phase lifecycle:

  1. Create Hold (atomic, blocks the slot) → status: "pending"
  2. Ask user to confirm (slot is protected for ttlSeconds)
  3. Confirm (finalize) → status: "confirmed" OR Cancel (release) → status: "cancelled"

Benefits:

  • ✅ Only one workflow can hold a slot
  • ✅ Conflicts are explicit (409 responses)
  • ✅ Automatic cleanup (holds expire after TTL)
  • ✅ Retry-safe (idempotency keys)
  • ✅ Works with voice agents, forms, multi-step workflows

Credentials

  1. Sign up at console.floyd.run
  2. Create an organization and API key
  3. In n8n: Credentials → New → Floyd API
  4. Paste your API key
  5. (Optional) Toggle "Show Advanced Options" to change the Base URL (for staging/self-hosted)

Links

Troubleshooting

| Error | Node | Cause | Fix | | -------------------------------- | --------------- | ------------------------------------- | --------------------------------- | | 409 Conflict (overlap) | Create Hold | Slot already held/booked | Branch and offer alternative | | 409 Conflict (hold expired) | Confirm Booking | Hold TTL expired | Create new hold | | 409 Conflict (already confirmed) | Confirm Booking | Booking already finalized | Check booking status | | 409 Conflict (already cancelled) | Cancel Booking | Booking already cancelled | No action needed | | 404 Not Found | Confirm/Cancel | Invalid booking ID | Verify bookingId from Create Hold | | 422 Validation | Create Hold | Bad date format or endAt <= startAt | Check ISO 8601 format | | 401 Unauthorized | All | API key missing or wrong | Check credentials |

Need help? Include the requestId from the output when contacting support.

License

MIT