# SignalDock Docs - [Welcome](/docs): How SignalDock turns public and private signals into scored opportunities. - [Getting started](/docs/getting-started): Run SignalDock locally and open the EventDock organization. - **Concepts** - Concepts - [Concepts](/docs/concepts): The objects SignalDock stores and how they move through the pipeline. - [Signals](/docs/concepts/signals): What a signal is, where it comes from, and how it is processed. - [Projects](/docs/concepts/projects): How SignalDock groups signals onto a real-world project and its companies. - [Scoring](/docs/concepts/scoring): Rule components, AI assessment, and the ignore / qualify / opportunity thresholds. - [Research briefs](/docs/concepts/research): How the research agent reads public sources about a company and why every fact carries its source URL. - [Enrichment and email verification](/docs/concepts/enrichment): How SignalDock fills in company and contact data from several providers, and how it checks emails before anything is sent. - [Knowledge base](/docs/concepts/knowledge): Give the writer agents your case studies, product notes, and tone of voice so drafts stay accurate. - [Campaigns and sequences](/docs/concepts/campaigns): How SignalDock turns an opportunity into a compliant, multi-touch sequence that pauses for your approval. - [Learning and evals](/docs/concepts/learning): How won, lost, and replied outcomes improve scoring and drafts, and how prompt changes are gated on evals. - [Copilot](/docs/concepts/copilot): Ask about signals and pipeline in plain language, and let the copilot draft campaigns that wait for your approval. - [Markets](/docs/concepts/markets): The countries SignalDock sells into, how a market is rolled out, and what enabling one creates in an organization. - [Compliance](/docs/concepts/compliance): How SignalDock decides whether a touch is allowed, what it must carry, and how personal data is kept, exported, and erased. - [Data residency and language](/docs/concepts/data-residency): Where SignalDock stores and processes data, and how it picks the language and register for every prospect-facing text. - [Languages](/docs/concepts/languages): The interface languages of the site and app, and how they differ from the language outreach is written in. - [Billing and usage](/docs/concepts/billing): Plans in euro, what is metered, what happens at a limit, and how Stripe keeps the plan in sync. - [SSO and audit export](/docs/concepts/security): SAML single sign-on per organization, how enforcement works, and exporting the audit log as CSV. - **Platform** - Sources - [Sources](/docs/sources): How SignalDock fetches publications, pages them, and dedupes before the pipeline. - [Overheid (KOOP SRU)](/docs/sources/overheid): Dutch official publications, such as permits, from the KOOP SRU repository. - [TenderNed](/docs/sources/tenderned): Dutch public tenders from the TenderNed publication API. - [TED](/docs/sources/ted): EU tenders from the Official Journal through the TED Search API. - [DSO](/docs/sources/dso): Draft spatial plans from the Omgevingswet Ruimtelijke Plannen API. - Integrations - [Integrations](/docs/integrations): Connect enrichment and CRM providers. Secrets stay in Vault, never in env or the browser. - [KvK Handelsregister](/docs/integrations/kvk): Resolve companies by KvK number and read legal form, SBI codes, and address from the Dutch company registry. - [Mailboxes (Gmail and Microsoft 365)](/docs/integrations/mailboxes): Connect sending mailboxes, how warm-up and send windows work, and the DNS checks that gate sending. - [Cal.com](/docs/integrations/calcom): Bring booking-link meetings back into SignalDock. - [Apollo](/docs/integrations/apollo): Enrich companies and find contacts from industry personas. - [HubSpot](/docs/integrations/hubspot): Companies, contacts, and deals, with every email, reply, and meeting on the timeline. - [Pipedrive](/docs/integrations/pipedrive): Organizations, persons, and deals, with notes for emails and replies and meeting activities. - [Attio](/docs/integrations/attio): Upsert companies, people, and deals without duplicating CRM records. - API - [API](/docs/api): REST over the shared oRPC contract. Scalar and OpenAPI live on the api service. - Reference - Session: Who the caller is and how they present themselves. Use `GET /me` to check that a token works before calling anything else; `/profile` reads and changes the caller's own name and picture. - [Describe the verified caller](/docs/api/reference/session/getMe): Returns the caller's user id and how the request was authenticated. A `200` means the bearer token verified and row-level security is keyed on this user. - [Read the caller's profile](/docs/api/reference/session/getProfile): The caller's own profile. Answers `404 NOT_FOUND` when the user has never saved a profile. - [Update the caller's profile](/docs/api/reference/session/updateProfile): Changes the caller's own profile, creating it on first save. Send only the fields to change; `null` clears one. - Organizations: The tenants the caller belongs to. Signals, projects, and opportunities live inside an organization. `slug` is its URL segment in the app. - [List the caller's organizations](/docs/api/reference/organizations/listOrganizations): Every organization the caller is a member of, by name. An empty array means they have not created or joined one yet. - [Create an organization](/docs/api/reference/organizations/createOrganization): Creates an organization and makes the caller its owner. `slug` is unique and not a reserved app path. Answers `409 CONFLICT` when the slug is taken. - [Update an organization](/docs/api/reference/organizations/updateOrganization): Renames an organization or changes its slug. Requires owner or admin. Answers `409 CONFLICT` when the slug is taken. - [Get one organization](/docs/api/reference/organizations/getOrganization): Fetches one organization by id. Answers `404 NOT_FOUND` when it does not exist or the caller is not in it. - Signals: Ingested commercial signals: list and read them, ignore one, or reprocess from a pipeline stage. Reprocess starts `processSignalWorkflow` on this service. - [List signals](/docs/api/reference/signals/listSignals): Signals in an organization, newest first. Filter by `status`, `projectId`, or a title search. Row-level security hides other tenants. - [Get one signal](/docs/api/reference/signals/getSignal): A signal plus its current classification and score breakdown when those exist. Answers `404 NOT_FOUND` when it is not visible. - [Reprocess a signal](/docs/api/reference/signals/reprocessSignal): Starts `processSignalWorkflow` from `fromStage` (or classify). Requires a write role. The API owns workflow start; this contract only describes the request. - [Ignore a signal](/docs/api/reference/signals/ignoreSignal): Sets the signal status to `ignored` so later pipeline stages skip it. - Projects: Resolved projects in an organization, typically inferred from signals. - [List projects](/docs/api/reference/projects/listProjects): Resolved projects in an organization, by name. - [Get one project](/docs/api/reference/projects/getProject): Fetches one project by id. Answers `404 NOT_FOUND` when it is not visible. - Companies: Resolved companies and public bodies in an organization. Distinct from SignalDock organizations. Enrich starts contact lookup via the organization provider. - [List companies](/docs/api/reference/companies/listCompanies): Resolved companies and public bodies in an organization. Distinct from SignalDock organizations. - [Get one company](/docs/api/reference/companies/getCompany): Fetches one company by id. Answers `404 NOT_FOUND` when it is not visible. - [Enrich a company](/docs/api/reference/companies/enrichCompany): Starts contact enrichment for one company via the organization's enrichment provider. - Opportunities: Qualified commercial opportunities. Create from a ready signal, or sync one to the organization CRM (`syncOpportunityWorkflow`). - [List opportunities](/docs/api/reference/opportunities/listOpportunities): Opportunities in an organization, newest first. - [Create an opportunity](/docs/api/reference/opportunities/createOpportunity): Creates an opportunity, typically from a ready signal. Requires a write role. - [Get one opportunity](/docs/api/reference/opportunities/getOpportunity): An opportunity plus its product fits. Answers `404 NOT_FOUND` when it is not visible. - [Sync an opportunity to CRM](/docs/api/reference/opportunities/syncOpportunity): Starts `syncOpportunityWorkflow` for the organization CRM integration. - [Record won or lost](/docs/api/reference/opportunities/setOpportunityOutcome): Marks the opportunity won (optionally with the deal value in euros), lost, or open again. Outcomes feed attribution and the learning loop. - Contacts: People at companies in the organization, with their verified email status and preferred language. - [List contacts](/docs/api/reference/contacts/listContacts): People at companies in the organization, by name. Filter by company or search the name. At most 200. - Sources: Ingestion sources in an organization. `POST /sources/{sourceId}/run` starts `ingestSourceWorkflow`; `POST /markets/{country}` adds a country's recommended sources. - [List signal sources](/docs/api/reference/sources/listSources): Configured ingestion sources in an organization. - [Create a signal source](/docs/api/reference/sources/createSource): Adds an ingestion source. `provider_key` must match a registered SignalSourceProvider. - [Update a signal source](/docs/api/reference/sources/updateSource): Changes name, config, enabled flag, or schedule. - [Run a signal source now](/docs/api/reference/sources/runSource): Starts `ingestSourceWorkflow` for one source. - [Enable a market](/docs/api/reference/sources/enableMarket): Creates the recommended public signal sources for a country (for example TED tenders for BE or DE). A provider that already has a source for that country is skipped, so the call is safe to repeat. - Integrations: Connected CRM, enrichment, and geocoding providers. Secrets are stored in Vault and never returned. - [List integrations](/docs/api/reference/integrations/listIntegrations): Connected CRM, enrichment, and geocoding providers. Secrets are never returned. - [Connect an integration](/docs/api/reference/integrations/connectIntegration): Stores non-secret config on the integration row and the API key in Vault. - [Test an integration](/docs/api/reference/integrations/testIntegration): Verifies the stored secret can authenticate with the provider. - Compliance: Per-country outreach policy defaults, suppressions, lawful-basis records, the audit trail, and GDPR data subject export and erasure. - [Read compliance settings](/docs/api/reference/compliance/getComplianceSettings): Default country and locale, retention window, sender identity, and AI Act disclosure mode. Returns EU-safe defaults when nothing is stored yet. - [Update compliance settings](/docs/api/reference/compliance/updateComplianceSettings): Owner or admin only. Every change is audited. - [List suppressions](/docs/api/reference/compliance/listSuppressions): Do-not-contact entries by email, domain, or KvK number, newest first. - [Add a suppression](/docs/api/reference/compliance/addSuppression): Blocks every future touch to an address, domain, or KvK number. Idempotent on (scope, value). - [Remove a suppression](/docs/api/reference/compliance/removeSuppression): Owner or admin only. Removing an unsubscribe or erasure suppression should be rare and is audited. - [Record a contact's lawful basis](/docs/api/reference/compliance/recordLawfulBasis): GDPR Art. 6 basis, recipient legal form, and the Art. 14 data source. Outreach refuses contacts without one. - [List audit events](/docs/api/reference/compliance/listAuditEvents): Append-only log of user, agent, and system actions, newest first. Page with `before`. - [Export audit events](/docs/api/reference/compliance/exportAuditEvents): Owner or admin on Growth or Scale. Audit events oldest first, at most 10,000 per call; continue from the last `created_at`. The export is itself audited. - [Export a data subject's data](/docs/api/reference/compliance/exportDataSubject): GDPR Art. 15 access request. Owner or admin only. Returns contacts, lawful basis, messages, and suppressions for the address. - [Erase a data subject](/docs/api/reference/compliance/eraseDataSubject): GDPR Art. 17 erasure. Deletes the contacts (messages and lawful basis cascade) and keeps a suppression so the address is never re-imported. - Research: Research agent briefs: sourced facts about a company and suggested outreach angles. Every fact links to the page it was read from. - [List research briefs](/docs/api/reference/research/listResearchBriefs): Research agent output per company: summary, facts with the source URL each was read from, and suggested outreach angles. Newest first. - Knowledge: Organization knowledge base: case studies, product notes, FAQs, objections, and tone guides. Documents are chunked and embedded so writer agents can ground their drafts. - [List knowledge documents](/docs/api/reference/knowledge/listKnowledgeDocuments): Case studies, product notes, FAQs, objections, and tone guides the writer agents ground on. - [Add a knowledge document](/docs/api/reference/knowledge/createKnowledgeDocument): Stores the document as pending and starts indexing (chunking and EU-routed embeddings). - [Update a knowledge document](/docs/api/reference/knowledge/updateKnowledgeDocument): Content changes re-index the document. - [Delete a knowledge document](/docs/api/reference/knowledge/deleteKnowledgeDocument): Removes the document and its chunks. - Mailboxes: Gmail and Microsoft 365 sending mailboxes: OAuth connect, warm-up caps, send windows, and SPF/DKIM/DMARC health. Tokens stay in Vault and are never returned. - [List sending mailboxes](/docs/api/reference/mailboxes/listMailboxes): Connected Gmail and Microsoft 365 mailboxes with warm-up cap, sends today, send window, and DNS health. - [Start connecting a mailbox](/docs/api/reference/mailboxes/authorizeMailbox): Owner or admin only. Returns the Google or Microsoft consent URL. After consent the browser returns to `returnTo` with `mailbox=connected` or `mailbox=error`. - [Update a mailbox](/docs/api/reference/mailboxes/updateMailbox): Owner or admin only. Pause or resume sending, and change the daily cap, warm-up ramp, send window, timezone, or signature. - [Disconnect a mailbox](/docs/api/reference/mailboxes/disconnectMailbox): Owner or admin only. Deletes the mailbox and its stored token. Sent message history is kept. - [Re-check deliverability](/docs/api/reference/mailboxes/checkMailboxHealth): Looks up SPF, DKIM, DMARC, and MX for the sending domain and stores the result. - Campaigns: Campaigns, versioned sequences, and enrollments. Each enrolled contact runs through one durable sequence that waits for delays, approvals, send windows, and daily caps. - [List campaigns](/docs/api/reference/campaigns/listCampaigns): Campaigns that are not archived, newest first, with their active sequence steps and enrollment counts per status. - [Create a campaign](/docs/api/reference/campaigns/createCampaign): Creates a draft campaign with a first sequence version. Without `steps` it uses the default four-touch sequence (email, follow-up, LinkedIn, last email). New campaigns start in review mode. - [Get a campaign](/docs/api/reference/campaigns/getCampaign): One campaign with its active sequence steps and enrollment counts. - [Update a campaign](/docs/api/reference/campaigns/updateCampaign): Changes settings, mode, or status. Sending `steps` creates a new sequence version; running enrollments keep the version they started on. - [List enrollments](/docs/api/reference/campaigns/listEnrollments): Contacts in the campaign with their step and status, newest first (up to 500). - [Enroll contacts](/docs/api/reference/campaigns/enrollContacts): Enrolls up to 100 contacts and starts one durable sequence run per contact. Contacts without an address or with an invalid address are skipped for email sequences; risky addresses are enrolled but every email to them waits for review. A draft campaign becomes active. - [Ask the strategist for a campaign](/docs/api/reference/campaigns/proposeCampaign): Starts the strategist agent for one opportunity. It proposes contacts, channels allowed in the company's country, and steps, and stores them as a campaign with status `proposed`. Nothing is sent until someone accepts it. At most one live proposal exists per opportunity. Signal processing does this automatically after outreach drafting. - [Accept a proposed campaign](/docs/api/reference/campaigns/acceptCampaignProposal): Turns an agent proposal into a campaign, enrolls the suggested contacts, and starts their sequences. Drafts still follow the campaign mode (review by default). - [Dismiss a proposed campaign](/docs/api/reference/campaigns/dismissCampaignProposal): Archives an agent proposal without contacting anyone. The strategist may propose again for the same opportunity later. - [Stop an enrollment](/docs/api/reference/campaigns/stopEnrollment): Stops the sequence for one contact. Drafts waiting for approval are skipped and the sequence run ends. - Messages: The approval inbox: drafts with their grounding (signal, sourced facts, compliance decision), sent emails, assisted tasks, and replies. - [List messages](/docs/api/reference/messages/listMessages): Outbound drafts, sent emails, assisted tasks, and replies, newest first. Filter by `status=pending_approval` for the approval inbox. Each message carries `why`: the signal, sourced facts, compliance decision, and review reasons. - [Get a message](/docs/api/reference/messages/getMessage): One message with its grounding (`why`), confidence, model, and prompt version. - [Approve a draft](/docs/api/reference/messages/approveMessage): Approves a draft, optionally with an edited subject or body, and releases the waiting sequence run. The original text is kept for learning. Sending still respects the mailbox window and daily cap. - [Reject a draft](/docs/api/reference/messages/rejectMessage): Rejects a draft and stops the contact's sequence. - [Complete a task](/docs/api/reference/messages/completeTask): Marks an assisted LinkedIn, phone, or letter task as done. - [Resolve a conversation](/docs/api/reference/messages/resolveThread): Closes a conversation the reply agent escalated (`thread_status: needs_human`) once a person has handled it. - Meetings: Meetings booked via Cal.com, by the reply agent on the mailbox owner's calendar, or by hand. A booking stops the contact's sequences, syncs to the CRM, and schedules a reminder. - [List meetings](/docs/api/reference/meetings/listMeetings): Meetings booked through a booking link (Cal.com), by the reply agent, or by hand. `upcoming=true` returns meetings that have not ended, soonest first. - [Record a meeting](/docs/api/reference/meetings/createMeeting): Records a meeting booked outside SignalDock. Like any booking, it stops the contact's sequences, syncs to the CRM when auto-sync is on, and schedules the reminder. - [Update a meeting](/docs/api/reference/meetings/updateMeetingStatus): Cancels a meeting or records the outcome (`completed`, `no_show`). Outcomes feed the learning loop. - Analytics: Signal-to-meeting-to-won attribution, deliverability per mailbox, and agent quality, including the latest prompt evals. - [Outreach analytics](/docs/api/reference/analytics/getOutreachAnalytics): Signal-to-meeting-to-won attribution by source, deliverability per mailbox, and agent quality (approval and edit rates, reply intents, latest prompt evals) for a 7, 30, 90, or 180 day window. - Billing: Plans billed monthly in EUR through Stripe, and metered usage (signals, research briefs, sent emails) against plan limits. - [Plan and usage](/docs/api/reference/billing/getBilling): The organization plan, subscription status, EUR price, and this month's metered usage against plan limits (signals, research briefs, sent emails). Usage resets on the 1st (UTC). - [Start a subscription](/docs/api/reference/billing/startCheckout): Owner or admin. Returns a Stripe Checkout URL for the Growth plan, billed monthly in EUR with VAT id collection. The plan changes when Stripe confirms payment. - [Manage the subscription](/docs/api/reference/billing/openBillingPortal): Owner or admin. Returns a Stripe customer portal URL for invoices, payment methods, and cancellation. - Settings: Organization industry profile, scoring thresholds and the learning job's weight suggestions, AI model overrides, and SAML SSO. - [Read the industry profile](/docs/api/reference/settings/getIndustryProfile): The organization industry profile with personas and products. - [Update the industry profile](/docs/api/reference/settings/updateIndustryProfile): Changes display fields on the industry profile. - [Read scoring settings](/docs/api/reference/settings/getScoring): The active scoring config and its rules. - [Update scoring thresholds](/docs/api/reference/settings/updateScoring): Changes ignore / qualify / opportunity cutoffs or the home coordinates on the active config. - [List scoring suggestions](/docs/api/reference/settings/listScoringSuggestions): Open weight changes proposed by the weekly outcome learning job, with the evidence behind each. Nothing changes until someone applies one. - [Apply a scoring suggestion](/docs/api/reference/settings/applyScoringSuggestion): Sets the rule's weight in the active scoring config to the suggested value. Owner or admin only; new signals are scored with it. - [Dismiss a scoring suggestion](/docs/api/reference/settings/dismissScoringSuggestion): Closes the suggestion without changing any weight. - [Read AI model settings](/docs/api/reference/settings/getAiSettings): Per-organization model overrides. Null means the code-level default. - [Update AI model settings](/docs/api/reference/settings/updateAiSettings): Sets or clears per-organization model overrides. - [Read outreach settings](/docs/api/reference/settings/getOutreachSettings): The organization autopilot kill switch, confidence thresholds, booking link, escalation address, and CRM sync flag. Defaults apply until an admin saves them. - [Update outreach settings](/docs/api/reference/settings/updateOutreachSettings): Admins only. Autopilot sends drafts without review only when it is enabled here, the campaign is in autopilot mode, and the draft's confidence is at or above the threshold. - [SSO settings](/docs/api/reference/settings/getSso): The SAML provider and email domains for the organization, or null when SSO is not set up. - [Configure SSO](/docs/api/reference/settings/updateSso): Owner or admin on the Scale plan. Links a Supabase Auth SAML provider and its email domains. With `enforce`, members on those domains must sign in through SSO. Audited. - [MCP](/docs/mcp): Connect Cursor, Claude, ChatGPT, and other assistants to SignalDock with OAuth. - **Decisions** - Decisions - [Decisions](/docs/decisions): Architecture decision records for choices that shape the platform. - [Marketing at the root, SaaS at /app](/docs/decisions/marketing-at-root): signaldock.dev serves the marketing site; the product is mounted at signaldock.dev/app. - [An EU-first AI SDR, compliance as product](/docs/decisions/eu-ai-sdr): SignalDock grows from signal-to-CRM into a full AI SDR that sends from customer mailboxes, with EU compliance modelled in the domain and humans in the loop by default. - **Releases** - [Changelog](/docs/changelog): What changed in each SignalDock release.