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 ishttps://app.stratifyinvest.com/api/v1(Hetzner, behind Cloudflare Access).*.stratifyinvest.comis 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 webhookaudit: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
| HTTP | error | meaning |
|---|---|---|
| 400 | invalid_body | zod validation failed |
| 401 | missing_bearer | header absent or malformed |
| 401 | invalid_key | revoked, unknown prefix, or hash mismatch |
| 403 | insufficient_scope | key valid, scope missing for route |
| 403 | partner_mismatch | audit export for a partner that isn't yours |
| 404 | unknown_mandate | mandateId not one of the seven |
| 429 | rate_limited | per-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