Skip to content
Docs

Type to search. Arrow keys to move, Enter to open, Escape to close.

Developers

REST API

Every SIGNL tool is also an HTTP endpoint, with the same inputs and scopes as the MCP server. This page is read from the OpenAPI contract the API serves, so the two always agree.

117 tools

The contract

SIGNL Developer API 1.0.0

OpenAPI 3.1

The machine-readable contract is /openapi.json. Generate a client from it, or read the full input JSON Schema of any tool there.

Authentication

Keys are minted under the client's Integrations page (API keys), or organisation Settings → API Keys.

Bearer key

SIGNL API key

Use Authorization: Bearer sk_live_…

GET /api/keys/me

Describe the key you are holding

Authenticated by the key itself; any valid key may call it. Returns only facts about that credential. Call this first when a key does not work: it answers what the key can reach in one request, instead of probing endpoints and comparing error codes.

Scopes

A key can do what its scopes allow and nothing else. Each tool below names the scope it needs.

ingest:write

scope

Send events and leads in (/api/ingest/server, /api/webhooks/inbound). Grants no read access.

read

scope

Read workspace data over MCP and the Zapier app.

write

scope

Change workspace-internal records: leads, deals, calls, tasks.

write:sensitive

scope

Actions that reach a real person: cadence enrolment, activating an automation.

write:builder

scope

Author forms and booking calendars, in draft only. Publishing stays a human action.

write:ads

scope

Pause, resume an ad campaign and change its daily budget. Real ad spend — kept separate from write:sensitive.

write:agency

scope

Run the agency: create, edit, archive and restore clients. Organisation-wide keys only. New clients count against your plan.

write:finance

scope

Generate the agency’s statement drafts and add adjustments to a draft. Organisation-wide keys only. Off by default and not part of Full access; issuing, voiding and recording payment stay in SIGNL.

recordings:write

scope

Reserve and finalise screen recordings from the recorder extension.

Calling a tool

Send the tool's input as a JSON body. Workspace tools also take workspace, a workspace slug, which an organisation-wide key uses to name the workspace it acts in.

GET /api/v1/tools

List the tools the calling key can use

Any valid key may call this. Each tool comes with its path, required scope, MCP annotations and input JSON Schema; tools the key cannot use are listed with the scope they need.

POST /api/v1/tools/<name>

run a tool

The body fields of every tool are listed under Tools, below.

Responses and errors

Every status code a tool can answer with, and what the contract says about each.

200

status

  • The tool result.

201

status

  • Created.
  • A client was created.

400

status

  • Invalid input, named field by field. Unknown fields are refused.
  • Invalid input, or the request was refused (plan limit, unknown client). Unknown fields are refused.

401

status

  • Missing, malformed, unknown or revoked API key. A valid key never gets 401 — a missing scope is 403.

403

status

  • The key lacks read; the body names both.
  • The key lacks write; the body names both.
  • The key lacks write:sensitive; the body names both.
  • The key lacks write:ads; the body names both.
  • The key lacks write:builder; the body names both.
  • The key lacks read, or is pinned to one workspace and so has no portfolio.
  • The key lacks the tool’s scope (write:agency, or write:finance for statements; some also need write:sensitive), or is pinned to one workspace and so has no agency to run.

404

status

  • A referenced record was not found in this workspace.

409

status

  • The request is still running (honour Retry-After), or its outcome is unknown and requires reconciliation before another write.

422

status

  • This Idempotency-Key was already used with a different tool or body.

429

status

  • Request limit exceeded.

insufficient_scope

403 body

A valid key that lacks the scope this surface requires.
  • error string, required
  • message string, required
  • key_scopes array of one of: ingest:write, read, write, write:sensitive, write:builder, write:ads, write:agency, write:finance, recordings:write, required
  • required array of one of: ingest:write, read, write, write:sensitive, write:builder, write:ads, write:agency, write:finance, recordings:write, required
  • fix string, required

Tools

Grouped by the scope each one needs. The same tools over MCP are on the MCP page.

Tools: read

63

get_client_snapshot

Get client snapshot

Compact 30-day KPI snapshot for this client: leads, calls, deals, pipeline, top leads, cadences. Start here for open-ended questions.

POST /api/v1/tools/get_client_snapshot · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

list_leads

List leads

Leads (visitors) for this client, most recently seen first. Each lead has name (full) plus firstName and lastName, which are null when unknown (never guessed from the full name). Filter by free-text search, tag, minimum intent score, or customer status.

POST /api/v1/tools/list_leads · scope read

  • workspace string, optional
  • search string, optional. Match against name, email, or phone.
  • tag string, optional. Only leads carrying this tag.
  • min_intent_score integer, optional. Only leads at or above this intent score.
  • is_customer boolean, optional. Filter to customers (true) or non-customers (false).
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_lead

Get lead detail

Full detail for one lead plus their recent journey events, notes, and calls.

POST /api/v1/tools/get_lead · scope read

  • workspace string, optional
  • lead_id string, uuid, required. Lead id from list_leads.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_calls

List calls

Calls for this client, most recent first. Filter by lead, closer, outcome, type or a date window. Each call carries leadId, callType, repId and setterId so it can be joined to a lead or rep without a get_call per row.

POST /api/v1/tools/list_calls · scope read

  • workspace string, optional
  • status one of: booked, showed, no_show, cancelled, completed, optional. Filter by call status.
  • when one of: past, upcoming, optional. "past": calls already due, newest first (use this to find calls needing an outcome). "upcoming": still to come, soonest first. Omit for both, newest first.
  • lead_id string, uuid, optional. Only this lead's calls. The `leadId` on each call; also the id from list_leads.
  • talent_id string, uuid, optional. Only calls assigned to this closer. From list_talent.
  • outcome one of: won, lost, follow_up, no_decision, pending, disqualified, no_pitch_dq, optional
  • call_type one of: discovery, closing, consult, follow_up, optional
  • since string, optional. Scheduled at or after this ISO 8601 date or timestamp.
  • until string, optional. Scheduled on or before this ISO 8601 date or timestamp.
  • limit integer, optional. Max results, default 25, capped at 50.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_pipelines

List pipelines and stages

CRM pipelines with their ordered stages. Call this to get stage ids before creating or moving a deal.

POST /api/v1/tools/list_pipelines · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

list_deals

List deals

CRM deals for this client, most recently updated first.

POST /api/v1/tools/list_deals · scope read

  • workspace string, optional
  • status one of: open, won, lost, optional. Filter by deal status.
  • pipeline_id string, uuid, optional. Restrict to one pipeline.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_tasks

List tasks

Tasks for this client, soonest due first, or newest first with sort "newest".

POST /api/v1/tools/list_tasks · scope read

  • workspace string, optional
  • status one of: open, done, optional. Filter by task status.
  • sort one of: due, newest, optional. "due" (default) or "newest" by creation time.
  • lead_id string, uuid, optional. Only tasks about this lead.
  • assignee_member_id string, uuid, optional. Only tasks assigned to this team member. The `member_id` on a list_talent row, or `assigneeMemberId` on a task.
  • overdue boolean, optional. Only open tasks already past their due date.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_commissions_summary

Get commissions summary

Pending, approved, and paid commission totals (integer pence) for this client.

POST /api/v1/tools/get_commissions_summary · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

get_affiliate_summary

Get affiliate summary

Affiliate/JV partner totals for this client: active partners, verified postback conversions, and outstanding payout (integer pence).

POST /api/v1/tools/get_affiliate_summary · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

get_leaderboard

Get leaderboard

Rep leaderboard for this client: paid commission, total calls and close rate (won over calls with a recorded outcome), ranked. Includes every rep with a call or a paid commission.

POST /api/v1/tools/get_leaderboard · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

get_attribution_summary

Get attribution summary

Multi-touch revenue attribution by source/medium for this client.

POST /api/v1/tools/get_attribution_summary · scope read

  • workspace string, optional
  • model one of: first_touch, last_touch, linear, u_shaped, time_decay, optional. Attribution model, default first_touch.
  • days integer, optional. Lookback window in days, default 30.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_funnel_summary

Get funnel summary

Funnel for this client over a window: page views, leads captured, applied and qualified (only when the client has a form with qualification rules; `applicationForms` counts them), booked, showed, won, with stage-to-stage conversion, booked/showed/won by source, and the worst leak priced in money. Use it for "where am I losing people".

POST /api/v1/tools/get_funnel_summary · scope read

  • workspace string, optional
  • days integer, optional. Lookback window in days, default 30.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_metric_figures

Get metric figures

Named figures SIGNL has already worked out for this client, the same ones the dashboards show (collected revenue, show rate, close rate and the rest), each with its value as displayed, the period before it, the change and how it was reached. Call it with no `metrics` to list the keys and what each counts, then with up to 12 keys to read them. Quote these figures in an answer; do not state a number that none of them gives.

POST /api/v1/tools/get_metric_figures · scope read

  • workspace string, optional
  • metrics array of string, optional. Metric keys from the catalogue. Leave out to list the catalogue.
  • range one of: today, 7d, 30d, 90d, mtd, qtd, ytd, all, optional. today, 7d, 30d, 90d, mtd, qtd, ytd or all. Default 30d. Days follow the client time zone.
  • compare boolean, optional. Also read the period before, for the change. Not for all time.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_vsl_summary

Get VSL summary

Every VSL video with views, completed views, average watch time and the 15-second stretch where the most viewers stop watching (needs 50 views). All-time; up to 20 videos.

POST /api/v1/tools/get_vsl_summary · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

get_tracking_summary

Get tracking summary

Visitor behaviour over a window (page views by hour and weekday in UTC, device, browser, country, median time on page, scroll depth, returning visitors) and, per tracking source (see list_sources), visitors, net revenue, revenue per visitor and share of revenue over the same window, by first or last touch.

POST /api/v1/tools/get_tracking_summary · scope read

  • workspace string, optional
  • days integer, optional. Lookback window in days, default 30, max 90.
  • model one of: first_touch, last_touch, optional. Which touch gets the revenue, default first_touch.

Responds 200 · 400 · 401 · 403 · 404 · 429

check_tracking_install

Check tracking install

Fetch one page of the client's site and check the SIGNL tag on it: present, this workspace's id, loaded from SIGNL, async, not doubled, held by a consent tool, plus events from that host in the last 24 hours and 14 days. Reads the HTML only (no JavaScript on the page is run), so a page built in the browser answers status unknown. Returns status (ok, degraded, broken, not_installed, unknown) and findings, each with an explanation and a fix. Ten checks a minute per workspace.

POST /api/v1/tools/check_tracking_install · scope read

  • workspace string, optional
  • url string, required. The page to check, e.g. https://yoursite.com/apply. Public http(s) addresses only.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_email_stats

Get email stats

Email performance from the client's connected Kit account: sent, opened and clicked with open and click rates over Kit's last 90 days, subscriber growth, and per-broadcast stats for recent broadcasts. Says so when Kit is not connected.

POST /api/v1/tools/get_email_stats · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

list_ad_campaigns

List ad campaigns

Ad campaigns SIGNL has seen for this client, newest first: platform, status, objective and currency, and whether pause, resume and budget can act on it (`controllable`: Meta and Whop today). The ids are what pause_ad_campaign, resume_ad_campaign and update_ad_campaign_budget take.

POST /api/v1/tools/list_ad_campaigns · scope read

  • workspace string, optional
  • platform one of: meta, google, tiktok, youtube, linkedin, whop, other, optional. Only campaigns on this platform.
  • limit integer, optional. Max results, default 50, capped at 100.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_talent

List talent

Sales roster (closers, setters, managers) for this client. Use these ids to assign calls.

POST /api/v1/tools/list_talent · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

list_automations

List automations

Automations for this client with trigger type, active state, and run counts.

POST /api/v1/tools/list_automations · scope read

  • workspace string, optional
  • limit integer, optional. Max results, default 100, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_cadences

List cadences

Outbound follow-up cadences for this client. Use these ids with enroll_lead_in_cadence.

POST /api/v1/tools/list_cadences · scope read

  • workspace string, optional
  • limit integer, optional. Max results, default 100, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_sources

List traffic sources

Every traffic source a tracked link can sit under: the built-in ones (YouTube, Instagram, Kit, Email…) and this client’s own, with each one’s key, default utm_source and utm_medium, whether it is hidden in the Source tab, and how many content items it has. Pass a key as create_tracked_link’s `source`.

POST /api/v1/tools/list_sources · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

get_content_performance

Get content performance

One row per content item in the Source tab (a video, a post, a broadcast or a campaign filed under a source such as YouTube, Instagram, Email or your own), with the numbers that tab shows: the item's links, their clicks, and the forms, calls booked and revenue (integer pence) of people whose first tracked link was one of them, plus their calls that showed (shows), calls won (wins) and ledger cash by currency in minor units (cash). All time by default; days counts one window, with clicks and revenue from the dated click ledger (ledgerCovers.note says when the window starts before it). A YouTube video is one item however many links it has. Pass a source key from list_sources to see one source.

POST /api/v1/tools/get_content_performance · scope read

  • workspace string, optional
  • source string, optional. Only items under this source key (see list_sources): youtube, instagram, tiktok, email, x, or one of your own.
  • sort one of: newest, revenue, bookings, forms, clicks, name, optional. Order: revenue (default), bookings, forms, clicks, newest or name.
  • days integer, optional. Count only the last N days (1 to 365). Leave out for all time.
  • limit integer, optional. Max results, default 50, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_forms

List forms

Forms for this client with view, start, submission counts and completion rate.

POST /api/v1/tools/list_forms · scope read

  • workspace string, optional
  • limit integer, optional. Max results, default 100, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_form_submissions

List form submissions

Recent form submissions with answers, most recent first.

POST /api/v1/tools/list_form_submissions · scope read

  • workspace string, optional
  • form_id string, uuid, optional. Restrict to one form.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_form

Get form

One form in full: fields with their stable ids, pages, endings, qualification rules and settings. Read this before update_form, and send the ids back, so rules keep matching.

POST /api/v1/tools/get_form · scope read

  • workspace string, optional
  • form_id string, uuid, required

Responds 200 · 400 · 401 · 403 · 404 · 429

list_booking_pages

List booking pages

Booking pages (calendars) for this client with status, duration and booking count.

POST /api/v1/tools/list_booking_pages · scope read

  • workspace string, optional
  • limit integer, optional. Max results, default 100, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_booking_page

Get booking page

One booking page with every setting that changes how it behaves: duration, buffer, notice, window, weekly hours, intake questions, location, hosts and endings.

POST /api/v1/tools/get_booking_page · scope read

  • workspace string, optional
  • page_id string, uuid, required

Responds 200 · 400 · 401 · 403 · 404 · 429

list_availability_schedules

List availability schedules

Shared weekly-hours schedules a booking page can use instead of its own hours, with their time zones.

POST /api/v1/tools/list_availability_schedules · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

get_call

Get call detail

One call in full: lead, rep, status, outcome, objection, notes, recording summary and the post-call record.

POST /api/v1/tools/get_call · scope read

  • workspace string, optional
  • call_id string, uuid, required. From list_calls.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_deal

Get deal detail

One deal in full, including notes and custom fields.

POST /api/v1/tools/get_deal · scope read

  • workspace string, optional
  • deal_id string, uuid, required. From list_deals.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_call_transcript

Get call transcript

The recording transcript of one call, up to 20,000 characters per response. Check `hasMore` and send `nextOffset` back as `offset` to read the rest. Personal data: read it to answer a question about a call, not to copy it elsewhere. Empty until transcription has run (see `transcriptionStatus`).

POST /api/v1/tools/get_call_transcript · scope read

  • workspace string, optional
  • call_id string, uuid, required. From list_calls.
  • offset integer, optional. Character offset; `nextOffset` from the previous slice.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_tags

List tags

Every tag in use on this client’s leads with how many leads carry it, most used first. Use it to pick a tag for list_leads or update_lead instead of guessing spelling.

POST /api/v1/tools/list_tags · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

get_ad_performance

Get ad performance

Ad campaigns over the last N days (default 30, at most 90): spend (integer pence, `null` when no spend row exists, which is unmeasured and not free), impressions, clicks, CTR and CPC, highest spend first. Same numbers as the Ads page.

POST /api/v1/tools/get_ad_performance · scope read

  • workspace string, optional
  • days integer, optional. Lookback window in days, default 30, max 90.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_offers

List offers

What this client sells: name, description, price (integer minor units in `currency`) and whether it is active. Offer ids link calls and deals to what was sold.

POST /api/v1/tools/list_offers · scope read

  • workspace string, optional
  • active boolean, optional. Only active (true) or inactive (false) offers.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_contracts

List contracts

Agreements sent for e-signature, newest first: status, signed total (integer minor units), the lead it is for (`leadId`, null for someone kept out of the CRM), the linked deal (often null: a contract need not have one) and dates. `get_contract` has the text and each signer.

POST /api/v1/tools/list_contracts · scope read

  • workspace string, optional
  • lead_id string, uuid, optional. Only this lead’s contracts (a lead id from list_leads).
  • status one of: draft, sent, viewed, signed, declined, expired, voided, optional. Only contracts in this status: draft, sent, viewed, signed, declined, expired or voided. A fully signed contract is "signed".
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_contract

Get contract

One contract with its text (first 20,000 characters), its sections, the template version it was drafted from, the fields the signer fills in (key, type, label, required) with the values they entered once signed, and each signer’s name, email, role and status. Signing links and drawn signatures are never returned.

POST /api/v1/tools/get_contract · scope read

  • workspace string, optional
  • contract_id string, uuid, required. From list_contracts.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_contract_templates

List contract templates

This workspace’s active contract templates, newest edit first: id, name, current version, whether it is a copy of an agency template and when it last changed. `get_contract_template` has the sections.

POST /api/v1/tools/list_contract_templates · scope read

  • workspace string, optional
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_contract_template

Get contract template

One contract template at its current version: its sections (key, heading, text, whether locked) and line items. Templates are written in the app.

POST /api/v1/tools/get_contract_template · scope read

  • workspace string, optional
  • id string, uuid, required. From list_contract_templates.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_webinars

List webinars

Webinars for this client, newest first (deleted ones excluded): title, slug, mode, status and timezone.

POST /api/v1/tools/list_webinars · scope read

  • workspace string, optional
  • status string, optional. Only webinars in this status.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_webinar_registrations

List webinar registrations

Who registered for one webinar, newest first: name, email, status, session time, how much they watched and whether they clicked the call to action.

POST /api/v1/tools/list_webinar_registrations · scope read

  • workspace string, optional
  • webinar_id string, uuid, required. From list_webinars.
  • status string, optional. Only registrations in this status.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_custom_fields

List custom fields

The custom fields this client added, with key, label, type, choices and what they attach to (leads, calls or deals).

POST /api/v1/tools/list_custom_fields · scope read

  • workspace string, optional
  • target string, optional. Only fields on this object, e.g. "lead" or "deal".

Responds 200 · 400 · 401 · 403 · 404 · 429

list_dni_numbers

List tracking numbers

The client’s call-tracking phone numbers: number, name, where it forwards, country and status.

POST /api/v1/tools/list_dni_numbers · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

list_data_tables

List data tables

The client’s own tables (the Data page): name, description, field definitions and whether the rows come from a form, booking page or report or are entered by hand. Use the ids with list_data_records.

POST /api/v1/tools/list_data_tables · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

list_data_records

List data records

Rows of one data table, newest first. `values` is keyed by the table’s field ids from list_data_tables.

POST /api/v1/tools/list_data_records · scope read

  • workspace string, optional
  • table_id string, uuid, required. From list_data_tables.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_dashboards

List dashboards

The client’s custom dashboards: name, description, which is the default, whether the client portal shows it, and how many widgets it has.

POST /api/v1/tools/list_dashboards · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

list_import_runs

List import runs

Imports and syncs, newest first: mode, status, file name, rows total, processed and failed, per-kind counts, any error, and whether it was undone.

POST /api/v1/tools/list_import_runs · scope read

  • workspace string, optional
  • status string, optional. Only runs in this status, e.g. "failed" or "completed".
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_training_assignments

List training assignments

Role-play practice assigned to reps, newest first: who, against which persona, status, due date and note.

POST /api/v1/tools/list_training_assignments · scope read

  • workspace string, optional
  • status string, optional. Only assignments in this status.
  • talent_id string, uuid, optional. Only this rep, from list_talent.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_task

Get task detail

One task by id.

POST /api/v1/tools/get_task · scope read

  • workspace string, optional
  • task_id string, uuid, required. From list_tasks.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_payments

List payments

Payments received from connected providers (Stripe, Whop and others), newest first. Amounts are integer minor units in the currency returned beside them; refunds point at the payment they reverse.

POST /api/v1/tools/list_payments · scope read

  • workspace string, optional
  • since string, optional. ISO 8601 timestamp; only payments on or after it.
  • kind string, optional. Filter by kind, e.g. "charge" or "refund".
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_payment_plans

List payment plans

Payment plans with every instalment, what is paid, and what is due. Use for "who is behind on their plan".

POST /api/v1/tools/list_payment_plans · scope read

  • workspace string, optional
  • status one of: active, completed, defaulted, optional
  • limit integer, optional. Max results, default 25, capped at 100.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_eod_reports

List EOD reports

End-of-day reports from the sales team, newest first: calls taken, shows, offers, closes, cash collected and the template answers.

POST /api/v1/tools/list_eod_reports · scope read

  • workspace string, optional
  • talent_id string, uuid, optional. From list_talent.
  • since string, optional. ISO 8601 date; only reports submitted on or after it.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_commission_entries

List commission entries

The individual commission rows behind get_commissions_summary, with the call or deal each came from.

POST /api/v1/tools/list_commission_entries · scope read

  • workspace string, optional
  • status one of: pending, approved, paid, disputed, optional
  • talent_id string, uuid, optional. From list_talent.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_recordings

List recordings

Screen and video recordings in this workspace. Share links are not returned.

POST /api/v1/tools/list_recordings · scope read

  • workspace string, optional
  • limit integer, optional. Max results, default 25, capped at 100.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_sops

List SOPs

Standard operating procedures, with their section and a short excerpt of each. Use get_sop for the full text.

POST /api/v1/tools/list_sops · scope read

  • workspace string, optional
  • limit integer, optional. Max results, default 25, capped at 100.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_sop

Get SOP

One SOP with its full body.

POST /api/v1/tools/get_sop · scope read

  • workspace string, optional
  • sop_id string, uuid, required. From list_sops.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_cadence_enrollments

List cadence enrolments

Leads enrolled in cadences: which step they are on, when the next action runs, and whether they replied or failed.

POST /api/v1/tools/list_cadence_enrollments · scope read

  • workspace string, optional
  • cadence_id string, uuid, optional. From list_cadences.
  • status one of: active, paused, completed, replied, failed, optional
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_messages

List a lead's messages

One lead's texts, WhatsApp messages and emails, newest first: what SIGNL sent (a subject or the first 80 characters, with delivery status) and what the lead replied by text or WhatsApp. Inbound email is not recorded yet.

POST /api/v1/tools/list_messages · scope read

  • workspace string, optional
  • lead_id string, uuid, required. From list_leads.
  • channel one of: sms, whatsapp, email, optional
  • direction one of: in, out, optional. in = the lead wrote, out = SIGNL sent.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

get_usage

Get credit usage

What this workspace has spent in credits, and what the caller has left: credits used in a window (default this month, UTC), split by vendor (AI, texts and calls, transcription, email, Meeting Bots) and by feature, optionally by day, plus the caller's own balance (credits belong to each person). Use it for "what have I spent on texts this month?". The balance is null when no person is calling.

POST /api/v1/tools/get_usage · scope read

  • workspace string, optional
  • from string, optional. Start of the window, ISO date. Default: the first of this month (UTC).
  • to string, optional. End of the window, ISO date, exclusive. Default: now. At most 366 days from `from`.
  • vendor one of: anthropic, twilio, deepgram, resend, recall, optional. anthropic = AI, twilio = texts and calls, deepgram = transcription, resend = email, recall = Meeting Bots.
  • by_day boolean, optional. Add a per-day breakdown.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_lead_history

List a lead's owner history

The recorded changes to one lead's owner, newest first: who it was, who it became, who changed it (a member, the Agent with the member who approved it, an API key) and when. History starts on 5 Oct 2026; earlier changes are not reconstructed.

POST /api/v1/tools/list_lead_history · scope read

  • workspace string, optional
  • lead_id string, uuid, required. From list_leads.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

list_deal_history

List a deal's stage history

The recorded stage moves of one deal, newest first: from, to, who moved it (a member, the Agent with the member who approved it, an automation, an API key) and when, plus the time spent in each stage. History starts on 5 Oct 2026; earlier moves are not reconstructed.

POST /api/v1/tools/list_deal_history · scope read

  • workspace string, optional
  • deal_id string, uuid, required. From list_deals.
  • limit integer, optional. Max results, default 25, capped at 100.
  • offset integer, optional. Skip this many results. Pass `nextOffset` from the previous page; the response says `hasMore`.

Responds 200 · 400 · 401 · 403 · 404 · 429

whoami

Who am I

Which workspace this connection is working in and who it is acting as: the workspace name and slug, whether it acts as a team member or an API key or connector (and its name), and the time zone dates are read in. Call it first when you start a task with no context. It returns no ids, keys or permissions.

POST /api/v1/tools/whoami · scope read

  • workspace string, optional

Responds 200 · 400 · 401 · 403 · 404 · 429

Tools: write

13

create_lead

Create lead

Create a lead for this client. Deduplicates on email then phone — if a matching lead exists it is returned instead of creating a duplicate.

POST /api/v1/tools/create_lead · scope write

  • workspace string, optional
  • name string, optional. Full name. Kept as sent; never split into first and last.
  • first_name string, optional. Given name, when known. Stored as an explicit value.
  • last_name string, optional. Family name, when known. Stored as an explicit value.
  • email string, email, optional
  • phone string, optional
  • tags array of string, optional
  • intent_score integer, optional
  • source string, optional. First-touch source, default "mcp".
  • medium string, optional. First-touch medium, default "api".
  • campaign string, optional

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

update_lead

Update lead

Update a lead. Tag changes are additive/subtractive via add_tags and remove_tags — existing tags are never blindly overwritten.

POST /api/v1/tools/update_lead · scope write

  • workspace string, optional
  • lead_id string, uuid, required
  • name string, optional. Full name. Changing it alone clears first_name and last_name when they no longer match it.
  • first_name string or null, optional. Given name. Omit to keep; null or empty clears. The full name follows first and last unless name is also sent.
  • last_name string or null, optional. Family name. Omit to keep; null or empty clears.
  • email string, email, optional
  • phone string, optional
  • intent_score integer, optional
  • is_customer boolean, optional
  • add_tags array of string, optional
  • remove_tags array of string, optional

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

add_lead_note

Add lead note

Append a timestamped note to a lead. Attributed to the API key that wrote it.

POST /api/v1/tools/add_lead_note · scope write

  • workspace string, optional
  • lead_id string, uuid, required
  • body string, required

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

create_call

Create call

Log a booked call for this client.

POST /api/v1/tools/create_call · scope write

  • workspace string, optional
  • lead_name string, required
  • scheduled_at string, required. ISO 8601 timestamp.
  • lead_email string, email, optional
  • lead_phone string, optional
  • call_type one of: discovery, closing, consult, follow_up, optional
  • talent_id string, uuid, optional. Rep to assign, from list_talent. Must be active.
  • setter_talent_id string, uuid, optional. The active setter who booked it, from list_talent. Setter commission reads this.
  • offer_id string, uuid, optional. What the call is selling, from list_offers.
  • lead_id string, uuid, optional. Link to an existing lead.
  • duration_minutes integer, optional
  • notes string, optional

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

update_call

Update call

Update a call — typically logging the outcome after it happened, or pushing its transcript or recording link from any call recorder. Money is integer pence. Does not create commission entries; the commissions engine derives those from rules.

POST /api/v1/tools/update_call · scope write

  • workspace string, optional
  • call_id string, uuid, required
  • status one of: booked, showed, no_show, cancelled, completed, optional
  • outcome one of: won, lost, follow_up, no_decision, pending, disqualified, no_pitch_dq, optional
  • deal_value_pence integer, optional. Integer pence, never a decimal amount.
  • objection string, optional
  • notes string, optional
  • talent_id string, uuid, optional
  • setter_talent_id string, uuid, optional. The active setter who booked it, from list_talent.
  • offer_id string, uuid, optional. What was sold, from list_offers.
  • cancel_reason string, optional. Why it was cancelled; use with status "cancelled".
  • recording_transcript string, optional. The call transcript as plain text, from any recorder. Feeds call scoring. Refused if the call already has one, unless replace_transcript is true.
  • replace_transcript boolean, optional. Set true to replace a transcript the call already has.
  • recording_url string, uri, optional. The recording link, stored on the call. A Fathom, Fireflies or Zoom link also imports the transcript from that tool when it is connected.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

create_deal

Create deal

Create a CRM deal. Call list_pipelines first to get a valid stage_id.

POST /api/v1/tools/create_deal · scope write

  • workspace string, optional
  • title string, required
  • contact_name string, required
  • stage_id string, uuid, required. Stage id from list_pipelines.
  • contact_email string, email, optional
  • value_pence integer, optional. Integer pence.
  • probability integer, optional
  • expected_close_date string, optional. ISO date, e.g. 2026-09-01.
  • lead_id string, uuid, optional
  • offer_id string, uuid, optional. What the deal is for. Offer id from list_offers.
  • notes string, optional

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

update_deal

Update deal

Update a deal — move stage, change value, or mark won/lost (with a loss_reason when lost). Moving stage keeps the pipeline consistent automatically. A stage can require fields before a deal enters it (value, close date, offer, custom fields): a move that leaves any empty is refused and names them, so set them in the same call or first.

POST /api/v1/tools/update_deal · scope write

  • workspace string, optional
  • deal_id string, uuid, required
  • stage_id string, uuid, optional
  • status one of: open, won, lost, optional
  • title string, optional
  • value_pence integer, optional. Integer pence.
  • probability integer, optional
  • expected_close_date string, optional
  • offer_id string, uuid or null, optional. Offer id from list_offers, or null to clear it.
  • notes string, optional
  • loss_reason one of: price, timing, no_budget, competitor, not_a_fit, no_response, other or null, optional. Why a lost deal was lost: price, timing, no_budget, competitor, not_a_fit, no_response or other. Needs the deal to be lost (set status to lost in the same call). null clears it. Reopening or winning a deal clears it automatically.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

create_task

Create task

Create a task, optionally linked to a lead.

POST /api/v1/tools/create_task · scope write

  • workspace string, optional
  • title string, required
  • description string, optional
  • due_at string, optional. ISO 8601 timestamp, or a date. Stored as that instant in UTC; include an offset if the time matters.
  • lead_id string, uuid, optional
  • assignee_member_id string, uuid, optional. Who does it: the `member_id` on a list_talent row. Must be a team member of this workspace.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

update_task

Update task

Update or complete a task. Setting status to done stamps the completion time.

POST /api/v1/tools/update_task · scope write

  • workspace string, optional
  • task_id string, uuid, required
  • status one of: open, done, optional
  • title string, optional
  • description string, optional
  • due_at string, optional
  • assignee_member_id string, uuid or null, optional. A team member (list_talent `member_id`), or null to unassign.
  • lead_id string, uuid or null, optional. Link the task to a lead, or null to unlink.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

create_source

Create traffic source

Add a traffic source of this client’s own (up to 40). Its key is its name as a slug; a built-in source’s name is refused. Links and content items go under it with create_tracked_link.

POST /api/v1/tools/create_source · scope write

  • workspace string, optional
  • name string, required
  • utm_source string, optional. Default utm_source for its links. Defaults to the key.
  • utm_medium string, optional. Default utm_medium, e.g. bio, story, email, dm.
  • icon string, optional. brand:<id> for a logo or lucide:<Name> for an icon. Defaults to lucide:Link.
  • default_destination_url string, uri, optional. Where its new links point by default.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

create_sop

Create SOP

Write a new standard operating procedure. role_scope labels who it is for, e.g. ["closer"]; it does not restrict who can read it.

POST /api/v1/tools/create_sop · scope write

  • workspace string, optional
  • title string, required
  • body string, optional. Markdown.
  • role_scope array of string, optional
  • section string or null, optional. Group label such as "Sales"; blank or null leaves it unsectioned.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

update_sop

Update SOP

Change an SOP. Only the fields you send change; body replaces the whole text.

POST /api/v1/tools/update_sop · scope write

  • workspace string, optional
  • sop_id string, uuid, required. From list_sops.
  • title string, optional
  • body string, optional
  • role_scope array of string, optional
  • section string or null, optional. Group label such as "Sales"; blank or null removes it from its section.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

Tools: write:sensitive

2

enroll_lead_in_cadence

Enrol a lead in a cadence

Start an outbound follow-up cadence for a lead. This sends real messages to a real person — requires the write:sensitive scope. Refuses a lead who has bounced, complained or unsubscribed when the cadence sends email.

POST /api/v1/tools/enroll_lead_in_cadence · scope write:sensitive

  • workspace string, optional
  • lead_id string, uuid, required. Lead id from list_leads.
  • cadence_id string, uuid, required. Cadence id from list_cadences.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

set_automation_status

Activate or pause an automation

Turn an automation on or off. An active automation can contact leads, so this requires the write:sensitive scope. Switching on is refused when the published version cannot do anything (the same check as the Active toggle in SIGNL), and steps that will skip are returned as warnings. Editing the automation node graph is intentionally not exposed here.

POST /api/v1/tools/set_automation_status · scope write:sensitive

  • workspace string, optional
  • automation_id string, uuid, required
  • is_active boolean, required

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

Tools: write:ads

3

pause_ad_campaign

Pause ad campaign

Pause a running ad campaign on the platform it is connected to. Spends real money if left running, so requires the write:ads scope. Meta and Whop today — a Google or TikTok campaign, or one only ever seen as a UTM string, is refused with the reason (roadmap E2).

POST /api/v1/tools/pause_ad_campaign · scope write:ads

  • workspace string, optional
  • campaign_id string, uuid, required. ad_campaigns id from list_ad_campaigns, not the platform’s own campaign id.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

resume_ad_campaign

Resume ad campaign

Resume a paused ad campaign on the platform it is connected to. This starts real spend again, so requires the write:ads scope. Meta and Whop today (roadmap E2).

POST /api/v1/tools/resume_ad_campaign · scope write:ads

  • workspace string, optional
  • campaign_id string, uuid, required. ad_campaigns id from list_ad_campaigns.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

update_ad_campaign_budget

Change ad campaign daily budget

Change a running ad campaign’s daily budget on the platform it is connected to. Changes real spend, so requires the write:ads scope. Meta and Whop today; refused when the campaign’s currency is unset or is not what SIGNL displays, the same guard ad-spend import uses. Capped at 10000 USD/day — a higher figure is refused rather than sent, to catch a fat-fingered amount (e.g. typing pounds where pence, or dollars where cents, were meant) before it reaches the platform.

POST /api/v1/tools/update_ad_campaign_budget · scope write:ads

  • workspace string, optional
  • campaign_id string, uuid, required. ad_campaigns id from list_ad_campaigns.
  • daily_budget_pence integer, required. Integer pence, SIGNL’s convention everywhere — converted to the account’s own currency before it reaches the platform. Hard-capped at 1000000 (10000 USD/day); a larger value is refused, not clamped.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

Tools: write:builder

5

create_form

Create form (draft)

Create a form as a DRAFT: fields, pages, endings and qualification rules. Nothing goes live; a person publishes it in SIGNL. Give an id to any field or option a rule refers to. Branching logic from another platform is never imported automatically; if you are migrating a form, list the rules you could not express and tell the operator.

POST /api/v1/tools/create_form · scope write:builder

  • workspace string, optional
  • name string, required
  • description string, optional. Shown in link previews, under the name on a classic form, and as the start screen of a one-question-at-a-time form (a blank line splits its heading from its text).
  • mode one of: classic, paged, typeform, optional. classic: every question on one page. paged: one page per screen, with Next and Back (use pages and each field's pageId). typeform: one question at a time.
  • fields array of object, optional. The questions, in order. On update this REPLACES the list — read get_form first and send every field you want to keep, with its id.
  • pages array of object, optional
  • endings array of object, optional. Screens a lead lands on: { id, kind: "thank_you" | "redirect" | "calendar", title?, body?, redirect_url?, booking_page_id? }. Defaults to one thank-you ending.
  • qualification_rules array of object, optional. { id, match: "all" | "any", conditions: [{ field_id, operator, value }], outcome: "qualified" | "disqualified", ending_id }. Operators: equals, not_equals, contains, not_contains, greater_than, less_than, is_empty, is_not_empty.
  • default_ending_id string, optional
  • redirect_url string, uri, optional
  • notification_email string, email, optional
  • theme one of: dark, light, optional

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

update_form

Update draft form

Edit a form. A draft is edited directly. A published form keeps its live version: the edit goes to its working copy and reaches visitors only when a person presses Publish changes in SIGNL. Refuses an archived form. `fields` replaces the whole list, so call get_form first and send every field you want to keep, with its id.

POST /api/v1/tools/update_form · scope write:builder

  • workspace string, optional
  • form_id string, uuid, required
  • name string, optional
  • description string, optional. Shown in link previews, under the name on a classic form, and as the start screen of a one-question-at-a-time form (a blank line splits its heading from its text).
  • mode one of: classic, paged, typeform, optional. classic: every question on one page. paged: one page per screen, with Next and Back (use pages and each field's pageId). typeform: one question at a time.
  • fields array of object, optional. The questions, in order. On update this REPLACES the list — read get_form first and send every field you want to keep, with its id.
  • pages array of object, optional
  • endings array of object, optional. Screens a lead lands on: { id, kind: "thank_you" | "redirect" | "calendar", title?, body?, redirect_url?, booking_page_id? }. Defaults to one thank-you ending.
  • qualification_rules array of object, optional. { id, match: "all" | "any", conditions: [{ field_id, operator, value }], outcome: "qualified" | "disqualified", ending_id }. Operators: equals, not_equals, contains, not_contains, greater_than, less_than, is_empty, is_not_empty.
  • default_ending_id string, optional
  • redirect_url string, uri, optional
  • notification_email string, email, optional
  • theme one of: dark, light, optional
  • paginate string, optional. "one_per_page" re-pages the form so each screen is its own page: one question each, a contact block or question group kept together, a statement on its own. It replaces `pages` and every field's pageId.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

import_form

Import form from Typeform (draft)

Import a Typeform from its public link as a DRAFT: questions, choices, endings and jumps. Returns `unmapped`, the list of what could not come across (score or variable logic, dropped screens). Always tell the operator what is in `unmapped` before they publish; never imply the logic came across when it did not.

POST /api/v1/tools/import_form · scope write:builder

  • workspace string, optional
  • url string, required. The public Typeform link, e.g. https://yourname.typeform.com/to/AbC123.
  • name string, optional. Defaults to the Typeform title.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

create_booking_page

Create booking page (draft)

Create a booking page (calendar) as a DRAFT: duration, buffer, notice, booking window, weekly hours and time zone (or a shared schedule), hosts (one, or a round-robin pool from list_talent), intake questions, location and look. It takes no bookings until a person activates it in SIGNL.

POST /api/v1/tools/create_booking_page · scope write:builder

  • workspace string, optional
  • name string, required
  • duration_minutes integer, required
  • description string, optional
  • buffer_minutes integer, optional. Gap kept free after each call. Default 10.
  • min_notice_minutes integer, optional. How soon ahead a lead can book.
  • booking_window_days integer, optional. How far ahead a lead can book. Default 90.
  • weekly_hours object, optional. Bookable hours per day, e.g. { "mon": [{ "start": "09:00", "end": "17:00" }] }. Replaces the whole week: a day left out is closed.
  • time_zone string, optional. IANA zone the weekly hours are in, e.g. Europe/London. Gives the page its own zone, which stays put when the workspace timezone changes.
  • follow_account_timezone boolean, optional. true: the page follows the workspace timezone and moves when it changes (not with time_zone). false: keep the zone it has as its own. A new page follows the workspace by default.
  • availability_schedule_id string, uuid or null, optional. Use a shared schedule (list_availability_schedules) for the hours instead of weekly_hours. null clears it.
  • send_confirmation_email boolean, optional
  • max_attendees integer, optional. Seats per slot: how many people can book the same time. 1 (the default) is one-to-one; more makes a group event and the page shows "N seats left".
  • first_slot_only boolean, optional. true: the page offers only its earliest open time, and the confirm step refuses any other. false: the whole calendar.
  • assignment_mode one of: single, round_robin, optional. single: one host. round_robin: rotate across talent_pool.
  • host_talent_id string, uuid or null, optional. The host for single mode, from list_talent.
  • talent_pool array of string, uuid, optional. Hosts to rotate across in round_robin mode, from list_talent.
  • questions array of object, optional. Intake questions. Defaults to name, email and phone. On update this REPLACES the list.
  • name_format one of: full, split, optional. "full": one name box. "split": first name and last name boxes, both required. Switches which of the name questions shows and keeps the wording of each; applies to questions when sent too.
  • bullet_points array of string, optional. What the call covers, shown beside the calendar.
  • consent_text string, optional
  • location object, optional
  • theme one of: dark, light, optional
  • accent_color string, optional. Hex, e.g. #2334d1.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

update_booking_page

Update draft booking page

Edit a DRAFT booking page. Refuses an active or inactive page. `questions` replaces the whole list.

POST /api/v1/tools/update_booking_page · scope write:builder

  • workspace string, optional
  • page_id string, uuid, required
  • name string, optional
  • duration_minutes integer, optional
  • description string, optional
  • buffer_minutes integer, optional. Gap kept free after each call. Default 10.
  • min_notice_minutes integer, optional. How soon ahead a lead can book.
  • booking_window_days integer, optional. How far ahead a lead can book. Default 90.
  • weekly_hours object, optional. Bookable hours per day, e.g. { "mon": [{ "start": "09:00", "end": "17:00" }] }. Replaces the whole week: a day left out is closed.
  • time_zone string, optional. IANA zone the weekly hours are in, e.g. Europe/London. Gives the page its own zone, which stays put when the workspace timezone changes.
  • follow_account_timezone boolean, optional. true: the page follows the workspace timezone and moves when it changes (not with time_zone). false: keep the zone it has as its own. A new page follows the workspace by default.
  • availability_schedule_id string, uuid or null, optional. Use a shared schedule (list_availability_schedules) for the hours instead of weekly_hours. null clears it.
  • send_confirmation_email boolean, optional
  • max_attendees integer, optional. Seats per slot: how many people can book the same time. 1 (the default) is one-to-one; more makes a group event and the page shows "N seats left".
  • first_slot_only boolean, optional. true: the page offers only its earliest open time, and the confirm step refuses any other. false: the whole calendar.
  • assignment_mode one of: single, round_robin, optional. single: one host. round_robin: rotate across talent_pool.
  • host_talent_id string, uuid or null, optional. The host for single mode, from list_talent.
  • talent_pool array of string, uuid, optional. Hosts to rotate across in round_robin mode, from list_talent.
  • questions array of object, optional. Intake questions. Defaults to name, email and phone. On update this REPLACES the list.
  • name_format one of: full, split, optional. "full": one name box. "split": first name and last name boxes, both required. Switches which of the name questions shows and keeps the wording of each; applies to questions when sent too.
  • bullet_points array of string, optional. What the call covers, shown beside the calendar.
  • consent_text string, optional
  • location object, optional
  • theme one of: dark, light, optional
  • accent_color string, optional. Hex, e.g. #2334d1.

Responds 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429

Agency tools: read

10

list_clients

List clients

Every client workspace in the organisation: id, slug, name, status, type and the name of its current package (null when it has none). Use the slug as the `workspace` argument of client tools.

POST /api/v1/tools/list_clients · scope read · organisation-wide key only

  • status one of: active, inactive, prospect, churned, optional. Only clients with this status.

Responds 200 · 400 · 401 · 403 · 429

get_portfolio_overview

Portfolio overview

The whole agency at a glance, over the last 30 days: totals across active clients, clients by status, average measured close and show rates, clients below their ROAS target, top performers, daily revenue trend and the team leaderboard. The same figures the agency dashboard shows. Package retainers are per client, each in its own currency — never totalled across clients. Start portfolio questions here.

POST /api/v1/tools/get_portfolio_overview · scope read · organisation-wide key only

No body fields.

Responds 200 · 400 · 401 · 403 · 429

compare_clients

Compare clients

Side-by-side performance for several clients over the last 30 days, sorted. Omit `workspaces` to compare every active client. Rates are null when no calls were measured. Each client carries its current package (name, currency, monthly value) as /clients shows it.

POST /api/v1/tools/compare_clients · scope read · organisation-wide key only

  • workspaces array of string, optional. Client slugs to compare. Omit for every active client.
  • sort_by one of: collected_revenue, contracted_value, roas, close_rate, show_rate, optional. Default collected_revenue, highest first.

Responds 200 · 400 · 401 · 403 · 429

get_client_health

Client health

One client's performance over the last 30 days with plain flags for what deserves a look (below ROAS target, no calls, cash collected far below contracted), and its current package in its own currency. For detail inside the client, follow up with its client tools.

POST /api/v1/tools/get_client_health · scope read · organisation-wide key only

  • workspace string, required. The client slug (from list_clients).

Responds 200 · 400 · 401 · 403 · 429

list_packages

List packages

The packages this agency sells its clients: name, kind (core or add-on), status, terms in their own currency (retainer, setup fee and instalments, revenue share) and how many clients are on each today.

POST /api/v1/tools/list_packages · scope read · organisation-wide key only

  • status one of: draft, active, archived, optional. Only packages with this status.

Responds 200 · 400 · 401 · 403 · 429

list_statements

List agency statements

What each client owes the agency, month by month, newest first: client, period, status, total and paid (integer minor units in the statement’s currency) and the engine’s warnings. Read only: issuing, voiding and recording payment stay in SIGNL.

POST /api/v1/tools/list_statements · scope read · organisation-wide key only

  • workspace string, optional. Only this client (slug).
  • status string, optional. Only statements in this status, e.g. "draft", "issued" or "paid".
  • limit integer, optional. Max results, default 50, capped at 100.

Responds 200 · 400 · 401 · 403 · 429

list_event_templates

List event templates

Managed booking-page templates defined once and pushed to clients: name, duration, how many fields are locked and how many client pages are linked. Owners and admins only.

POST /api/v1/tools/list_event_templates · scope read · organisation-wide key only

No body fields.

Responds 200 · 400 · 401 · 403 · 429

list_agency_skills

List agency skills

Agent skills the agency wrote once and pushed to clients: title, version, the tools each names, and for every client carrying a still-linked copy whether it is locked and whether it has the latest version. Owners and admins only.

POST /api/v1/tools/list_agency_skills · scope read · organisation-wide key only

No body fields.

Responds 200 · 400 · 401 · 403 · 429

list_org_members

List team members

Everyone with a SIGNL login in the organisation: name, email, role, the one client they are pinned to (if any) and when they were last active.

POST /api/v1/tools/list_org_members · scope read · organisation-wide key only

No body fields.

Responds 200 · 400 · 401 · 403 · 429

list_agency_talent

List talent across clients

Setters, closers and other talent across every client, with the client each works in and their paid commission, total calls and close rate from the agency leaderboard. Filter by workspace or role.

POST /api/v1/tools/list_agency_talent · scope read · organisation-wide key only

  • workspace string, optional. Only talent in this client (slug).
  • role string, optional. Only this role, e.g. closer or setter.
  • include_inactive boolean, optional. Include deactivated talent. Default false.

Responds 200 · 400 · 401 · 403 · 429

Agency tools: write:agency

19

create_client

Create a client

Create a new client workspace in the organisation, with the starter pipeline and report templates for its type. Counts against the plan’s client limit, and is refused at the limit exactly as Add Client is. Commercial terms are not set here: assign a package in SIGNL. Returns the new client’s id and slug, the workspace to use in every other tool.

POST /api/v1/tools/create_client · scope write:agency · organisation-wide key only

  • name string, required. The client’s name. The URL slug is derived from it.
  • type one of: coaching, agency, saas, ecom, info, optional. coaching (default), agency, saas, ecom or info. Picks the starter pipeline.
  • primary_contact string, optional. Who you deal with at the client.
  • primary_email string, optional. Their email address.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

update_client

Edit a client

Change a client’s name, contact, type, status or target ROAS. Send only the fields to change. Retainer and rev share belong to the client’s package and cannot be set here.

POST /api/v1/tools/update_client · scope write:agency · organisation-wide key only

  • workspace string, required. The client to edit: slug, id or exact name (list_clients).
  • name string, optional
  • primary_contact string, optional
  • primary_email string, optional. An empty string clears it.
  • type one of: coaching, agency, saas, ecom, info, optional
  • status one of: active, inactive, prospect, churned, optional
  • target_roas number, optional

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

archive_client

Archive a client

Archive a client: it leaves every agency list, aggregate and Login As, and its workspace becomes read-only. Reversible with restore_client. Its package assignment is left alone, so restoring brings it back on the terms it left with. Archiving again is a no-op.

POST /api/v1/tools/archive_client · scope write:agency · organisation-wide key only

  • workspace string, required. The client to archive: slug, id or exact name.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

restore_client

Restore an archived client

Bring an archived client back. Counts against the plan’s client limit again, and is refused at the limit. Takes the client’s id or slug as shown when it was archived.

POST /api/v1/tools/restore_client · scope write:agency · organisation-wide key only

  • client string, required. The archived client’s slug or id.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

create_package

Create a package

Add a package to the catalogue: a core offer (or an add-on) with its setup fee, retainer and/or rev share. Created as a draft unless `status` says otherwise; only an active package can be assigned to a client. Money is integer pence of the stated currency.

POST /api/v1/tools/create_package · scope write:agency · organisation-wide key only

  • name string, required
  • description string or null, optional
  • kind one of: core, add_on, required. core is what a client is on; add_on rides under a core package.
  • group_key string or null, optional. Groups alternative packages together in the catalogue.
  • sort_order integer, optional
  • status one of: draft, active, archived, optional. Default draft. Only an active package can be assigned.
  • deliverables array of object, optional
  • internal_notes string or null, optional
  • terms object, required. Commercial terms. At least one of a setup fee, a retainer or a rev share is required.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

update_package

Edit a package

Replace a package’s details and terms (send the whole package, as the edit form does; list_packages shows the current one). Clients already assigned keep the terms they were assigned on.

POST /api/v1/tools/update_package · scope write:agency · organisation-wide key only

  • package_id string, required. The package id (list_packages).
  • name string, required
  • description string or null, optional
  • kind one of: core, add_on, required. core is what a client is on; add_on rides under a core package.
  • group_key string or null, optional. Groups alternative packages together in the catalogue.
  • sort_order integer, optional
  • status one of: draft, active, archived, optional. Default draft. Only an active package can be assigned.
  • deliverables array of object, optional
  • internal_notes string or null, optional
  • terms object, required. Commercial terms. At least one of a setup fee, a retainer or a rev share is required.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

set_package_status

Activate, draft or archive a package

Move a package between draft, active and archived. Archiving hides it from new assignments; existing assignments are untouched.

POST /api/v1/tools/set_package_status · scope write:agency · organisation-wide key only

  • package_id string, required
  • status one of: draft, active, archived, required

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

duplicate_package

Duplicate a package

Copy a package as a new draft named “… (copy)”.

POST /api/v1/tools/duplicate_package · scope write:agency · organisation-wide key only

  • package_id string, required

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

delete_package

Delete a draft package

Permanently delete a package. Only a draft that has never been assigned can be deleted; anything else is refused (archive it instead).

POST /api/v1/tools/delete_package · scope write:agency · organisation-wide key only

  • package_id string, required

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

assign_package

Put a client on a package

Assign an active core package (and optional add-ons) to a client from a date, with the terms that apply to that client. This sets what the client will be billed from `effective_from`. Refused if the client already has a current package (use switch_package) or the date falls inside a period with an issued statement.

POST /api/v1/tools/assign_package · scope write:agency · organisation-wide key only

  • workspace string, required. The client: slug, id or exact name.
  • package_id string, required
  • effective_from string, required. YYYY-MM-DD.
  • terms object, required. Commercial terms. At least one of a setup fee, a retainer or a rev share is required.
  • add_ons array of object, optional
  • notes string or null, optional

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

switch_package

Switch a client to another package

Move a client from its current core package to another from a date: the current package (and its add-ons) ends the day before and the new one starts, in one step that is rolled back if it cannot complete. Switching to the same package is a re-price and does not charge the setup fee again. Refused inside a period with an issued statement.

POST /api/v1/tools/switch_package · scope write:agency · organisation-wide key only

  • workspace string, required. The client: slug, id or exact name.
  • package_id string, required
  • effective_from string, required. YYYY-MM-DD.
  • terms object, required. Commercial terms. At least one of a setup fee, a retainer or a rev share is required.
  • add_ons array of object, optional
  • notes string or null, optional

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

end_package_assignment

End a client’s package

End an assignment (and its add-ons) on a date. Cannot end before it started, or before the period covered by an issued statement.

POST /api/v1/tools/end_package_assignment · scope write:agency · organisation-wide key only

  • assignment_id string, required
  • effective_to string, required. YYYY-MM-DD.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

create_event_template

Create an event template

Define booking-page settings once for the agency: duration, buffer, questions, location, branding and rules. `locked_fields` names what clients cannot change on pages made from it. Nothing reaches a client until push_event_template.

POST /api/v1/tools/create_event_template · scope write:agency · organisation-wide key only

  • name string, required
  • duration_minutes integer, required
  • description string or null, optional
  • buffer_minutes integer, optional
  • questions array of object, optional
  • question_flow one of: inline, grouped, single, optional
  • bullet_points array of string, optional
  • consent_text string or null, optional
  • location one of: google_meet, zoom, phone or null, optional. google_meet, zoom or phone.
  • min_notice_minutes integer or null, optional
  • booking_horizon_days integer or null, optional
  • send_confirmation_email boolean, optional
  • reminder_1h_enabled boolean, optional
  • theme one of: dark, light, optional
  • accent_color string or null, optional. Hex like #2334d1.
  • accent_color_secondary string or null, optional
  • logo_url string or null, optional. Absolute http(s) URL.
  • prevent_duplicate_bookings boolean, optional
  • reschedule_with_same_host boolean, optional
  • locked_fields array of one of: name, description, duration, buffer, questions, highlights, consent, location, booking_window, notifications, branding, booking_rules, optional. Which groups of settings clients cannot change on pages from this template.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

update_event_template

Edit an event template

Change an event template; send only the fields to change. Saving propagates its LOCKED fields to every booking page already made from it, so this can change live client pages. The result says how many pages were updated.

POST /api/v1/tools/update_event_template · scope write:agency · organisation-wide key only

  • template_id string, required. The template id (list_event_templates).
  • name string, optional
  • duration_minutes integer, optional
  • description string or null, optional
  • buffer_minutes integer, optional
  • questions array of object, optional
  • question_flow one of: inline, grouped, single, optional
  • bullet_points array of string, optional
  • consent_text string or null, optional
  • location one of: google_meet, zoom, phone or null, optional. google_meet, zoom or phone.
  • min_notice_minutes integer or null, optional
  • booking_horizon_days integer or null, optional
  • send_confirmation_email boolean, optional
  • reminder_1h_enabled boolean, optional
  • theme one of: dark, light, optional
  • accent_color string or null, optional. Hex like #2334d1.
  • accent_color_secondary string or null, optional
  • logo_url string or null, optional. Absolute http(s) URL.
  • prevent_duplicate_bookings boolean, optional
  • reschedule_with_same_host boolean, optional
  • locked_fields array of one of: name, description, duration, buffer, questions, highlights, consent, location, booking_window, notifications, branding, booking_rules, optional. Which groups of settings clients cannot change on pages from this template.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

push_event_template

Push an event template to clients

Create a draft booking page from the template in each named client (slug, id or exact name). Clients that already have a page from it are skipped. Pages start as drafts; publishing stays a human action in SIGNL.

POST /api/v1/tools/push_event_template · scope write:agency · organisation-wide key only

  • template_id string, required
  • workspaces array of string, required. Clients to push to.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

detach_event_template_page

Unlink a booking page from its template

Stop a booking page following its template. It keeps its current values and becomes fully editable by the client.

POST /api/v1/tools/detach_event_template_page · scope write:agency · organisation-wide key only

  • page_id string, required. The booking page id.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

delete_event_template

Delete an event template

Delete a template. Pages already made from it stay as they are, with their current values, and become fully editable.

POST /api/v1/tools/delete_event_template · scope write:agency · organisation-wide key only

  • template_id string, required

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

set_client_setup_brief

Set a client’s setup brief

Shape the AI setup chat a client sees at their first login (replaces the brief; send all of it). `enabled: false` turns the chat off for that client. `notes` is private to the agency (server-only, never shown to the client) but the setup guide reads it and may act on it, so write nothing you would regret the client hearing paraphrased. `prefill` answers questions the agency already knows, in the setup profile’s own values; these ARE shown to the client, because the chat confirms each in one line instead of asking: business_model (one_to_one, group, course, agency, community, other), offers ([{ name, price_band: under_1k | 1k_3k | 3k_10k | 10k_plus, delivery }]), sales_motion (application_call, direct_booking, webinar, vsl, dm_setting, checkout, referrals), team_shape (solo, with_setter, setters_closers, sales_team), stack ([{ category, provider }]), alert_channel, alert_events, automations_before, notes. `allowed` names the kinds the chat may propose (pipeline, form, event, automation, integration; any left out stay allowed). `include_event_template_ids` puts up to 20 of the agency’s event templates on the client’s plan as draft booking pages. Refused once the client’s setup has been planned, built or skipped. A client with no setup yet gets one, opened at their next login.

POST /api/v1/tools/set_client_setup_brief · scope write:agency · organisation-wide key only

  • workspace string, required. The client: slug, id or exact name.
  • enabled boolean, required. False turns the setup chat off for this client.
  • notes string, optional
  • prefill object, optional. Setup profile answers the agency already knows (see the description for the keys and values).
  • allowed object, optional
  • include_event_template_ids array of string, optional. Event template ids (list_event_templates).

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

invite_client_member

Invite someone to one client’s workspace

Email an invitation to join ONE client’s workspace as a member. Always the member role, pinned to that client: inviting an admin, someone with the whole organisation or a custom role is done in SIGNL. Emails a real person, so the key needs write:sensitive as well as write:agency. Resending to a pending address replaces its earlier link.

POST /api/v1/tools/invite_client_member · scope write:agency and write:sensitive · organisation-wide key only

  • workspace string, required. The client they will work in: slug, id or exact name.
  • email string, required
  • name string, optional. Who they are; used in confirmations.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

Agency tools: write:finance

2

generate_statement_drafts

Generate the month’s statement drafts

Compute what each client owes the agency for a month from its packages and collected cash, and create or refresh the DRAFT statements. Drafts are working copies: nothing is issued to a client. Issuing, voiding and recording payment stay in SIGNL. Returns how many drafts were created, refreshed and skipped (already issued).

POST /api/v1/tools/generate_statement_drafts · scope write:finance · organisation-wide key only

  • period_start string, required. The first day of the month, YYYY-MM-DD.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

add_statement_adjustment

Add an adjustment to a draft statement

Add a manual line to a DRAFT statement: a positive amount adds to what the client owes, a negative one is a credit. Amount is integer pence of the statement’s currency. Refused once the statement is issued: put it on next month’s draft instead.

POST /api/v1/tools/add_statement_adjustment · scope write:finance · organisation-wide key only

  • statement_id string, required. The draft statement id (list_statements).
  • label string, required. What the adjustment is for; shown on the statement.
  • amount_pence integer, required. Non-zero. Negative for a credit.

Responds 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429

Also in the contract

The other endpoints in the OpenAPI contract, beyond the tools.

POST /api/ingest/server

ingest:write

Ingest a server-side event

POST /api/webhooks/inbound

ingest:write

Send a workflow event

POST /api/mcp

read

Use the SIGNL MCP server

GET /api/builder/forms

read

List forms, or read one in full with ?id=

POST /api/builder/forms

write:builder

Create a draft form

PATCH /api/builder/forms

write:builder

Edit a draft form

GET /api/builder/booking-pages

read

List booking pages, or read one in full with ?id=

POST /api/builder/booking-pages

write:builder

Create a draft booking page

PATCH /api/builder/booking-pages

write:builder

Edit a draft booking page

POST /api/builder/forms/import

write:builder

Import a Typeform from its public link, as a draft

GET /api/keys/me

Keys

Describe the key you are holding

This page is generated from the same list the product runs on, so it is never out of date. Something missing or unclear? Get help.