Install
$ agentstack add skill-outboundsync-skills-preflight ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
OutboundSync launch preflight
Run read-only. Never write, activate, pause, or re-point anything. Never print, log, or commit the API key. Never print sources[].url or destinations[].url except as a full paste URL under a Next step that needs it. Capabilities and config flags are safe to print.
Render only the fixed output shape in this skill — no prose outside it.
Vocabulary: “Webhook wiring” in this skill means the SEP → OutboundSync Sources paste URL (sources[].url). OutboundSync-emitted Sync Monitoring Webhooks (/api/v1/webhooks, sync.failed) are a different surface — hand off to sync-monitoring. API vocabulary bootstrap → api.
Credentials
- Load
$OUTBOUNDSYNC_API_KEYfrom the environment (Bearer token). - Base URL:
https://app.outboundsync.com/api/v1 - Docs: https://outboundsync.com/docs/api/v1/
See [references/endpoints.md](references/endpoints.md) for the thin API map.
Note: These instructions reflect OutboundSync best practices shared freely and without warranty of outcomes — see [DISCLAIMER.md](../../DISCLAIMER.md).
Phase 1 — OutboundSync pipeline (always, in order)
GET /me→account.email,apiKey.connectionScope/connectionId,connections[](id,crm,organizationDomain).GET /connections→ per connection:id,crm,status,organizationDomain,organizationId,capabilities{sync, destinations, blocklists},createdAt.GET /account/status→ top-levelready,blockers[],warnings[], per-connection component statuses (crmConnection,sources,destinations,blocklists).GET /sources→ per source:platform,connectionId,url,config{createOrUpdateCompany, createOrUpdateTask, assignContactOwner, salesforceObjectType},destinations[]{url, description, eventTypes, isDelayed}, boundreplyRelaywhen present. Paginate to exhaustion.GET /destinations/reply-relays→ reply-relay catalog for accessible connections (advisory on the CRM card; does not change gate math). Sources may already embed a boundreplyRelay.
Join by connectionId. Render one CRM card + one OutboundSync (pipeline) card per connection. When >1 connection, disambiguate gauge labels by domain (e.g. CRM (acme.com), OutboundSync (acme.com)).
Gates (faithful split of per-connection ready = crmConnection.ready && sources.ready)
- CRM BLOCKED iff
crmConnection.status !== "ready"(map tocrm_disconnectedwhen that blocker is present). Capabilities are context only — never fail the CRM gate forcapabilities.syncoff; that surfaces assync_not_enabledon the pipeline card. - OutboundSync (pipeline) BLOCKED iff
sources.status !== "ready"(sync_not_enabled|no_sources). Warnings never block.
Card text: preserve each blocker's meaning in one short ✗ line. Convert remediation into the shortest Next action. Include a docUrl only when it helps resolve that action.
Phase 2 — Detect platforms
Group /sources by platform + connectionId. The expected SEP→OutboundSync webhook target is that source's exact url.
Multiple sources for one platform: never pick the first. Show the count and short identifiers (…/webhooks/). Ask which source pairs with the target campaign before campaign-specific webhook checks.
Run Phase 3 per detected platform only. If no_sources blocks the pipeline, invent no SEP rows — gauge is CRM + OutboundSync only (total 2).
Phase 3 — SEP-specific readiness
If an MCP/API exists for the platform, run its checks. If not: confirm the source(s) exist, mark the SEP MANUAL (unverified — never a ✓ pass), and put verification in Next.
API/MCP/auth failures are UNVERIFIED, not empty results. Never invent empty mailboxes/campaigns/webhooks from a failed call.
Paginate accounts, campaigns, webhooks, and sources to exhaustion.
Never duplicate destination-forwarding recap in a SEP card — destinations live only on the CRM card.
Instantly (MCP / Instantly API, all read-only)
When Instantly MCP or Instantly API access is available:
workspace_get→ workspace + plan.list_accounts(limit 100)+get_account→ count ACTIVE senders vs paused/error; warmup + daily limit. Require ≥1 active sender with daily limit > 0.get_warmup_analytics→ health score. If Instantly docs give no numeric threshold, treat as advisory (·), not a hard block.accounts_ctd_status(host)when link/open tracking is on → SSL + CNAME ok; otherwise advisory unless sending is impossible.- Target campaign: use the named one; if none named → sole launchable campaign if exactly one; if zero → ✗ no sendable campaign; if multiple → ask which.
get_campaign→ status ≠ completed, ≥1 sequence step, senders assigned, leads present, schedule set. campaigns_sending_status(id, with_ai_summary=true)→ authoritative sendability; quote the summary meaning in one line.webhooks_list→ webhook whosetarget_hook_urlexactly equals the chosen Instantly source url (reject trailing whitespace/tabs), status enabled,event_typeall_eventsor covers EMAIL_SENT/REPLY/OPEN, campaign filter (if any) includes the target campaign. Skip campaign-filter checks until a campaign is identified.webhook_events_summary→ prefer matching webhook/campaign scope; workspace-wide failure counts are advisory (·) only.
Instantly BLOCKED if any of: 0 active senders; not sendable; no exact-match webhook; matching webhook disabled or filtered away. Warmup/CTD/unscoped delivery noise are WARN (·) unless they make sending impossible.
Other platforms (e.g. Smartlead)
Confirm source(s) exist, mark MANUAL, list short identifiers, instruct UI verification. Never mark MANUAL as ✓ Ready.
Gates (count these exactly for the status gauge)
- CRM (1): CRM connected (
crmConnection.status === "ready"). - OutboundSync / pipeline (1): sources+sync enabled (
sources.status === "ready"). - Each SEP (3): ≥1 active mailbox · exact-match webhook wired+enabled · sendable campaign.
- A gate counts as passed only when verified true. Manual/unverified SEPs have zero passed gates and render as an unverified row.
- Gauge total is dynamic: sum of CRM + pipeline + 3 per automated SEP. SEP rows exist only for platforms detected in
/sources. Whenno_sources, total = 2 (CRM + OutboundSync).
CRM card (one per connection)
Counted gate is OAuth only; everything else is advisory recap of how the integration is configured in OutboundSync.
Header: ### CRM — with context ` Connection · · org `.
- Gate:
✓ Connected — OAuth readyOR✗ Disconnected — crm_disconnected(→ Next: reconnect). · Capabilities: sync · destinations · blocklists(fromGET /connections; plan context, not a gate).· Integration config— per source under this connection:→ company · task · owner(+SF object:only when Salesforce; omit when null).· Destinations (forwarding, not CRM writes): endpoint(s)listingdescription → eventTypesfromsources[].destinations[], ORnone — events still sync to CRM natively. Use connection-leveldestinations{status,count}for the count/advisory. Honor ComponentStatus: ready / not_configured (advisory) / disabled on plan (no warning) / error.· Reply relays: in catalog(from/destinations/reply-relays) and/or bound relays on sources — advisory only; never a launch gate.· Blocklists:— map ComponentStatus: ready (enabled) / not_configured / disabled on plan / error: ``.
Distinguish disabled (feature off on plan → no warning, show "disabled on plan") from not_configured (feature on, nothing set up → advisory) for both destinations and blocklists.
OutboundSync / pipeline card (one per connection)
Header: ### OutboundSync with context ` · ` (or domain-disambiguated label when multi-connection).
- Gate:
✓ Sources + sync enabledOR ✗ lines forsync_not_enabled/no_sources. - Do not re-list destinations/blocklists/config here — those live on the CRM card. Pipeline card is sources/sync gate only.
Output contract
GitHub-flavored markdown only. Layout is the spec:
##for the verdict.- Immediately below it, one fenced ```text status gauge block.
- Then
###CRM card(s), then###OutboundSync card(s), then###per SEP, then### Next. - Blank line between every block. Every status line under a system is a
-bullet. Never two checks on one line. Never rely on soft line breaks. - Marks: ✓ verified pass · ✗ blocker · · warning/manual/unverified. No colored emoji, no ASCII boxes.
- Elide URLs in headers as
…/webhooks/. When a Next step needs a paste, put the FULL exact URL on the next line in inline code. - Show
### Nextonly when overall is not ready; each item maps to a ✗ or unverified · above.
Status gauge (inside the ```text block)
- Bars are 20 wide: █ passed gate · ░ failed/missing gate · ▒ unverified/manual.
- One
Overallrow, then one row per system in order: CRM, OutboundSync, then each SEP. Left-pad every label to the width of the longest label so all bars start in the same column. - Row fill: filled =
round(passed / total * 20)█ cells, remainder ░. A fully manual/unverified row is 20 ▒ cells (partial-verified manual rows fill █ for confirmed gates). - After the bar + two spaces:
- Overall →
/ · [ · manual]. Total = sum of automated gates across all systems; exclude manual systems from the fraction and append· manualwhen any exist. - System →
/ | manual — >. - The gauge is the glance layer; the
###sections carry the specifics.
Shape
````markdown
Overall / · [ · manual]
CRM
OutboundSync
CRM —
Connection · · org
- · Capabilities / Integration config / Destinations / Blocklists advisories
OutboundSync
·
Connection · …/webhooks/
Next
``
````
Worked examples: [references/examples.md](references/examples.md).
Verdict logic (compute, never print as its own section)
- Overall Ready only if every CRM card is connected AND every OutboundSync pipeline card is ready AND every SEP is ✓ Ready (all gates passed) or the user has explicitly confirmed each MANUAL check in this conversation.
- Manual/unverified SEPs keep overall Not ready and appear in Next until confirmed.
- Keep mailbox addresses and source codes verbatim where shown; full paste URLs appear only under the Next step that needs them.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: outboundsync
- Source: outboundsync/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.