# Booking Link Finder: Calendly, Cal.com & More (`bowmark-ai/booking-link-finder`) Actor

Find the public Calendly, Cal.com or HubSpot meeting link a person publishes. Give names and company domains, get booking links with the page each was found on and a confidence level.

- **URL**: https://apify.com/bowmark-ai/booking-link-finder.md
- **Developed by:** [Bowmark AI](https://apify.com/bowmark-ai) (community)
- **Categories:** Lead generation, MCP servers, Agents
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $22.00 / 1,000 person searcheds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Booking Link Finder do?

Booking Link Finder finds the **public meeting link a person publishes**: their Calendly, Cal.com, HubSpot Meetings, SavvyCal, TidyCal, Chili Piper or similar booking page.

Give it a list of names, ideally with each person's company website. For every person it returns the booking link it found, the page it was written on, and how confident the match is.

It never books a meeting. It only finds and reports the link.

### Why use it?

- **Outbound and lead generation.** Put a founder's or sales lead's own booking link next to their name in your CRM, so your team can book straight in.
- **Partnerships and recruiting.** Skip the "what time works for you?" email chain when someone already publishes a calendar.
- **AI agents.** Connect it as an MCP server and let an agent look up booking links while it researches a prospect.

### How it finds a link

For each person it checks, at the same time:

1. **Their company website.** The homepage plus the about, team, contact and services pages, looking for a booking link written on the page.
2. **Their GitHub profile** and any personal pages you pass in `urls`.
3. **Search results** for their name on booking platforms.
4. **Their name as a booking address**, such as `calendly.com/first-last` or `cal.com/first-company`.
5. Optionally, **old copies of their company website**, to catch a link that has since been removed.

Results are sorted strongest first.

### Confidence levels

Every link carries a `confidence` value, so you can decide what to trust:

| Confidence | What it means |
|---|---|
| `published` | Written on a page about this person, such as their company's team page. The strongest evidence. |
| `archived` | Written on an older copy of their company's website. It may have been removed since. |
| `indexed` | A search engine lists a booking page under this person's name. |
| `name_match` | A booking page exists at an address built from their name. Someone else with the same name may own it. Turn these off with **Include unconfirmed name matches**. |

### Input

| Field | Required | Description |
|---|---|---|
| `people` | Yes | A list of people. Each needs a `name` (first and last). Add `domain` and `company` whenever you can: they make results much more accurate. Optional: `github`, `urls`. |
| `searchArchive` | No | Also read old copies of the company's website. Slower. Default `false`. |
| `includeNameMatches` | No | Include `name_match` links. Default `true`. |
| `maxConcurrency` | No | People searched at once, 1 to 8. Default `4`. |

Example input:

```json
{
  "people": [
    { "name": "Caleb Peffer", "company": "Firecrawl", "domain": "firecrawl.dev" },
    { "name": "Jane Doe", "domain": "example.com" }
  ],
  "includeNameMatches": true
}
```

### Output

One dataset row per person. Download it as JSON, CSV, Excel or HTML, or read it through the Apify API.

```json
{
  "name": "Christopher Powroznik",
  "company": null,
  "domain": "bowmark.ai",
  "status": "found",
  "bookingUrl": "https://calendly.com/christopher-bowmark-ai/bowmark-discovery",
  "platform": "calendly",
  "confidence": "published",
  "foundOn": "https://bowmark.ai/",
  "context": "Book a call",
  "links": [
    { "url": "https://calendly.com/christopher-bowmark-ai/bowmark-discovery", "platform": "calendly", "confidence": "published", "foundOn": "https://bowmark.ai/" },
    { "url": "https://calendly.com/christopher-bowmark-ai", "platform": "calendly", "confidence": "name_match", "ownerName": "Christopher Powroznik" }
  ],
  "pagesScanned": 2,
  "warnings": ["1 link(s) match only the person's name, so someone else with the same name may own them. Check the owner name on the booking page, or pass `domain` so a link they published ranks first."],
  "error": null
}
```

`status` is `found`, `not_found` or `error`. A person with no public booking link comes back as `not_found`, which is a real answer: many people do not publish one.

### Pricing

**$0.022 per person searched**, with no monthly fee. That is $22 per 1,000 people.

- You pay the same whether or not a link is found, because the search does the same work either way.
- A lookup that fails with an error is not charged.
- Set a spending limit on the run and the Actor stops cleanly when it reaches it.
- On Apify's free plan, each run looks up the first 10 people (10 tool calls per MCP session). Any paid Apify plan removes the limit.

### Use it as an MCP server

This Actor also runs as an MCP server with one tool, `find_booking_links`. Point any MCP client (Claude, Cursor, ChatGPT, your own agent) at:

```
https://bowmark-ai--booking-link-finder.apify.actor/mcp
```

with your Apify API token as a bearer token. Each tool call is billed like one person in a normal run.

### Limits and good practice

- It reads only **public** pages. It never signs in anywhere and never books anything.
- Pass the company `domain`. Without it, only the name-based checks can run and most results will be `name_match`.
- A `name_match` or `indexed` link is not proof of identity. Check the owner name on the page before you rely on it.

### Questions or a wrong result?

Open an issue on the **Issues** tab with the name you searched and what you expected. We read every one.

# Actor input Schema

## `people` (type: `array`):

The people to look up, up to 500 per run (10 on Apify's free plan). One object per person. `name` (first and last) is required. Add `domain` (their company website) and `company` whenever you know them: they make the search much more accurate. Optional: `github` (a handle you read on a page about them) and `urls` (their personal site, speaker bio or blog).

## `searchArchive` (type: `boolean`):

Also read archived copies of the company's about, team and contact pages, to catch a link that has since been removed. Slower, often 10 to 30 seconds more per person.

## `includeNameMatches` (type: `boolean`):

Also return links that only match the person's name, such as calendly.com/first-last, with no page tying them to this person. Someone with the same name can own these, so each one is marked `confidence: name_match`.

## `maxConcurrency` (type: `integer`):

How many people are looked up in parallel.

## Actor input object example

```json
{
  "people": [
    {
      "name": "Caleb Peffer",
      "company": "Firecrawl",
      "domain": "firecrawl.dev"
    }
  ],
  "searchArchive": false,
  "includeNameMatches": true,
  "maxConcurrency": 4
}
```

# Actor output Schema

## `results` (type: `string`):

One row per person: the strongest booking link found, its platform, confidence and the page it was found on.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "people": [
        {
            "name": "Caleb Peffer",
            "company": "Firecrawl",
            "domain": "firecrawl.dev"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bowmark-ai/booking-link-finder").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "people": [{
            "name": "Caleb Peffer",
            "company": "Firecrawl",
            "domain": "firecrawl.dev",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("bowmark-ai/booking-link-finder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "people": [
    {
      "name": "Caleb Peffer",
      "company": "Firecrawl",
      "domain": "firecrawl.dev"
    }
  ]
}' |
apify call bowmark-ai/booking-link-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bowmark-ai/booking-link-finder"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Twe7yredBewPOWTwi/builds/c8q2VIQRykUPpPTHa/openapi.json
