- Brand
- Draftboard
- Category
- Sales & CRM
- Primary Subcategory
- B2B Prospecting & Contact Data
Integration details
Description
Draftboard finds the warm introduction to the person you want to reach. Ask who can introduce you to a prospect, and you get the people in your own network who know them, how strong each relationship is on a 0-100 scale, and the shared history behind it, such as years at the same company or the same school. Use it to see your best introduction opportunities right now, check whether you are already connected to someone, review every path to one prospect, see which of your saved prospects a teammate can reach, and track how your introductions are going. You can also rate the people you would ask for an introduction, label who they are to you, and save new prospects from LinkedIn. Draftboard works only on the data in your own Draftboard account, and every answer says how much of it was checked. Sign-in happens in your browser and can be revoked at any time from Settings, Connected apps. A Draftboard account with a scanned network is required.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- B2B Prospecting & Contact Data
- Secondary Subcategories
- None listed
- Brand
- Draftboard
- Access
- Account required
- First tracked
- 2026-10-30
- Tool count
- 28
- Market
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for Draftboard
Get updates when Draftboard’s Discoverability Score or category rank changes.
Competing in ChatGPT B2B Prospecting & Contact Data
View Category28 tools agents can invoke
WRITE / DESTRUCTIVE and NOT reversible via the public API. Soft-deletes a target: it disappears from list_targets and frees its capacity slot (associated intros remain as history). Requires `confirm: true` AND must be confirmed with the user first.
archive_target
WRITE. Attach tags (by id and/or name; names auto-create as manual tags) to one or more targets. Idempotent. All-or-nothing: if any target id is missing or foreign, the whole request is rejected. Caps: 1–500 targets, ≤50 tags, ≤5000 associations.
attach_tags_to_targets
Given LinkedIn profile URLs, report whether the customer already has warm paths to each person. Looks each URL up directly (one request per person, any book size), then returns per-URL `{status, isTarget, targetId, hasPaths, pathsCount, topConnector, topRank, degree, directlyConnected}`. `status` is `target`, `not_a_target`, `import_pending`, or `lookup_failed`. On `import_pending` and `lookup_failed` the booleans are `null`, NOT false — the answer is unknown, so never tell the user they have no path on the strength of it; re-check instead. By default it imports only the URLs that are not targets yet; Draftboard processes an import batch asynchronously, so those usually come back `import_pending` on this call and resolve moments later. For a SINGLE person where you only need the id or a yes/no, `resolve_target` is one call instead of two.
check_if_connected
WRITE. Promote pool prospects (by their `list_pool` ids) into saved targets — idempotent. Every requested id still in the pool is confirmed; nothing is held back. Returns `confirmedCount` and `remainingCapacity` (informational only, not a limit on what gets confirmed). This is how you keep the good people a search found; the rest can be left or `reject_pool`ed. Once confirmed they are real targets and their warm paths are charged like any Target's — tell the customer before confirming. `list_targets` / `find_top_paths` will include them (path scoring is async, so paths may take a moment).
confirm_pool
READ-ONLY. Count the network by label and by star rating in one cheap call — for 'how many investors do I know?', 'how is my network labelled?', or sizing a group before listing it. Takes exactly the filters of `list_network_connections` (same names, same meaning — `ownerIds` from `get_me` for your own or a teammate's network, omit for the team's combined list). Returns `{ total, unrated, ratings[{rating,count}] 5..1, labels[{label,scope,count}] (non-zero only), zeroLabels[] }`. EACH SECTION IGNORES ITS OWN FILTER: a label's count is what `list_network_connections` with `labels: [that label]` plus your other filters would return (your `labels`/`labelsMatch`/`excludeLabels` are not applied to it); `ratings` and `unrated` ignore `ratings`/`rating`/`tiers`; `total` applies every filter and equals that list's `count`. Ratings are the caller's own stars, 1..5 where HIGHER IS BETTER (5 = 'ask anytime', 1 = 'do not ask', which includes the people it hides); never describe a tier in stars. Personal labels and `supporter` are the caller's own as well. A label count of 0 means nobody has been given that label yet — labels are only what the team has set — NOT that the network holds no such people. When `unrated` is above 0, it is worth suggesting the user rate them (`set_connector_tier`). This only counts: to see the people, call `list_network_connections` with the same filters.
get_label_counts
READ-ONLY. Find companies where people in the team's network CURRENTLY work, by name (`query`) and/or by the labels the company carries (`labels`, `labelsMatch`). Returns `{ companies: [{ id, name, connectorsCount, labels[] }], count, nextPage }`. This is where a company id for `set_company_labels` comes from — `id` here is NOT an account id from `list_accounts`. `connectorsCount` is how many people in the network work there, i.e. how many a company label would reach. One company can show up as several rows (different spellings or records of the same employer), each with its own count — offer them all, do not pick silently. Paginated — loop until `nextPage` is 0.
find_network_companies
Your strongest open warm-intro paths, ranked, one per target: shared employer or school on both sides first, then between connector and target, then other quality paths — basis `other_quality_signal`, which carries NO work/school overlap label. Describe those only from `rankDetails` (e.g. "you both know 500 people") and never call them strong. One call, one path per target; for several connectors on one person use `get_target_connections` instead. Scope with accountId, tagNames, title, `roles` (job-title words on the target, any of them; expand synonyms yourself, e.g. founder, co-founder, cofounder), ownerIds, and `ratings` for paths only through people you would actually ask (e.g. [4,5]). Each opportunity carries `connectorRating`, your own star rating of the connector (higher is better), absent when you have not rated them. Filter by connector label with `connectorLabels` (+ `connectorLabelsMatch` all|any) — e.g. ["investor"] for paths through investors — and `excludeConnectorLabels`; each opportunity carries `connectorLabels` (org labels are shared with the whole team, personal ones are the caller's own, `supporter` mirrors a 2..5 rating). `do_not_contact` is a plain label that hides nobody unless the user asks to exclude it.
find_top_paths
List the warm-intro connections for one target: each connector's profile, relationship `score` (0-100, `rank` in the outcome tools), `scoreDetails` (the human-readable shared history — omitted when there is nothing to say, so read it as `scoreDetails ?? []`), and the team members (`owners`) whose network the connection comes from. Each connection also carries `rating`: YOUR star rating of that connector (1..5, higher is better), absent when you have not rated them — unrated is not a low rating. Filter by `ownerIds` to see paths through specific teammates, by `ratings` (e.g. [4,5]) for paths only through people you would actually ask, and by `connectorLabels` (+ `connectorLabelsMatch` all|any) / `excludeConnectorLabels` for paths through, say, investors ("paths to this person through our investors"). Each connection carries `labels`: who that connector is to the team (org labels are shared with the whole team, personal ones are the caller's own, `supporter` mirrors a 2..5 rating). `do_not_contact` is a plain label that hides nobody unless the user asks to exclude it. Paginated. A connection may also carry two structured relationship fields. `relationships`: how the connector and the target know each other — zero or more of exactly `current_colleague`, `former_colleague`, `university_classmate`, and no other value is ever emitted. `relationshipDetails`: the machine-readable facts behind `scoreDetails` — one record per shared company / school / mutual-contact signal, with exactly one of `employment` (`company`, `department`, `location`, `overlapStartDate`, `overlapEndDate` as ISO yyyy-MM-dd, `loose`, `unit`) / `education` (`school` + the same window) / `mutualConnections` (`count`) set, plus that record's `score`. BOTH KEYS ARE ABSENT WHEN EMPTY — the key is simply not in the JSON, it is never `[]` — so read them as `connection.relationships ?? []`. They are present when we hold that signal for the pair and omitted when we do not: absence means "we hold no structured signal for this pair", NOT "these two have no relationship". PROMOTE on the signal, NEVER demote on its absence — never drop or downrank a connector for it; `scoreDetails` carries the human-readable summary. The two fields are also INDEPENDENT: a connection whose only signal is shared contacts gets a `relationshipDetails` record and NO `relationships` entry, and a rank can carry `relationships` with no records. Never derive, gate or index-align one from the other or from `scoreDetails`.
get_target_connections
Return the authenticated customer: `{ id, name, customerProfileId, user{ id, firstName, lastName, linkedinUrl }, teamMembers[]{ id, firstName, lastName, linkedinUrl }, credits }`. Call this first to confirm whose account you are working with. `credits` is the team's credit balance: writes are paid from it and are refused only once it reaches 0. If `credits` is missing, the balance is unknown, not 0 — go ahead and try the write. `customerProfileId` is your own member id — pass it as `ownerIds` to scope to your own network (e.g. `list_network_connections` for 'my connections'). `teamMembers` is your team roster, you included — to filter through a teammate, match them by name here and pass their `id` as `ownerIds`. If several members fit the name, or none fits exactly, ask the user which one (full names) instead of guessing.
get_me
List the intro opportunities where a given connector is the connector — i.e. everyone this person can introduce you to, each with a relationship score and shared-history `scoreDetails`, plus the team members who can make the ask. Answers 'who can <this person> introduce me to?'. Each item may also carry `relationships` — how the connector and that target know each other, zero or more of exactly `current_colleague`, `former_colleague`, `university_classmate` — and `relationshipDetails`, the structured records behind `scoreDetails` (one per shared company / school / mutual-contact signal, exactly one of `employment` / `education` / `mutualConnections` set per record, dates ISO yyyy-MM-dd). BOTH KEYS ARE ABSENT WHEN EMPTY (never `[]`), so read them as `item.relationships ?? []`: absence means "we hold no structured signal for this pair", NOT "these two have no relationship" — promote on the signal, never demote on its absence, and keep reading `scoreDetails`, which carries the human-readable summary (it too is omitted when there is nothing to say). The two fields are independent: a mutual-contacts-only signal yields a `relationshipDetails` record and NO `relationships` entry, so never derive or index-align one from the other. The response's `connector` object also carries your personal star `rating` (1..5, higher is better; absent when unreviewed).
get_connector_intros
WRITE. Add people as supporters from their LinkedIn profile URLs (max 100 per call). Supporters are prioritized as warm-intro connectors.
import_supporters
Import one or more people as targets from their LinkedIn profile URLs, optionally tagging them. Tags are created if they do not exist. A success response means the batch was ACCEPTED, not finished, and there are TWO separate waits: the target rows appear within about half a minute, and their warm-intro paths are computed after that — minutes, and longer on a large network (14 minutes on a real account). To confirm a specific person landed, call `resolve_target` with the same URL: it returns the target as soon as the row exists, before any path. Do NOT confirm with `list_targets` (by tag, `updatedSince` or anything else) — it only returns targets that already have a path, so an empty result there is never evidence the import failed. Then poll `get_target_connections` for the paths.
import_targets
Summarize the customer's targets by status (new / completed / stopped), with an optional per-tag breakdown. Use to track progress across requested intros. Optionally scope to `tagNames`.
intro_status_overview
List the companies where the customer has saved targets, with per-account counts: saved targets, total paths, and how many are 1st- vs 2nd-degree reachable. Filter by company name (`query`) or by degree. Useful for an account-level view of where warm reach already exists.
list_accounts
READ-ONLY. List the team's network: the people it can ask for intros. This is the tool for 'my connections', 'my 1st-degree network', 'who does <teammate> know', and for exporting a network. WHOSE NETWORK: with `ownerIds` (ids from `get_me`: your own is `customerProfileId`, a teammate's is `teamMembers[].id`) you get exactly the LinkedIn 1st-degree connections of those members, and nobody else; to export the whole team's LinkedIn connections, pass every member's id. Without `ownerIds` you get the team's combined list, which is broader than LinkedIn: it also holds people added by hand as supporters, colleagues inferred from shared employers, and the team members themselves. Resolve a person by name from `get_me` yourself; if more than one roster member fits the name, or none fits exactly, ask the user which one, naming the candidates in full, before calling. Find people by name with `name` (typo-tolerant; if the response carries `nameMatch: "approximate"` nobody matched exactly, so present the rows as the closest names, not as the person asked for) or by job-title words with `roles` (expand synonyms yourself, e.g. founder, co-founder, cofounder); `query` is the older free-text search. Say whose connections you are showing. Each row's `owners` lists who on the team knows that person (the whole team, not narrowed by `ownerIds`). At most 100 per page: to read the whole list, keep requesting the next page until `nextPage` is absent or 0, and say how many you read. SEARCH BY RATING: each row carries the caller's personal star `rating`: 1..5 where HIGHER IS BETTER (5 = ★★★★★ 'ask anytime' … 1 = ★ 'don't ask'), absent when unreviewed. Each also carries `tier`, the same setting spelled as the raw wire number: 1..5 where LOWER IS BETTER (tier 1 = 'ask anytime' … tier 5 = 'don't ask'). Filter with `ratings` — `[5]` is 'my closest connections'. `tiers` is the same filter on the wire scale; the two are UNIONED, not intersected. HIDDEN: a connector rated 1 ('don't ask') is hidden from the listing. Without `ownerIds` that is YOUR rating, and a connector you rated 1 still shows while a teammate keeps them visible, carrying your own `rating: 1`. With `ownerIds` it is each listed member's own choice: people a teammate hid are left out of that teammate's list. `ratings: [1]` lists the ones YOU hid; there is no separate 'hidden' flag. This tool only READS the rating — to SET one, call `set_connector_tier`. LABELS: each row carries `labels` (who the person is to the team — org labels are shared with the whole team, personal ones are the caller's own, `supporter` mirrors a 2..5 rating). Filter with `labels` (+ `labelsMatch` all|any) and `excludeLabels`; `do_not_contact` is a plain label that hides nobody unless the user asks to exclude it. To SET labels call `set_connector_labels`.
list_network_connections
List the pool: potential prospects (status `new`) awaiting confirm/reject — the people a search found and held for review: everyone `search_supporters` finds, and those `search_accounts` found beyond its per-company limit. Each carries `id`, `name`, `linkedinUrl`, `headline`, `accountName`, `source`, `tags` and `icpFits`: one entry per supporter search that was given an ideal customer (`icp`) and found this person, each with `campaignId`, `percent` (0-100) and `reason`. No `percent` means that search could not assess the person — not a poor fit, and not 0; an empty `icpFits` means no such search found them. With `campaignId`, `icpFits` carries only that search's entry. A person fits when `percent` is 50 or more — the product's threshold; do not invent others. The pool never hides anyone: every person is returned whatever their fit, unless you pass `minIcpFit` (0-100, requires `campaignId`), which keeps only people that search scored at or above it and leaves out those it could not assess. To keep a review short, prefer `minIcpFit: 50` over paging through everyone. Review the fits with the customer before `confirm_pool`: say how many fit and that the rest are a poor fit or could not be assessed, and confirm only the people the customer chooses. Filter by `campaignId` (the id either search returned) to read one search's results, or by `accountId` / `tagIds` / `query`. Paginated (loop until `nextPage` is 0). A search fills the pool asynchronously, so an empty result may mean the results are not ready yet — it does not mean the search has finished or found nothing; check back later.
list_pool
List the customer's tags. Tag `type` is either `manual` (a label the customer created and applied themselves, e.g. via import or attach-tags) or `automatic` (a system-generated batch marker Draftboard stamps on everything ingested together — usually the date of the campaign/upload/discovery batch, e.g. "20-Apr-2026"). There is no queryable `icp` tag type. Use to discover tag names/ids before filtering targets. Paginated.
list_tags
List the customer's saved targets (leads) with status, best path rank (`maxRank`), path count (`pathsCount`), and tags. Returns only targets that ALREADY have at least one warm-intro path — a saved target still being indexed will not appear here (use `resolve_target` for those). Filter by tag, status, update time, **company** (`accountId`), or **title/position** (`title`), **name** (`name`, typo-tolerant; when the response carries `nameMatch: "approximate"` nobody matched exactly, so present the rows as the closest names, not as the person asked for), or **role words** (`roles`, e.g. ["founder", "co-founder", "cofounder"] — expand synonyms yourself). To scope to a company, first resolve its name to an id with `list_accounts` (company search), then pass that id as `accountId` here — far cheaper than paging the whole target list. To find ONE person by LinkedIn URL, use `resolve_target`, never a page walk; to find people by name when you have no URL, use `name`. Paginated — loop pages until `nextPage` is 0.
list_targets
WRITE, LEGACY. Mark (`preferred: true`) or unmark (`preferred: false`) a connector as a preferred supporter for this customer. Preferred connectors are prioritized when ranking warm paths. The product moved this axis onto the rating, so reach for `set_connector_tier` for any new work and use this tool only when the caller specifically needs the `preferred` flag itself. This flag is NOT the rating: `set_connector_tier` does not write the `preferred` column, so setting `rating: 5` will not mark someone preferred, and marking them preferred will not give them a rating.
set_connector_preferred
WRITE, LEGACY. Exclude (`excluded: true`) or un-exclude (`excluded: false`) a connector for this customer. Excluded connectors are dropped from warm-path results. The product moved this axis onto the rating: a `rating: 1` ('don't ask') hides the connector and sets this flag for you, so prefer `set_connector_tier` with `rating: 1`. ⚠ The sync runs ONE WAY: writing a rating updates this flag, but `excluded: false` here does NOT clear a `rating: 1` — it leaves the connector rated don't-ask while un-excluded. To un-hide someone cleanly, give them a `rating` of 2..5 instead of un-excluding.
set_connector_excluded
WRITE. SET THE STARS: the caller's personal star `rating` for a connector — how readily they'd ask this person for an intro. This is the tool for 'star this person', 'rate them' or 'prioritize them as a supporter'. `rating` is 1..5 and HIGHER IS BETTER: 5 = ★★★★★ 'ask anytime' (the closest) down to 1 = ★ "don't ask", with 4, 3 and 2 in between — and a rating of 1 also HIDES the connector from the default listings. `tier` is the same setting spelled as the raw wire number, where LOWER IS BETTER (1 = 'ask anytime' … 5 = "don't ask", 0 = clear), and is still accepted: pass EXACTLY ONE of `rating` (1..5) or `tier` (0..5) — sending both, or neither, is rejected. There is no `rating: 0`: clearing a rating back to unreviewed stays `tier: 0`. This does NOT touch the legacy `preferred` flag — that is a separate column with its own tool. To SEARCH by rating instead, call `list_network_connections` (each supporter carries its `rating`; filter with `ratings`). Personal to the API-key owner.
set_connector_tier
WRITE. Discard pending pool prospects (by their `list_pool` ids) — soft-deletes the status-`new` entries. A rejected person stays rejected: later searches do not bring them back, and there is no way to undo it here — confirm with the customer first. Idempotent; already-confirmed prospects are unaffected. Use to clear out people a search surfaced that you don't want.
reject_pool
Look up ONE person by their LinkedIn profile URL and get back that target (with its `id` for the id-scoped tools), or `found: false` if they are not one of your targets. Use this for any question about a single named person — "is X already a target", "what's X's target id", "do I have paths to X" (resolve, then `get_target_connections`). Do NOT page `list_targets` looking for someone: on a large book that is dozens of slow requests and can stop before reaching them. Unlike `list_targets` (which returns only targets that already have a warm-intro path), this finds ANY of your non-archived targets — including one imported moments ago whose paths are still being computed, so it is also how you get the id straight after `import_targets`. `found: false` is a normal answer, not an error.
resolve_target
WRITE. Company-first discovery: find NEW people with the given job `titles` at the given `companies` — for when you have target companies but not the names yet. `companies` are domains (`acme.com`) or LinkedIn company URLs (`linkedin.com/company/…`); `titles` form the persona (e.g. "Head of Sales"). Tell the customer before launching: people this search finds are normally added as Targets AUTOMATICALLY, up to a limit per company, and their warm paths are charged like any Target's; only the people beyond that limit wait in the pool for review. Every call launches a new search — do not repeat a call to retry or to check on it. Returns a `campaignId`; people arrive ASYNCHRONOUSLY with no completion signal. `list_targets` shows the customer's Targets, new ones included once they have at least one warm path, and `resolve_target` confirms one specific person; the ones held back are in `list_pool` (filter by this `campaignId`), where `confirm_pool` makes the ones the customer wants Targets (charged the same way) and `reject_pool` discards the rest.
search_accounts
WRITE. Supporter-first discovery: find people with the given job `titles` inside the networks of the given `supporters` — people the customer knows and can ask for an introduction — optionally only at the given `companies`. `supporters` are LinkedIn profile URLs (`linkedin.com/in/…`); `titles` form the persona (e.g. "VP Sales"); `companies` are domains (`acme.com`) or LinkedIn company URLs. Launching charges nothing: the people this search finds wait in the pool for review and do not become Targets on their own. Someone the customer rejected earlier stays rejected. Every call launches a new search — do not repeat a call to retry or to check on it. Returns `status`, `errors`, a `campaignId` and counts of supporters accepted and not accepted — not the people found, who arrive over time with no completion signal. Check back later with `list_pool` filtered by this `campaignId`, then `confirm_pool` (a batch of ids) the ones the customer wants and `reject_pool` the rest. Before confirming, tell the customer that confirming takes those people on as Targets and their warm paths are then charged. The search does not change anyone's rating. Optionally pass `icp`, the customer's ideal customer (`industry`, `companySize`, `location`, `description`): every person the search finds is then scored for fit against it. Take it ONLY from what the customer said — never infer, guess or fill in an ideal customer they did not describe. The pool never hides anyone for a poor fit: review the fits with `list_pool` (this `campaignId`, optionally `minIcpFit`) together with the customer. `icp` cannot be combined with `companies` — an ideal customer is scored only on a search through the whole network.
search_supporters
WRITE. Add and/or remove labels on a COMPANY, so everyone in the team's network who currently works there carries it. Company labels are ORG labels, visible to the whole team: investor, customer, partner, do_not_contact (nothing else can be set on a company). REQUIRED FIRST STEP: call `find_network_companies` with the company name and pass the `id` of the row you pick as `companyId`. NEVER use an account id from `list_accounts` or `search_accounts` — it is a different kind of id and is refused. One company can appear as SEVERAL rows (e.g. a long and a short spelling of the name), each with its own `connectorsCount`: show the user every row with its count and let them choose one or several, then call this once per chosen id. State how many people the label will reach (`connectorsCount`) before writing. `do_not_contact` is only a label and hides nobody by itself. Adding a label already there changes nothing.
set_company_labels
WRITE. Add and/or remove labels on ONE person in the network — who they are to the customer (`{"add":["investor"]}`). ORG labels — investor, customer, advisor, partner, do_not_contact — are visible to the WHOLE team, with who set them; PERSONAL labels — close_friend, family, mentor — are visible only to the caller. `supporter` is NOT a label write: it is the caller's 2..5 star rating, so for 'make them a supporter' / 'star them' call `set_connector_tier`. The automatic labels (current_colleague, former_colleague, university_classmate) cannot be set or removed. `do_not_contact` is only a label: it marks the person and hides nobody by itself. Adding a label already there, or removing one that is not, changes nothing. To label a whole COMPANY (everyone who works there) use `set_company_labels`. Read a person's labels back on `labels` of `list_network_connections`, `get_target_connections` and `find_top_paths`.
set_connector_labels
WRITE. Move an intro through its lifecycle: `requested` (intro sent), `completed` (intro made), or `declined`. For `declined` you may pass `reasonId` (connector_declined | prospect_declined | other) and a free-text `customReason` (≤200 chars). Idempotent per status.
set_intro_status
Draftboard ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Draftboard's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Draftboard alternatives on ChatGPT?
As of 2026-10-30, Draftboard competes with Add to CRM, AdvPulse, AgentData, AI Leads Scout, AI Vibe Prospecting, anVendor, Apollo.io, Bullwhip and 69 more in ChatGPT B2B Prospecting & Contact Data, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.