Composite signals

A signal that admits what it rests on.

Any API can return a number between −1 and 1 and call it a signal. The problem is that a well-supported reading and a guess look identical on the wire. /v1/signal returns the composite and its coverage, so your product can tell the difference.

  • Coverage reported per response
  • Claim ledger included
  • 100,000 free Quan 3.4 L tokens
composite-signal.sh
curl https://stockup.cc/v1/signal \
  -H "x-api-key: $STOCKUP_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "ticker": "NVDA",
    "horizon": "months",
    "objective": "balanced",
    "question": "What is the composite read
      and what is it weakest on?"
  }'
Same request shape as /v1/risk and /v1/decision.
CoverageVerified vs inferred, split out
Claim ledgerEach assertion listed
Horizon-awareDays through years
ReplayableRetrievable decision record
The actual problem with signals

Confidence and support are not the same thing.

Consider two responses. Both return a moderately positive composite for a mid-cap name. In the first, the reading rests on verified pricing, a recent filing, and complete fundamentals. In the second, half the inputs were unavailable and the composite is largely inference.

A conventional signal API hands you the same shaped payload for both. You build a UI that renders a confident arrow, and your users cannot distinguish a well-supported read from a shrug. That is not a modelling failure — it is a payload design failure.

This endpoint separates them. coverageBreakdown and primarySourceCoverage tell you how much of the answer stood on verified primary data. claimLedger enumerates the individual assertions the composite is made of. Thin support is visible in the response, which means it can be visible in your interface.

gate-on-coverage.js
const res = await fetch("https://stockup.cc/v1/signal", {
  method: "POST",
  headers: {
    "x-api-key": process.env.STOCKUP_API_KEY,
    "content-type": "application/json"
  },
  body: JSON.stringify({
    ticker: "NVDA",
    horizon: "months",
    objective: "balanced"
  })
});

const signal = await res.json();

// Do not render a decisive UI on thin support.
if (signal.primarySourceCoverage < 0.6) {
  return renderLowConfidence(signal);
}

return renderSignal(signal);
One branch, and your product stops overstating its own certainty.
Request fields

Shared shape across the decision endpoints.

FieldValuesEffect
tickerstringThe security to read.
questionstringSteers the written interpretation alongside the composite.
horizondays · weeks · months · yearsThe window the signal is framed against. Materially changes the read.
objectivecapital_preservation · balanced · growthShapes what counts as favourable.
portfolioobjectOptional. Supply cash and holdings to read the signal in the context of an existing book.
constraintsobjectOptional. Same five limits as the risk endpoint.
researchFallbackauto · offWhether to fall back to deeper research when primary coverage is insufficient.

Because /v1/signal, /v1/risk and /v1/decision accept the same payload, you can build one request object in your codebase and route it to whichever depth the surface needs — a compact signal on a list row, full decision intelligence on a detail view.

Where it fits

Three integration shapes.

Watchlist rows

One signal per row, cached

Read the composite for each name on a watchlist and cache per horizon. Gate the decisive styling on coverage so a sparse name renders as sparse.

Position sizing

Signal, then constraints

Pull the signal, then post the same payload to /v1/risk with maxPositionPct set. You get the read and the limit check without reshaping the request.

Agent tool

A tool that reports its own limits

Expose it over MCP and an agent can decide to seek more evidence when coverage is low, instead of asserting a confident view built on gaps.

Signal FAQ

What this is and is not.

Is the signal a buy or sell rating?

No, and it should not be presented as one. It is a composite research reading for a security. It knows nothing about a user's horizon, tax position, or risk tolerance, and StockUp is not a registered investment adviser. See the risk disclaimer and how these models are built and reviewed.

What happens when coverage is poor?

Coverage is reported low rather than the gaps being filled. With researchFallback: "auto" the system may pursue deeper research first; set it to off when you would rather have a fast, explicitly thin answer than a slower thorough one.

Can I get a signal for any ticker?

Coverage varies by security. Rather than failing opaquely, the response tells you what it managed to verify — check primarySourceCoverage before treating a reading as solid.

How is this different from asking a Quan model about a stock?

/v1/signal returns a structured composite with provenance fields you can branch on in code. A model call returns prose. For UI logic you want the structured endpoint; for explanation you want the model. Products commonly use both.

Can I audit a signal I served last quarter?

Yes. Keep the decisionId and pass it to /v1/audit for the owner-scoped immutable record, including the releaseFingerprint of the build that produced it.

Signals with their receipts

Stop shipping confidence you cannot justify.

Start with 100,000 free Quan 3.4 L tokens. No card required.

Create a free API key →