DocsIntegration Guide

Integration Guide

Four ways to send user signals to Specter. Pick the one that fits your stack.

Compare Methods

MethodBest ForSetupCode
Script TagWeb apps, landing pages30 secondsNone
WebhookZapier, Make.com, n8n2 minutesNone
SDKJS/TS apps5 minutesMinimal
REST APIAny language, backends5 minutesMinimal

Script Tag

No code

The fastest way to integrate. Add a single line to your HTML and Specter automatically captures page views, JS errors, unhandled promise rejections, form submissions, and rage clicks.

Add to your HTML <head> or before </body>html
<script
  src="https://specter.draftlabs.org/s.js"
  data-api-key="YOUR_API_KEY"
  async
></script>

What gets tracked automatically

page_view

Every page load and SPA navigation

js_error

Uncaught exceptions and promise rejections

rage_click

3+ rapid clicks on same element

form_submit

Any HTML form submission

Custom event tracking

Add data-specter attributes to any HTML element to track custom click events:

Custom click trackinghtml
<!-- Tracks a "cta_click" signal when clicked -->
<button data-specter="cta_click">Get Started</button>

<!-- Tracks a "pricing_viewed" signal when clicked -->
<a href="/pricing" data-specter="pricing_viewed">View Pricing</a>

Disabling page view tracking

On high-traffic sites, page views can consume your signal quota quickly. Disable them while keeping all other auto-tracking:

html
<script
  src="https://specter.draftlabs.org/s.js"
  data-api-key="YOUR_API_KEY"
  data-track-pageviews="false"
  async
></script>
SPA support: The script patches history.pushState and history.replaceState to detect route changes in React, Vue, Angular, and other SPA frameworks.

Webhook / Zapier

No code

The ingest endpoint accepts flexible field names from Zapier, Make.com, n8n, or any HTTP client. Pass your API key as a query parameter.

Endpoint

POST https://specter.draftlabs.org/api/ingest?key=YOUR_API_KEY

Accepted field names

The ingest endpoint auto-detects field names from common automation tools:

PurposeAccepted Field Names
Signal typetype, event, event_type, event_name
Payload datapayload, data, properties, metadata
Context routingcontext_id (optional UUID)

Example: Zapier webhook

Zapier sends this JSON bodyjson
{
  "event": "form_submitted",
  "data": {
    "form_name": "contact",
    "page": "/pricing"
  }
}

Example: cURL

Send via cURLbash
curl -X POST "https://specter.draftlabs.org/api/ingest?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "purchase_completed", "payload": {"amount": 49.99}}'

SDK

The JavaScript/TypeScript SDK gives you full control over what gets tracked. Use it in any browser or Node.js environment.

Installation

Install the SDKbash
npm install @specterorg/sdk

Basic usage

Initialize and track eventstypescript
import { Specter } from "@specterorg/sdk";

const specter = new Specter({
  apiKey: "YOUR_API_KEY",
  // Optional: specify a context for all signals
  // contextId: "uuid-of-your-context",
});

// Track a positive signal
specter.track("swap_completed", {
  token_in: "ETH",
  token_out: "USDC",
  amount: 1.5,
  slippage: 0.3,
});

// Track a negative signal
specter.track("swap_failed", {
  error: "insufficient_balance",
  token_in: "ETH",
});

// Track user feedback
specter.track("thumbs_up", {
  feature: "new-chart-view",
});

Auto-tracking (browser)

For browser environments, use autoTrack to automatically capture page views, errors, rage clicks, and form submissions — just like the script tag, but with SDK control:

Auto-tracking modetypescript
import { autoTrack } from "@specterorg/sdk/auto-track";

const specter = autoTrack({
  apiKey: "YOUR_API_KEY",
  trackPageViews: true, // set to false to save quota
});

// You can still track custom events alongside auto-tracking
specter.track("feature_used", { feature: "dark-mode" });

Signal batching

The SDK automatically batches signals and flushes them:

Every 5 seconds (or when the batch reaches 10 signals)

When the page becomes hidden (tab switch, page close)

When specter.flush() is called manually


REST API

Send signals directly via HTTP from any language or platform. Authenticate with your API key in the x-api-key header.

Endpoint

POST https://specter.draftlabs.org/api/signals

Single signal

Send one signalbash
curl -X POST https://specter.draftlabs.org/api/signals \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "type": "checkout_completed",
    "payload": {
      "order_id": "ord_123",
      "total": 89.99
    }
  }'

Batch signals

Send multiple signals in a single request by passing an array:

Send multiple signalsbash
curl -X POST https://specter.draftlabs.org/api/signals \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '[
    {"type": "page_view", "payload": {"url": "/dashboard"}},
    {"type": "feature_used", "payload": {"feature": "export"}},
    {"type": "thumbs_down", "payload": {"reason": "slow loading"}}
  ]'

Response

Success responsejson
{
  "received": 3
}
With unrecognized types warningjson
{
  "received": 3,
  "warnings": [
    "Unrecognized signal types: feature_used. These signals are stored but won't affect polarity scoring until registered in a context."
  ]
}
Context routing: If your product has exactly one context, signals are automatically routed to it. With multiple contexts, include "context_id": "uuid" in each signal to route it to the right context.

CORS Support

Both /api/signals and /api/ingest support cross-origin requests with Access-Control-Allow-Origin: *. You can send signals directly from the browser without a proxy.