| name | saber-cli |
| description | GTM intelligence via the Saber CLI. Use when the user wants to define their ICP and buying signals, build target account or contact lists, run company or contact signal research, manage signal subscriptions, or prioritize outreach. Also use when the user mentions prospecting, lead scoring, intent data, buying intent, firmographic filters, or anything related to sales intelligence. Triggers include "find companies", "who should I target", "track hiring signals", "build a list", "run signals", "check credits", or any GTM workflow involving the saber command.
|
Saber CLI
The Saber CLI runs company and contact signal research, builds target lists, and
manages signal subscriptions from the terminal. It talks to the Saber API,
authenticated with an API key stored at ~/.saber/credentials.json.
Core Workflow
Every Saber engagement follows three phases:
- Discover -- define ICP and buying signals
- Build -- create target account and contact lists
- Activate -- run signals against those lists
saber org get
saber list company create --name "Mid-market SaaS" --industry "software development" --size "51-200" --country US
saber subscription create --list <listId> --name "Hiring in sales" \
--question "Is this company actively hiring in sales or revenue roles?" \
--answer-type boolean --frequency monthly --run-once
Phase 1 -- Signal Discovery
Help the user define what buying intent looks like for their Ideal Customer Profile
before activating any signal tracking.
Step 1 -- Load organisation context
Run saber org get first. If the profile has name, website, and description fields,
use them directly. If the profile is empty, ask the user to fill the gaps, then persist:
saber org update --name "Acme Corp" --general "B2B sales intelligence platform" \
--products "Signal tracking, list building" \
--use-cases "Outbound prospecting, ABM campaigns" \
--value-prop "Find buying intent before your competitors do"
Step 2 -- Gather ICP details
Once org context is established, ask these in order (conversationally, not all at once):
- Who do you sell to? -- industry, company size, geography, buyer title
- Who is the buyer? -- title, seniority, department (e.g. "VP Sales", "Head of RevOps")
- What makes a company ready to buy? -- triggers (new hire, funding, tech migration)
Step 3 -- Generate signal hypotheses
Propose 3-5 signals based on the ICP. For each:
- Signal question -- natural language question Saber will answer
- Signal type --
company or contact
- Why it matters -- brief rationale linking the signal to purchase readiness
Example signals:
Signal: Is this company actively hiring in sales or revenue roles?
Type: company
Rationale: Hiring in sales indicates growth mode and budget for new tools.
Signal: Has this company recently raised a funding round?
Type: company
Rationale: Post-funding companies accelerate spend on GTM tooling.
Signal: Is the Head of People posting about frontline retention challenges?
Type: contact
Rationale: Public pain signals from the buyer persona indicate active problem awareness.
Step 4 -- Confirm and hand off
Present proposed signals, adjust based on feedback, then keep the agreed ICP and signal
definitions in conversation context. Next steps: build lists (Phase 2), then activate
signals (Phase 3).
Phase 2 -- Build Target Lists
Company lists
Ask how the user wants to supply accounts:
Option A -- Let Saber find companies (recommended)
saber list company create --name "US Mid-market SaaS" \
--industry "software development" --size "51-200" --country US
Filter formats:
--industry values are lowercase: restaurants, hospitality, food & beverages
--size uses K notation: 1-10, 11-50, 51-200, 201-500, 501-1K, 1K-5K, 5K-10K, 10K+
--country uses ISO 3166-1 alpha-2: US, GB, DE, NL
--technology uses slugs: stripe, hubspot, salesforce
Technology filters consume credits per matched company. Always run count-preview
first so the user can see the cost before committing:
saber list company count-preview --technology "salesforce" --size "51-200" --country US
Option B -- Import from HubSpot
saber list company import --name "From HubSpot" \
--property industry --operator EQ --value "Technology"
Preview without creating:
saber company search --industry "software development" --size "51-200" --country US
Contact lists
Contacts are sourced from company LinkedIn URLs. If a company list exists, get URLs
from it first:
saber list company companies <listId> --limit 10
Then create the contact list:
saber list contact create --name "VP Sales at target accounts" \
--company-linkedin https://linkedin.com/company/acme \
--company-linkedin https://linkedin.com/company/globex \
--title "VP Sales" --title "Head of Sales"
Both --company-linkedin and --title are repeatable. --company-linkedin is required.
Preview without creating:
saber contact search --company-linkedin https://linkedin.com/company/acme --title "VP Sales"
Filter by department and seniority using the LinkedIn Sales Navigator taxonomy
(both repeatable), and page through large result sets with --limit/--offset.
Values must match the LSN taxonomy exactly — e.g. seniority is Vice President,
not VP; unknown values are rejected by the API with a validation error:
saber contact search --company-linkedin https://linkedin.com/company/acme \
--department Sales --seniority CXO --seniority "Vice President" \
--limit 50 --offset 0
Look up a single contact's email (one-shot, given just full name + company domain):
saber contact find-email --full-name "Joey van Ommen" --domain saber.app
Reach for find-email when you already have a target name in mind — e.g. enriching
a list with verified emails before drafting outreach, or resolving a contact you
saw on LinkedIn. It's distinct from contact search (which previews many contacts
by filter) and from list contact create (which snapshots a Sales Navigator list).
Catch-all domains return the modal real-world pattern with accept_all: true —
treat as lower confidence.
Market Signals
Market signals monitor external data sources continuously and deliver matching
signals to a webhook. Unlike company/contact signals which answer research questions,
market signals track real-time events: job postings, LinkedIn posts, fundraising,
investments, and IPOs.
Subscription types
| Type | Description |
|---|
JOB_POSTS | Monitor job postings matching title, location, company filters |
LINKEDIN_POST | Monitor LinkedIn posts matching keyword filters (requires Sales Navigator) |
FUND_RAISED | Monitor fund closings and fundraising events |
RECENT_INVESTMENT | Monitor investment and funding rounds |
IPO | Monitor IPO and public listing announcements |
Create a market signal subscription
saber market-signal create --type JOB_POSTS --name "DevOps hiring" \
--filters '{"titleKeywords":["DevOps Engineer","SRE"],"countries":["US"]}' \
--webhook https://example.com/hook
saber market-signal create --type JOB_POSTS --name "AI startups" \
--prompt "Find companies hiring ML engineers at Series A startups in Europe" \
--webhook https://example.com/hook
saber market-signal create --type LINKEDIN_POST --name "AI posts" \
--filters '{"keywordsAll":["artificial intelligence"],"keywordsAny":["GPT","LLM"]}' \
--webhook https://example.com/hook
saber market-signal create --type FUND_RAISED --name "PE funds" \
--filters '{"keywords":["private equity"],"maxLookbackDays":30}' \
--webhook https://example.com/hook --interval weekly
Manage market signal subscriptions
saber market-signal list
saber market-signal get <subscriptionId>
saber market-signal update <id> --name "New name"
saber market-signal pause <id>
saber market-signal resume <id>
saber market-signal trigger <id>
saber market-signal signals <id>
saber market-signal delete <id>
The alias saber ms works as shorthand for saber market-signal.
Phase 3 -- Activate Signal Tracking
Before running any signals
Before any saber signal or saber subscription command that consumes credits:
- Run
saber credits and show the current balance. Balances can be whole or fractional credits.
- State how many signals will run (companies x questions, or contacts x questions)
- Ask the user to confirm before proceeding
Signal templates
Create reusable templates for frequently used signal questions. Templates store the
question, answer type, weight, and qualification criteria so they can be referenced
by ID instead of repeating the full definition.
saber template create --name "CRM Detection" --question "Which CRM are they using?" \
--answer-type list --weight important
saber template list
saber template get <templateId>
saber template update <templateId> --name "CRM Detection v2" --weight nice_to_have
saber template delete <templateId>
Extract templates from historical ad-hoc signals
If an org has been running ad-hoc signals (saber signal --question ...) before
templates existed, those executions can be retroactively grouped into reusable
templates so they're scoreable. The flow is two steps:
saber template extract propose --type company --json > plan.json
saber template extract apply --from-file plan.json
Or pipe straight through if you trust the proposal as-is. --yes skips the
credit-confirmation prompt that propose would otherwise block on:
saber template extract propose --type contact --yes --json | \
saber template extract apply --from-file -
Re-running the same plan returns 409 — drop already-attached executionIds
before retrying. Only score-compatible answer types (boolean, number,
percentage, currency, list) are clustered; open-text answers are skipped.
Prebuilt signals (use when one answers the question exactly)
Five prebuilt signals run by key with no question design needed: funding,
mna, tech, open-jobs, firmographics. Each answers one commodity fact —
same credit confirmation, same output, same --no-wait/--webhook async options.
Use one only when the question IS that fact, with no threshold, window,
filter or judgement attached. "Has this company raised recently?" is funding;
"raised a Series B+ in the last 6 months and has no VP Sales yet" is a custom
--question — a prebuilt key cannot express it, and reshaping the question to
fit one throws away the qualification criteria that make it worth asking.
saber signal funding --domain acme.com
saber signal tech --domain acme.com --category crm
saber signal mna --domain acme.com --no-wait
tech takes exactly one of --category erp|crm or --technology "<name>";
an unknown technology returns a 422 with did-you-mean suggestions.
Company signals -- spot check
Run a question against a single domain:
saber signal --domain acme.com --question "Are they hiring engineers?" --answer-type boolean
Use a template instead of inline question:
saber signal --domain acme.com --template <templateId>
Use lenient verification mode for broader answers:
saber signal --domain acme.com --question "What is their tech stack?" --verification-mode lenient
Fire multiple in parallel with --no-wait:
saber signal --domain acme.com --question "Are they hiring?" --no-wait
saber signal --domain globex.com --question "Are they hiring?" --no-wait
saber signal get <signalId>
Company signals -- batch
Run multiple questions across multiple domains in one call. Creates a Cartesian
product (each question x each domain).
saber signal batch \
--domain acme.com --domain globex.com --domain initech.com \
--question "Are they hiring engineers?" \
--question "What CRM do they use?" \
--answer-type boolean
saber signal batch --domain acme.com --domain globex.com \
--question "Revenue?" --question "Headcount?" --generate-summary
saber signal batch --domain acme.com --question "..." --async
Company signals -- listing and filtering
Browse and filter existing signal results:
saber signal list
saber signal list --domain acme.com --status completed
saber signal list --from-date 2024-01-01T00:00:00Z
saber signal list --subscription-id <id>
saber signal list --limit 10 --offset 20
Signal summaries
Generate AI-powered summaries that consolidate insights from all completed signals
for a domain into structured data points with qualifications and sources.
saber summary generate --domain acme.com
saber summary list --domain acme.com
Company signals -- full list (subscriptions)
For running a signal across all companies in a list, use subscriptions.
One-off run (recommended for getting started):
saber subscription create --list <listId> \
--name "Hiring signal" \
--question "Is this company actively hiring in sales or revenue roles?" \
--answer-type boolean \
--frequency monthly --run-once
--run-once triggers immediately, then stops the schedule. One subscription per signal question.
Recurring schedule:
saber subscription create --list <listId> \
--name "Hiring signal" \
--question "Is this company actively hiring in sales or revenue roles?" \
--answer-type boolean --frequency weekly
Structured data (json_schema):
saber subscription create --list <listId> \
--name "Company financials" \
--question "Extract annual revenue, employee count, and funding stage" \
--answer-type json_schema \
--output-schema '{
"type": "object",
"properties": {
"revenue": {"type": "string"},
"employees": {"type": "number"},
"funding_stage": {"type": "string"}
}
}' \
--frequency monthly
Or use a schema file:
saber subscription create --list <listId> \
--name "Company financials" \
--question "Extract annual revenue, employee count, and funding stage" \
--answer-type json_schema \
--output-schema @schema.json \
--frequency monthly
Manage subscriptions:
saber subscription list
saber subscription get <subscriptionId>
saber subscription trigger <subscriptionId>
saber subscription start <subscriptionId>
saber subscription stop <subscriptionId>
Contact signals
Run a question against a LinkedIn profile:
saber signal --profile https://linkedin.com/in/janedoe \
--question "Is this person posting about employee retention challenges?"
Use a template:
saber signal --profile https://linkedin.com/in/janedoe --template <templateId>
Fire multiple with --no-wait:
saber signal --profile <linkedin-url> --question "<question>" --no-wait
saber signal get <signalId>
Sample run (recommended before full activation)
Before running signals across a full list, test a sample of 5-10 items first so the
user can validate quality without spending credits on everything.
For company signals:
saber list company companies <listId> --limit 10
saber signal --domain <domain> --question "<question>" --answer-type boolean --no-wait
saber signal get <signalId>
Or use batch for a quicker multi-domain sample:
saber signal batch --domain acme.com --domain globex.com --domain initech.com \
--question "Are they hiring?" --answer-type boolean
Present results and ask:
- Do the signals look accurate?
- Any false positives or unexpected answers?
- Proceed with the full list?
For contact signals, pick 3-5 contacts the user already knows about (so they can judge
accuracy), run signals, review, then confirm.
Scoring
Scoring turns signal results into structured fit and urgency scores
(0-100) for companies and contacts. It builds on top of signals -- any data the
signal layer can ingest becomes scoreable.
Mental model
- Profile -- a named, org-scoped configuration bound to a single object
type (
company or contact). Holds rules. One object can be assigned to
multiple profiles of the matching type.
- Rule -- within a profile, maps one signal template to point values for
one dimension (
fit or urgency). The shape of point values depends on the
template's answer type.
- Assignment -- links a profile to a specific company or contact. Triggers
an immediate recompute.
- Score result -- the computed score for one
(profile, object, dimension)
triple, with a per-rule contribution breakdown so it's always explainable.
Score is (earned / maxPossible) * 100. All rules count toward the
denominator regardless of whether a signal answer exists, so low-coverage
scores stay conservatively low.
Manage profiles
saber scoring profile create --type company --name "EMEA Enterprise" \
--description "1000+ headcount in EMEA"
saber scoring profile list
saber scoring profile get <profileId>
saber scoring profile update <profileId> --name "Enterprise ICP"
saber scoring profile delete <profileId>
Profile --type is immutable after creation.
Manage rules
A rule's point-value shape depends on the answer type of the referenced signal
template:
saber scoring rule upsert <profileId> --signal-template <id> --dimension fit \
--true 20 --false -5
saber scoring rule upsert <profileId> --signal-template <id> --dimension fit \
--range "0:500:5" --range "500:5000:15" --range "5000:100000:25"
saber scoring rule upsert <profileId> --signal-template <id> --dimension fit \
--choice "Salesforce:10" --choice "HubSpot:8" --choice "None:-10"
saber scoring rule upsert <profileId> --signal-template <id> --dimension urgency \
--points '{"ranges":[{"min":0,"max":500,"points":5}]}'
saber scoring rule upsert <profileId> --signal-template <id> --dimension urgency \
--points-file rules.json
saber scoring rule list <profileId>
saber scoring rule delete <profileId> <ruleId>
Upserting or deleting a rule recomputes every object assigned to the profile,
so scores never go silently stale.
Assign profiles to objects
Object IDs are domains for companies and LinkedIn profile URLs for contacts.
saber scoring assignment create --profile <id> --type company --object acme.com
saber scoring assignment bulk --profile <id> --type company \
--object acme.com --object stripe.com --object framer.com
saber scoring assignment list --type company --object acme.com
saber scoring assignment delete <assignmentId>
Read and recompute scores
saber scoring scores --type company --object acme.com
saber scoring scores --type company --object acme.com --object stripe.com
saber scoring scores --type company --object acme.com --detailed
saber scoring compute --type company --object acme.com --object stripe.com
Recompute is also triggered automatically on profile assignment and on rule
upsert/delete -- direct compute calls are mainly for refreshing against the
latest signal data.
Signal Flags
| Flag | Default | Description |
|---|
--domain / -d | -- | Company domain (company signals) |
--profile / -p | -- | LinkedIn profile URL (contact signals) |
--question / -q | required* | Research question (max 500 chars) |
--template | -- | Signal template ID (alternative to --question) |
--answer-type / -a | open_text | open_text, boolean, number, list, percentage, currency, url, json_schema |
--output-schema | -- | JSON Schema string or @file path (required when answer-type is json_schema) |
--verification-mode | strict | strict or lenient |
--force-refresh | false | Bypass 12h result cache |
--no-wait | false | Return signal ID immediately without polling |
--webhook | -- | POST result to this URL when complete |
--max-wait | 120 | Max seconds to wait before timing out |
*Required unless --template is provided.
Common Patterns
End-to-end ICP activation
saber org update --name "Acme" --general "We sell HR software to mid-market"
saber list company create --name "Mid-market US" \
--industry "software development" --size "51-200" --country US
saber list company companies <listId> --limit 10
saber signal --domain <domain> --question "Are they hiring in HR?" --no-wait
saber subscription create --list <listId> --name "HR hiring" \
--question "Is this company actively hiring in HR roles?" \
--answer-type boolean --frequency monthly --run-once
saber subscription get <subscriptionId>
Multi-signal activation
Create one subscription per signal question against the same list:
saber subscription create --list <listId> --name "Hiring signal" \
--question "Is this company actively hiring?" --answer-type boolean --frequency monthly --run-once
saber subscription create --list <listId> --name "Funding signal" \
--question "Has this company raised funding recently?" --answer-type boolean --frequency monthly --run-once
saber subscription create --list <listId> --name "Tech migration" \
--question "Is this company migrating their tech stack?" --answer-type boolean --frequency monthly --run-once
Or use batch for a quick multi-question run across specific domains:
saber signal batch \
--domain acme.com --domain globex.com \
--question "Is this company actively hiring?" \
--question "Has this company raised funding recently?" \
--question "Is this company migrating their tech stack?" \
--answer-type boolean --generate-summary
Template-based workflow
Create templates once, reuse across signals and subscriptions:
saber template create --name "Hiring" --question "Is this company actively hiring?" --answer-type boolean
saber template create --name "Funding" --question "Has this company raised funding recently?" --answer-type boolean
saber signal --domain acme.com --template <templateId>
saber subscription create --list <listId> --template <templateId> --frequency weekly
Check account status
saber credits
saber connectors
saber auth status
saber update
Update checks
The CLI checks for updates in the background (once per 24h, non-blocking). A
one-line notice is printed to stderr when an update is available. The check is
skipped when --json, --quiet, or SABER_NO_UPDATE_CHECK=1 is set, when
stderr is not a TTY, or on dev builds.
Global Flags
Available on every command:
| Flag | Description |
|---|
--json | Output raw API JSON to stdout |
--quiet / -Q | Suppress all non-error output |
--verbose / -v | Log HTTP method, URL, status, rate-limit headers to stderr |
--api-url | Override base API URL (default: https://api.saber.app) |
Deep-Dive Documentation