Auditable decisions

A decision you can re-open in six months.

The hard part of shipping AI into finance is not producing an answer. It is being able to explain, later, exactly what a specific answer rested on. /v1/decision composes macro regime, portfolio risk, deterministic calculations, and evidence into one response — and hands back a claim ledger plus an immutable decision ID.

  • Claim-level provenance
  • Retrievable months later
  • 100,000 free Quan 3.4 L tokens
decision.sh
curl https://stockup.cc/v1/decision \
  -H "x-api-key: $STOCKUP_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "question": "Is this book too concentrated
      for a capital-preservation mandate?",
    "horizon": "months",
    "objective": "capital_preservation",
    "portfolio": {
      "cash": 25000,
      "holdings": [
        { "ticker": "NVDA", "shares": 300 },
        { "ticker": "AVGO", "shares": 80 }
      ]
    },
    "constraints": {
      "maxPositionPct": 0.20,
      "maxSectorPct": 0.35,
      "cashFloorPct": 0.10
    },
    "researchFallback": "auto"
  }'
Returns decisionId, claimLedger, portfolioRisk, regime, calculations, evidence.
Claim ledgerAssertions, listed separately
Coverage splitVerified vs inferred
Build fingerprintWhich engine produced it
Immutable recordFetch it back verbatim
The core idea

Prose cannot be audited. A ledger can.

When an LLM writes "the portfolio is over-concentrated in semiconductors given the current environment," that sentence bundles at least four separate claims: a sector classification, a concentration measurement, a threshold judgement, and a macro read. Each could be independently right or wrong, and none of them is inspectable.

A claim ledger unbundles them. Each assertion is a discrete entry carried with its supporting evidence, so your application can render them individually, cite the ones that came from primary sources, or refuse to display the ones with thin support.

This is what makes an AI finance feature defensible rather than merely impressive. When a user or a reviewer asks why your product said something, "here are the six claims it made and what each one rested on" is an answer. "The model said so" is not.

response envelope
{
  "decisionId": "dec_...",
  "status": "...",
  "releaseFingerprint": "...",
  "quantitativeCoreHash": "...",
  "portfolioRisk":      { ... },
  "regime":             { ... },
  "coverageBreakdown":  { ... },
  "claimLedger":        [ ... ],
  "calculations":       [ ... ],
  "evidence":           [ ... ],
  "research":           { ... },
  "audit":              { ... }
}
Every field is inspectable. Nothing is collapsed into a single opaque string.
What it composes

One call, four layers underneath.

LayerWhat it contributesAlso available alone
Macro regimeWhich of seven states the environment is in, so the same exposure is judged against the right backdrop./v1/regime
Portfolio riskComputed VaR, CVaR, drawdown, Sharpe and Sortino, plus which of your constraints are breached./v1/risk
CalculationsDeterministic arithmetic — computed, not generated, and returned in a calculations array you can re-check./v1/valuation
EvidenceThe material each claim leans on, with a coverage breakdown separating verified primary sources from inference./v1/signal

Use /v1/decision when you want the composed answer, and the individual endpoints when you want one layer cheaply. The request payload is deliberately identical across /v1/decision, /v1/risk and /v1/signal, so moving between depths is a URL change rather than a rewrite.

Replay

The decision ID is the whole point.

Store the decisionId next to whatever you showed the user. When the question comes back — from the user, from a colleague, from someone reviewing your product — pass it to /v1/audit and you get the owner-scoped immutable record.

Note what this avoids. The naive approach is to re-run the analysis, but a re-run uses today's data and possibly a newer engine build, so it may legitimately disagree with what you displayed. That is indistinguishable from a bug, and you cannot tell which happened. The releaseFingerprint and quantitativeCoreHash in every response exist so you can prove whether two results differ because inputs changed or because the engine did.

Records are owner-scoped: a key reads only decisions it created.

replay.sh
# Six months later, same answer, verbatim.
curl https://stockup.cc/v1/audit \
  -H "x-api-key: $STOCKUP_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "decisionId": "dec_..." }'
Not a re-run. The original record.
Speed vs thoroughness

Choose speed or thoroughness explicitly.

"auto" — when primary coverage is insufficient, the system pursues deeper research before answering. Slower, better supported. The right default for a detail view a user is waiting on deliberately.
"off" — answer from what is already verified and report the gap. Faster, and explicitly thinner. The right choice for a list row or a background job where a low-coverage response is genuinely more useful than a slow one.
Either way, coverage is reported. The setting changes how hard the system works, never whether it tells you what it found. There is no configuration in which a gap gets filled with a plausible value.
Decision FAQ

Before you build on it.

Is this a robo-adviser I can put in front of users?

No. It returns research output, not personalized advice, and StockUp is not a registered investment adviser. If you are building something user-facing that recommends actions, that is a regulatory question for your counsel, not a technical one. See the risk disclaimer and terms.

How long does a decision take?

Longer than a single-layer call, especially with researchFallback: "auto", because it composes several analyses. Treat it as a considered request rather than something to run during a page render.

Do I have to send a portfolio?

No. question and ticker alone work for a single-name analysis. Supplying portfolio and constraints is what unlocks concentration and constraint-breach reasoning.

What is quantitativeCoreHash for?

It identifies the quantitative core that produced the numbers. Two decisions with the same hash were computed by the same logic, which lets you distinguish an engine change from an input change when results move.

Can I use this inside an AI agent?

Yes, and the claim ledger is particularly useful there — an agent can act on individual verified claims rather than parsing a paragraph. See the MCP server for tool-shaped access.

Auditable by construction

Build the AI finance feature you can defend.

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

Create a free API key →