MCP and API v1 · version 2026-10-06
Use Owlbound from Claude, ChatGPT or code
Connect Owlbound to Claude, ChatGPT or Claude Code and work your GTM workspace in plain language, or call the same actions from code. Every action is a dry run first, a person approves every send, and nothing spends past a cap.
Last updated from API version 2026-10-06 at (live spec, refreshed hourly). openapi.json
Connect Claude, ChatGPT or Claude Code
Owlbound is a remote MCP server. Add it once to your AI app, sign in with your Owlbound account, and the app can read your workspace and prepare actions for you. Every client uses the same URL:
https://app.owlbound.ai/api/v1/mcpClaude (web and desktop)
- Open Settings > Connectors and choose Add custom connector. On a Team or Enterprise plan, an owner adds the connector once in the organization's admin settings, then each member connects their own account.
- Name it
Owlbound, paste the connector URL and add it. Leave the advanced OAuth fields empty. - Choose Connect, sign in to Owlbound and allow access on the consent screen.
- In a chat, turn the Owlbound tools on from the tools menu and ask away.
ChatGPT
- Open Settings > Apps and Connectors. Under Advanced settings, turn on Developer mode if your plan asks for it.
- Create a connector: name it
Owlbound, paste the connector URL and choose OAuth as the authentication. - Sign in to Owlbound and allow access, then add the connector to a chat.
Claude Code
claude mcp add --transport http owlbound https://app.owlbound.ai/api/v1/mcpThen run /mcp in Claude Code, pick owlbound and authenticate: your browser opens the Owlbound sign in and consent screen. Add --scope project to share the server with your team through the project's .mcp.json (each person still signs in as themselves).
Grok, Gemini and other AI apps
The same connector URL works in any app that supports remote MCP servers. Step by step guides:
- Connect Grok: a custom connector, sign in with your Owlbound account.
- Connect Gemini Enterprise: an admin adds Owlbound in Google Cloud with an OAuth app you create in Owlbound, then each person signs in.
- Connect Gemini CLI: one entry in
settings.json, then sign in from the terminal.
The consumer Gemini app (gemini.google.com) is not tested yet: see the note in the Gemini Enterprise guide.
With an API key instead
For scripts, CI or an MCP client without sign in, send a v1 API key (Settings > Settings > Workspace > Developer) as a Bearer token. The tools are limited to the key's scopes and daily caps.
claude mcp add --transport http owlbound https://app.owlbound.ai/api/v1/mcp \
--header "Authorization: Bearer $OWLBOUND_API_KEY"More client setups and protocol details are in the MCP guide.
Sign in, scopes and disconnecting
The consent screen shows which app is asking, lets you pick the workspace, and lists what the app may do. The app acts as you, in that one workspace, with your own sender (your connected LinkedIn account and mailbox). Untick any scope you do not want to grant.
| Scope | Lets the app |
|---|---|
read | See your contacts, companies, tables, runs, credit balance and approvals. Free. |
enrich | Run enrichments, lists, scoring, research and AI writing that spend credits. |
write | Create and update contacts, tables and lists in the workspace. |
act | Prepare LinkedIn, email, sequence and CRM actions. Every one still waits for your approval in Owlbound. |
- Viewers can grant
readonly. Other roles can grant all four. - A connected app can never approve its own sends, change billing, buy credits, or manage members, keys or settings.
- Disconnect any app in Settings > Connected apps. Access stops at once; actions it already created stay in Owlbound and still wait for approval. Removing a member from the workspace disconnects their apps too.
How actions work
Reads answer straight away. Anything that spends credits, changes data or reaches someone outside your workspace runs in steps, so you always see what will happen before it does.
- Dry run. The app calls an action tool without applying it. Nothing runs and nothing is charged.
- Plan. Owlbound answers with the targets it would run, the ones it would skip and why, the credit range, whether a person must approve, and a
planId. Your AI app shows you the plan. - Apply. On your go, the app calls the same tool again with the same arguments,
apply: trueand thatplanId. Only that exact plan runs, within 15 minutes of the dry run and from the same session. - Approve. Sends and writes to outside systems are not sent yet: they wait in Approvals in the Owlbound app, where the owner of the sender (or someone they delegated to) reviews the rendered messages and approves or rejects them.
- Track. The app follows the run with
action_runs_get(and its per target list) until it finishes, then reports what happened.
Nothing is sent without a person
No tool can approve, reject or change settings. LinkedIn messages and invitations, emails, WhatsApp, sequence enrollments, CRM writes, notifications and HTTP calls all wait for a person in the app, whatever the app or the key asks. Approved content is frozen, and the same kind of send never reaches the same person twice from your sender within 30 days.
- Credits only on success. The plan holds at most its maximum; you are charged only for targets that succeeded. Reads are free.
- Daily caps. Every member and key has a daily credit and send cap, and an AI app gets half of yours. Sends also follow your LinkedIn account's and mailbox's own daily limits.
- Approvals expire. An approval not decided within 72 hours sends nothing.
What the tools cover
Your AI app reads the full tool list, with every argument, from the server. Tools are grouped by job:
| Job | Tools |
|---|---|
| Read the workspace | Contacts (with contacts_search), companies and their contacts, meetings (meetings_list, meetings_get), sequences with their enrollments, analytics and replies (sequences_*), your senders (identities_list), tables and their rows, credits and prices (credits_get, credits_costs_list), events, approvals and action runs (approvals_*, action_runs_*). Free. |
| Stop a run | action_runs_cancel stops the targets of an action that have not started yet. Targets already running finish, and nothing more is charged. |
| Build lists | actions_lists_*: Sales Navigator, LinkedIn search, saved audiences (ICPs), companies, a company's employees or decision makers, post engagers, website visitors. |
| Find and enrich | actions_find_* (LinkedIn URL, company and profile ids), actions_enrich_* (work email, mobile phone), actions_research_* (company website, news, web). |
| Score and write | actions_score_contact against an ICP, actions_ai_* (message, icebreaker, subject line). |
| Update contacts | actions_contacts_*: tag, set status or fields, assign an owner, link to an ICP, archive. |
| Reach people | actions_sequences_* (enroll, pause, resume, stop), actions_linkedin_*, actions_email_send, actions_whatsapp_send. Every send waits for a person. |
| Your other tools | actions_crm_* (HubSpot and more), actions_notify_* (Slack, Google Chat), actions_http_call, actions_plays_trigger. Every write or send waits for a person. |
Recipes
Ask in plain language. These prompts work as written in Claude, ChatGPT and Claude Code.
Score contacts against an ICP
Score the contacts in my "Q4 fintech" table against my Fintech CFO ICP.
Enrich any that are missing a job title or company first, then show me the top 20.- Scoring needs something to match on: a job title with a company or industry, or enrichment data. A contact without it is skipped as not enriched, and nothing is charged for it.
- The plan lists skipped contacts, so enrich those first (for example with
actions_find_linkedin_urland the enrich tools), then score again.
Build a list into a table
Build a list of heads of sales at French SaaS companies with 50 to 200
people from this Sales Navigator search: <url>. Put them in a new table
called "FR SaaS heads of sales". Show me the count and cost before you run it.- The
actions_lists_*tools find people or companies and write them into a table in your workspace, one row per person. - The dry run gives the count and the credit range. Lists that read LinkedIn run on your connected LinkedIn account.
Enrich and write messages
For the first 50 rows of "FR SaaS heads of sales": find their LinkedIn
URL where it is missing, find a work email, then draft a short first
message for each that mentions their company's latest news.- Each step is its own dry run and plan, so you see the credits per step and can stop at any point.
- Drafted messages are saved to the contact's message history and nothing is sent. Sending is a separate action that waits for your approval.
Learn from your meetings
Which priorities and objections came up in my meetings with Acme this
month? Then list the open next steps and who owns each one.- Add a meeting in the Owlbound app first: paste or upload a transcript, or connect Granola to import your notes every few minutes. Owlbound writes the notes and pulls out priorities, pains, objections, competitors and next steps.
- Your AI app reads them with
meetings_listandmeetings_get, linked to the right companies and contacts. Reading is free.
Run sequences
Enroll the 30 best scored contacts from "Q4 fintech" into my
"Fintech CFO intro" sequence. Then pause everyone at Acme in that sequence.- Enroll and resume wait for your approval in the app; pause and stop take effect when applied.
- The sequence must already exist. Creating and editing sequences is done in the Owlbound app for now.
Stop a run
Stop the work email search you started on "FR SaaS heads of sales".- The app calls
action_runs_cancel: targets not started yet are canceled, and credits are charged only for what already succeeded.
REST API quickstart
The MCP tools are API v1 operations. Call them from your own code with a key; the rest of this page covers the API. Older v0 keys and paths are deprecated: see v0 deprecation and migration.
1. Create a v1 API key
In the app, open Settings > Settings > Workspace > Developer and create an API key. Choose its scopes, optionally bind it to one sending identity, and set its daily caps. The key starts with owl_sk_ and is shown once: store it in your secret manager or an environment variable, never in a browser or a repository.
export OWLBOUND_API_KEY="owl_sk_..."2. Make your first call
GET /api/v1/me needs no scope and returns the key, its workspace, its scopes and its rate limits. Send the key as a Bearer token (X-API-Key works too) and pin the version you built against with Owlbound-Version.
curl "https://app.owlbound.ai/api/v1/me" \
-H "Authorization: Bearer $OWLBOUND_API_KEY" \
-H "Owlbound-Version: 2026-10-06"{
"data": {
"workspace": { "id": "<workspaceId>", "name": "Acme", "plan": null, "status": "active" },
"apiKey": {
"id": "<apiKeyId>",
"name": "Production",
"keyPrefix": "owl_sk_...",
"scopes": ["read", "write", "enrich"],
"identityId": null,
"apiVersion": "2026-10-06",
"expiresAt": null
},
"rateLimit": { "requestsPerMinute": 60, "requestsPerHour": 1000, "requestsPerDay": 10000 }
},
"meta": { "requestId": "<requestId>", "credits": { "used": 0 } }
}rateLimit shows your key's own limits (the values above are an example); -1 means unlimited.
3. Do something useful
Follow Build a list into a table: one dry run tells you how many people a search finds and what it would cost, then the same call with the plan builds the table.
Authentication and scopes
Every operation except GET /api/v1/health and GET /api/v1/openapi.json needs a key. A key holds one or more scopes; each operation in the reference names the scope it needs (403 INSUFFICIENT_SCOPE otherwise).
| Scope | Lets the key |
|---|---|
read | Read contacts, companies, sequences, tables, credits, actions, events and approvals; run free read actions. |
write | Change workspace data: tables, columns, rows, views, imports and exports, webhook endpoints, and workspace-only actions such as tagging a contact. |
enrich | Run actions that spend credits on data or AI: lists, find, enrich, score, research and AI content. |
act | Run actions that touch someone outside the workspace: LinkedIn, email, WhatsApp, sequence enrollment, CRM writes, notifications and HTTP calls. Sends still wait for a person. |
A key can be bound to an identity(a member's LinkedIn account or mailbox). A bound key always acts as that identity; an unbound key passes identityId on actions that need one.
Versioning
The API is versioned by date. Each key is pinned to the version current when it was created; send Owlbound-Version: 2026-10-06 to choose one explicitly. Every response echoes the version that served it in the Owlbound-Version header. Changes inside a version are additive: clients must ignore unknown fields and unknown enum values.
Responses and errors
Every JSON response uses one envelope: {data, meta} on success, {error} on failure. The meta.requestId (also the X-Request-Id header) identifies the request: quote it to support.
{
"error": {
"type": "permission",
"code": "INSUFFICIENT_SCOPE",
"message": "This operation needs the enrich scope.",
"requestId": "<requestId>",
"docUrl": "https://owlbound.ai/docs/api/errors#INSUFFICIENT_SCOPE",
"param": null
}
}Branch on error.code, never on the message. Every code is listed with what to do on the errors page, and docUrl links straight to it.
Idempotency keys
Retries are safe with an Idempotency-Key header (1 to 255 printable characters, for example a UUID) on POST, PATCH and DELETE. Operations marked required in the reference refuse a write without one.
- A repeat of a finished request returns the stored response with
Idempotent-Replayed: true. Nothing runs again and nothing is charged again. - While the first request is still running, a repeat gets
409 IDEMPOTENCY_IN_PROGRESSwithRetry-After. - The same key with another body is
422 IDEMPOTENCY_KEY_REUSED. Use one key per distinct request. - Keys are kept 24 hours and scoped to your API key (and the keys it is rotated into).
- 2xx and 4xx results are stored and replayed. After a
402 INSUFFICIENT_CREDITS, add credits and retry with a new key. A 5xx is not stored: retry with the same key.
Pagination
Lists are cursor paginated. Pass limit (1 to 200, default 50) and, for the next page, the cursor from meta.page.nextCursor. meta.page.hasMore is the only end signal: pages may be shorter than the limit. Keep the same filters for every page (400 CURSOR_MISMATCH otherwise).
async function* allContacts() {
let cursor;
do {
const url = new URL("https://app.owlbound.ai/api/v1/contacts");
url.searchParams.set("limit", "200");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.OWLBOUND_API_KEY}` },
});
const { data, meta } = await res.json();
yield* data;
cursor = meta.page.hasMore ? meta.page.nextCursor : undefined;
} while (cursor);
}Rate limits
Requests are limited per key and per workspace, per minute, hour and day. Your key's limits are in GET /api/v1/me (data.rateLimit); responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset for the minute window. Over a limit the answer is 429 RATE_LIMITED with Retry-After (seconds): wait, then retry. It is answered before anything runs, so the retry is safe.
Heavy operations (imports, exports, pushes) count as several requests: the reference shows their rate weight. Sends also follow the identity's own LinkedIn and mailbox limits, which no key can lift (see approvals and never-twice).
Credits
Reads are free. Priced operations hold their maximum price before they run and charge, at most that, only for what succeeded; meta.credits.used and the X-Owlbound-Credits-Used header report the charge. One credit is $0.01 list value. The price list is GET /api/v1/credits/costs and every priced operation shows its price in the reference. Daily caps per key stop runaway spend: see credits, caps and pricing.
Base URL and spec
| What | Where |
|---|---|
| API base URL | https://app.owlbound.ai/api/v1 |
| OpenAPI 3.1 document (no key) | https://app.owlbound.ai/api/v1/openapi.json |
| Health (no key) | GET https://app.owlbound.ai/api/v1/health |
| MCP server | https://app.owlbound.ai/api/v1/mcp |
Always current
The reference on this site is generated from the live OpenAPI document and refreshed every hour, so it never drifts from what the API serves.
Guides
- Tables in the app: Start a table from a source, add enrichment, AI and action columns, run them with an estimate, and send after approval.
- Build a list into a table: Turn a Sales Navigator search, a LinkedIn search or a saved audience into a table with one call.
- Enrich with action columns: Add enrichment, AI and action columns, estimate them, and run them under a hard credit cap.
- Push to a sequence or CRM: Send table rows to contacts, an existing sequence or HubSpot, with review before anything goes out.
- Dry runs, plans and applying: See exactly what an action would do, then run that exact plan, or nothing.
- Approvals and never-twice: Why sends wait for a person, who approves, and how Owlbound guarantees a person is never contacted twice.
- Credits, caps and pricing: How priced operations hold, charge and cap credits, and where to read the price list.
- Async runs and events: Follow long actions with bounded long polling, per-target status and the event feed.
- Webhooks: Receive signed events on your endpoint: verify, rotate, retry, redeliver and disable.
- MCP clients and protocol: Connect any MCP client with sign in or an API key, and how the server speaks MCP.
- Connect Grok: Add Owlbound as a custom connector in Grok and sign in with your Owlbound account, or use a key from the xAI API.
- Connect Gemini Enterprise: Create an OAuth app in Owlbound, add it as a custom MCP server in Google Cloud, and let each person sign in.
- Connect Gemini CLI: Add Owlbound to your Gemini CLI settings and sign in from the terminal, or use an API key for scripts.
- CLI: Run the whole list, table, enrich and push flow from a terminal (early access).
- v0 deprecation and migration: Legacy v0 keys stop working on 31 January 2027. How to move to v1.