{"version":"0.1.0","spec_url":"https://app.signal.geysera.com/signal-api/v1/openapi.json","auth":{"scheme":"Bearer","header":"Authorization","format":"sk_sig_...","obtain_at":"Signal dashboard -> Exports & API","note":"A key is scoped to one workspace. Results respect that workspace's plan caps, exactly as the dashboard does. Scopes are fixed when the key is created: to change reach, create a new key and revoke the old one.","scopes":{"read":"The /signal-api/v1 REST endpoints: accounts, visitors, attribution, recommendations.","copilot":"Ask questions in natural language at /signal/copilot/ask. READ-ONLY: a key reaches the copilot's read tools and never the ones that change the workspace, whatever it is asked."}},"rate_limit":{"requests":300,"window_seconds":60,"scope":"per key","exceeded_status":429},"conventions":{"pagination":{"params":"page (1-based), page_size (default 50, maximum 200)","response":"an array named for the resource (`accounts`, `visitors`) plus total, page, page_size. There is no `items` key.","note":"total is capped at what your plan may resolve, never the raw row count","out_of_range":"page_size above 200 is rejected with 422 rather than silently clamped, so a script cannot believe it read more than it did"},"error_shape":{"error_code":"stable machine-readable code; one of CONFLICT, FORBIDDEN, INTERNAL, NOT_FOUND, RATE_LIMITED, UNAUTHORIZED, VALIDATION_ERROR","message":"human-readable description","correlation_id":"echo of X-Correlation-ID; quote it in support requests","details":"optional structured context"},"request_headers":{"Authorization":"Bearer sk_sig_... (required)","X-Correlation-ID":"optional; generated when absent, echoed on every response"},"response_headers":{"X-Correlation-ID":"the id for this request, generated when you do not send one","Retry-After":"seconds to wait, on 429 only. The real remaining window, not a fixed number — arrive late in a window and it is small"},"caps":"Accounts beyond your plan's monthly resolution cap are not returned. The response reports how many exist so the omission is never silent.","key_limit":"A workspace may hold 10 active keys at once. Creating one beyond that returns 409; revoke an unused key first."},"router_prefixes":["/capabilities","/health","/signal","/signal-api","/version"],"copilot_tools":[{"name":"aov_decomposition","summary":"Splits AOV into average unit price x average units per order, before vs after a boundary date."},{"name":"attribution_overview","summary":"Which channels, sources and campaigns the attributed sessions came from, and what they were worth — the same cached rollup the Attribution page renders."},{"name":"causal_impact","summary":"Did a dated change actually CAUSE a metric to move? Fits a Bayesian interrupted time series: models the pre-change trend, predicts what would have happened without the change, and reports the difference with a credible interval."},{"name":"customer_counts","summary":"How many distinct people bought, how often they came back, and how many were new."},{"name":"data_coverage","summary":"What this workspace can and cannot answer for a window: order count, pixel volume, how many orders link to a pixel session, and which days the order sync missed."},{"name":"dry_run_sync_rule","summary":"Show exactly which contacts a rule WOULD push, without pushing anything."},{"name":"enrichment_config","summary":"Who this workspace enriches, under what conditions, and what it is spending."},{"name":"esp_connection","summary":"Which email platform this workspace is connected to, if any, and whether the connection is verified."},{"name":"get_account","summary":"Everything known about ONE account by domain: firmographics, its visitors, orders and ESP contacts."},{"name":"get_conversation","summary":"Read back one past conversation — its questions, answers and the caveats each answer carried."},{"name":"identification_status","summary":"Is identification actually running right now, and when did it last resolve anyone? Use when a workspace says visitors stopped appearing — a quiet pipeline and quiet traffic look identical on the accounts page, and this is what tells them apart."},{"name":"intent_pages","summary":"The page rules this workspace uses to score buying intent, and what share of its real traffic they match."},{"name":"journey_paths","summary":"How visitors move BETWEEN pages — the page-to-page graph behind the Journey view, reading the same nightly rollup the page reads."},{"name":"list_alert_destinations","summary":"Slack destinations receiving this workspace's alerts, and whether each is active."},{"name":"list_api_keys","summary":"The workspace's API keys — id, name, prefix, last used."},{"name":"list_conversations","summary":"Your own past conversations in this workspace, most recently updated first, with each one's title, question count and when it was last touched."},{"name":"list_team","summary":"Who has access to this workspace: members with their roles, invitations still pending, and how many seats are left."},{"name":"list_webhooks","summary":"Registered webhook endpoints and whether each is enabled."},{"name":"membership_conversion_paths","summary":"Which OTHER products are in the basket when a given product is bought."},{"name":"open_recommendations","summary":"The workspace's open recommended actions, from both the journey and attribution surfaces."},{"name":"page_funnel","summary":"Per page: sessions that saw it, and how many added to cart, reached checkout and purchased in that same session."},{"name":"page_to_product_attribution","summary":"Which pages were seen in the same session as a purchase, optionally restricted to orders containing a given product."},{"name":"price_history","summary":"When a product's price actually changed."},{"name":"product_performance","summary":"Revenue, orders, units and quantity-weighted unit price per product."},{"name":"recall_facts","summary":"What this workspace has taught the assistant, and when."},{"name":"revenue_and_aov","summary":"Revenue, order count, AOV, discount and units per period (day/week/month)."},{"name":"search_accounts","summary":"The accounts board: search by name or domain, filter by classification and minimum intent, sort, paginate."},{"name":"search_visitors","summary":"Individual identified people, with the filters the Visitors page offers: text search, classification, minimum intent, whether they have ordered, whether they have been contacted, and which intent page they hit."},{"name":"subscription","summary":"This workspace's plan status, when it next renews, and whether it is set to cancel at the end of the period."},{"name":"sync_rules","summary":"The auto-sync rules that push identified accounts to the connected ESP: their filters, status and last run."},{"name":"visiting_accounts","summary":"Which organisations visited the site, ranked by intent score, with their visits, visitors and any orders."},{"name":"visitor_journey","summary":"The pages ONE visitor viewed, in order, with time on each."},{"name":"workspace_setup","summary":"Is this workspace actually working? Store connection, onboarding progress, pixel status, identification health and the current plan and usage, in one call."}],"actions":[{"method":"GET","path":"/","summary":"Root","tags":[],"required_scope":null},{"method":"GET","path":"/capabilities","summary":"Platform capability discovery","tags":["capabilities"],"required_scope":null},{"method":"GET","path":"/health","summary":"Health check","tags":[],"required_scope":null},{"method":"GET","path":"/health/liveness","summary":"Liveness check","tags":[],"required_scope":null},{"method":"GET","path":"/health/readiness","summary":"Readiness check","tags":[],"required_scope":null},{"method":"GET","path":"/signal-api/v1/accounts","summary":"List identified accounts (API-key auth, cap-respecting)","tags":["signal","public-api"],"required_scope":"read"},{"method":"GET","path":"/signal-api/v1/attribution","summary":"Attribution rollup for a window (API-key auth)","tags":["signal","public-api"],"required_scope":"read"},{"method":"GET","path":"/signal-api/v1/openapi.json","summary":"Signal public api spec","tags":[],"required_scope":null},{"method":"GET","path":"/signal-api/v1/recommendations","summary":"Open recommended actions (API-key auth)","tags":["signal","public-api"],"required_scope":"read"},{"method":"GET","path":"/signal-api/v1/visitors","summary":"List identified visitors (API-key auth, cap- and tier-respecting)","tags":["signal","public-api"],"required_scope":"read"},{"method":"POST","path":"/signal/copilot/ask","summary":"Ask a question about this workspace's commerce data","tags":["signal","copilot"],"required_scope":"copilot"},{"method":"POST","path":"/signal/copilot/stream","summary":"Ask a question, streamed per analysis step","tags":["signal","copilot"],"required_scope":"copilot"},{"method":"GET","path":"/signal/copilot/threads","summary":"List this workspace's conversations","tags":["signal","copilot"],"required_scope":"copilot"},{"method":"GET","path":"/signal/copilot/threads/{thread_id}","summary":"A conversation and its messages","tags":["signal","copilot"],"required_scope":"copilot"},{"method":"GET","path":"/version","summary":"Version","tags":[],"required_scope":null}],"supported_flow_types":["cart_abandonment","checkout_abandonment","browse_abandonment","winback"],"inferred_flow_types":["browse_abandonment","cart_abandonment","checkout_abandonment","nurture","post_purchase","welcome_series","winback"],"integration_platforms":{"ecommerce":["shopify","woocommerce","bigcommerce"],"esp":["klaviyo","sendgrid","mailchimp","hubspot"]}}