Overview

Company signals that return structured, evidence-backed answers — prebuilt signals for the most common questions, custom signals for your own.

Signals answer research questions about a company. Each signal researches the live web, grounds its answer in public evidence (with source citations where the signal provides them), and returns JSON you can score, route, or sync into a CRM without post-processing.

Five prebuilt signals cover the questions teams ask most often: pass a company domain and get a structured answer with a documented schema, so every call for the same signal comes back in the same well-defined shape. When your question isn't one of the five, a custom signal lets you ask it in your own words with your own answer shape.

Available signals

SignalKeyAnswers
FundingfundingMost recent funding round and public/IPO status
M&AmnaWhether the company was acquired or made acquisitions
TechtechWhich ERP/CRM it uses, or whether it uses a specific technology
Open Jobsopen-jobsWhat the company is currently hiring for
FirmographicsfirmographicsBase company profile plus a refined Saber category
CustomYour own research question, in the answer shape you define

Every prebuilt signal is company-scoped and returns a json_schema answer whose payload conforms to that signal's documented answer schema.

Sync vs async

Each prebuilt signal is available in two shapes:

  • SyncPOST /v1/signals/sync/{key} blocks until the signal completes and returns the result in the same response. Use this for interactive and agent workflows where a caller is waiting for the answer. This is the recommended default. Signals typically take one to two minutes. If one doesn't finish before the timeout — 870s by default, lowerable per request with the X-Sbr-Timeout-Sec header — you get a 200 whose body is the still-processing signal; check the body's status (not the HTTP code) and poll GET /v1/companies/signals/{signalId} for the result.
  • AsyncPOST /v1/signals/{key} returns a processing signal (or an already-completed one if the same request ran recently). Poll GET /v1/companies/signals/{signalId} for the result, or include a webhookUrl to have the completed signal delivered to your endpoint. Use this for event-driven and high-volume workflows.

The webhookUrl field is intended for the async endpoints. If you supply it on a sync endpoint it is still honored — the completed signal is delivered to the webhook in addition to the blocking response — so omit it on sync unless you want both.

Custom signals follow the same sync/async pattern on their own endpoints.

Request shape

Every prebuilt signal takes the same minimal body — you provide the company domain and nothing else:

curl -X POST https://api.saber.app/v1/signals/sync/funding \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "stripe.com"
  }'

The Tech signal is the one exception: it also takes a single typed parameter (category or technology) that selects what to look for.

Two optional fields apply to every prebuilt signal:

  • webhookUrl — where to deliver the completed result. See Sync vs async for how it behaves on each endpoint shape.
  • forceRefresh — set to true to force a fresh run. By default, an identical request (same domain and parameters) returns the existing result instead of re-running.

Response shape

A completed prebuilt signal returns a signal object whose answer.type is json_schema and whose answer.jsonSchema holds the structured payload. A confidence score accompanies the answer, and sources are included where the signal provides them. Prebuilt-signal responses echo the signal key as namedSignal; unlike custom signals, they carry no question field:

{
  "id": "e45c1dc4-d422-4b51-956b-cb6d3ddaf250",
  "signalType": "COMPANY",
  "namedSignal": "funding",
  "status": "completed",
  "domain": "stripe.com",
  "answerType": "json_schema",
  "answer": {
    "type": "json_schema",
    "jsonSchema": {
      "hasFundingEvent": true,
      "isPublic": false,
      "latestRound": "Series I",
      "latestEvents": [
        {
          "eventType": "funding_round",
          "round": "Series I",
          "amount": 6500000000,
          "currency": "USD",
          "investors": ["Andreessen Horowitz", "Sequoia Capital", "General Catalyst"],
          "announcedAt": "2023-03-15",
          "sourceUrls": ["https://stripe.com/newsroom/news/series-i"]
        }
      ]
    }
  },
  "confidence": 0.93,
  "sources": [
    { "url": "https://stripe.com/newsroom/news/series-i", "title": "Stripe raises Series I" }
  ]
}

The exact shape of answer.jsonSchema is documented per signal.

A signal that ends in a terminal failed state is still returned with a success status code and status: "failed" in the body, so check the status field rather than relying on the HTTP code alone.

Errors

Requests authenticate with an API key, so a missing or invalid key returns 401. A malformed body returns 400; a well-formed request that fails validation — an unrecognised domain, or (for tech) supplying neither or both of category/technology — returns 422. Exceeding your rate limit returns 429. Each operation's full response list is in the API reference.

Pricing

Most prebuilt signals cost 2 credits per run; each signal's page lists its cost. Reading results (GET /v1/companies/signals/{signalId}) is free, and cached responses do not consume additional credits.

Ask your own question

The prebuilt signals cover the most common questions, not every question. When your qualification criteria are specific to your niche — a particular certification, a hiring pattern, a product capability — a custom signal lets you ask exactly that, with a bespoke output schema to match.

On this page