Stratify
Engineering

Quickstart

docs/api/quickstart.md

Source updated 03. Aug. 2026

Stratify B2B-API — Quick Start (Sandbox, v2.1 pre-license)

The Stratify B2B-API lets neobroker partners consume Stratify Signals — the seven curated strategy mandates — via REST + webhook fan-out. Partners run execution and end-user identity; Stratify owns the signal authorship + audit trail.

This guide walks a partner from "I have an API key" to "I received a signed signal.published webhook" in ~10 minutes.

Phase A note. Pre-license, Stratify Signals is a research publication. Endpoints exist (signals, audit), but the suitability + mirror-order surface from PRD v2.0 is not in this release. They re-enter when the FMA Liechtenstein VVG-license is granted.

1. Prerequisites

  • A sandbox API key from Stratify in the form st_<prefix>_<secret>. Stratify

ops issues these per-partner after KYB completes.

  • A publicly reachable HTTPS endpoint to receive signal webhooks.
Base URL. Live API is https://app.stratifyinvest.com/api/v1 (Hetzner, behind Cloudflare Access). *.stratifyinvest.com is the future canonical host — not live yet. Examples below use the live base.

2. Authentication

All endpoints expect:

Authorization: Bearer st_<prefix>_<secret>

Key scopes:

  • signals:read — list mandates, fetch signals, subscribe a webhook
  • audit:read — export the partner's chain-verified audit slice

Rate limits: 60 req/min/key (audit endpoint: 30/min). See docs/internal/b2b-rate-limits.md.

3. List the seven mandates

curl https://app.stratifyinvest.com/api/v1/mandates \
  -H "Authorization: Bearer $STK"
[
  {
    "id": "pelosi-tracker-plus",
    "number": 1,
    "name": "Pelosi Tracker",
    "thesis": "Event-driven mirror of disclosed Pelosi family trades from US House PTR filings.",
    "demoPublisher": "Capitol Trades Demo",
    "universe": "US equities from STOCK Act PTR disclosures (45-day lag)",
    "rebalance": "on_event"
  }
]

4. Fetch recent signals for a mandate

curl "https://app.stratifyinvest.com/api/v1/mandates/pelosi-tracker-plus/signals?limit=20" \
  -H "Authorization: Bearer $STK"

Each signal carries id, action, publishedAt, effectiveAt, title, body, legs, disclaimer, pilotRef, version.

5. Subscribe a webhook URL

curl -X POST https://app.stratifyinvest.com/api/v1/subscriptions \
  -H "Authorization: Bearer $STK" \
  -H "content-type: application/json" \
  -d '{
    "mandateId": "pelosi-tracker-plus",
    "webhookUrl": "https://your.app/stratify/signals"
  }'

201 on success. Subsequent signal publishes fan out to your URL.

6. Verify outbound webhooks (HMAC-SHA256)

POST /your/url
Content-Type: application/json
X-Stratify-Event: signal.published
X-Stratify-Signature: <hex>

Compute hex = HMAC_SHA256(partner_webhook_secret, raw_body) and reject anything that doesn't match. Stratify retries up to 8 times with growing back-off, then sets the delivery to failed in signal_deliveries.

Verifier script: scripts/verify-partner-webhook.ts (see docs/runbooks/production-env.md).

Webhook envelope version 2

{
  "version": 2,
  "type": "signal.published",
  "signal": {
    "id": "uuid",
    "mandateId": "pelosi-tracker-plus",
    "mandateNumber": 1,
    "action": "rebalance",
    "title": "…",
    "body": "…",
    "publishedAt": "2026-05-19T08:00:00.000Z",
    "effectiveAt": "2026-05-19T08:00:00.000Z",
    "legs": [{ "symbol": "VWCE", "weight": 0.4 }],
    "disclaimer": "Research publication, no investment advice.",
    "pilotRef": "demo",
    "version": 1
  },
  "orderIntents": [
    {
      "symbol": "VWCE",
      "side": "buy",
      "targetWeight": 0.4,
      "effectiveAt": "2026-05-19T08:00:00.000Z",
      "idempotencyKey": "uuid:VWCE"
    }
  ]
}

6b. Fetch order intents (REST)

curl "https://app.stratifyinvest.com/api/v1/mandates/pelosi-tracker-plus/signals/$SIGNAL_ID/order-intents" \
  -H "Authorization: Bearer $STK"

Mapping guide: docs/api/partner-order-mapping.md.

7. Audit-log export

curl "https://app.stratifyinvest.com/api/v1/audit-log/$PARTNER_ID?from=2026-05-01T00:00:00Z" \
  -H "Authorization: Bearer $STK"

Returns:

{
  "partnerId": "uuid",
  "from": "2026-05-01T00:00:00Z",
  "to": "2026-05-19T00:00:00Z",
  "chainVerified": true,
  "rows": [
    {
      "id": 42,
      "occurredAt": "…",
      "eventType": "partner.subscription.upserted",
      "hash": "…",
      "prevHash": "…",
      "payload": {}
    }
  ]
}

chainVerified is the result of verifyChain over the full table, not a slice — re-run partner-side too with the bare hashes to confirm.

8. Common errors

HTTPerrormeaning
400invalid_bodyzod validation failed
401missing_bearerheader absent or malformed
401invalid_keyrevoked, unknown prefix, or hash mismatch
403insufficient_scopekey valid, scope missing for route
403partner_mismatchaudit export for a partner that isn't yours
404unknown_mandatemandateId not one of the seven
429rate_limitedper-partner window exceeded; honour retry-after

9. Reference

  • OpenAPI 3.1: openapi/stratify-api.yaml (v0.2.0)
  • Order mapping: docs/api/partner-order-mapping.md
  • Phase C (parked): docs/api/phase-c-endpoints.md
  • Audit format: docs/compliance/audit-trail-export-format.md
  • Rate limits: docs/internal/b2b-rate-limits.md
  • Production env: docs/runbooks/production-env.md