Closed beta — partner integration test (unaided, v2.1)
Status (2026-05-22): v2.0 runbook (mirror orders + suitability delegation) is parked — seedocs/api/phase-c-endpoints.md. Phase A: usedocs/api/quickstart.md: list mandates → fetch signals →GET …/order-intents→ subscribe webhook → verify webhook v2 (HMAC) → audit export withchainVerified: true. Mapping:docs/api/partner-order-mapping.md.
Goal: one neobroker engineer completes this runbook without Stratify support and produces artifacts proving read/write access, suitability delegation, and audit visibility.
Replace placeholders:
| Placeholder | Example |
|---|---|
BASE | https://your-preview.vercel.app or local http://localhost:3000 |
STK | Raw key from tmp/closed-beta/manifest.json (stk_sbx_…) |
PILOT | pilotId from the same manifest |
0. Preconditions
- Stratify ops ran
pnpm seed:closed-betaagainst the sandbox database and sent you the manifest (prefix-only over Slack is OK; full key via vault). - Your egress IP is allowed if Stratify enabled IP allowlisting (default off in sandbox).
STRATIFY_SANDBOX_MODE=1on the deployment under test (paused pilots visible, IBKR mocked).
1. Smoke — authentication
curl -sS "$BASE/api/v1/pilots" \
-H "Authorization: Bearer $STK" \
-H "Accept: application/json" | jq .Expect 200 and at least one pilot with status: "live".
Artifact: save response JSON as artifacts/01-pilots.json.
2. Strategy contract
curl -sS "$BASE/api/v1/pilots/$PILOT/strategy" \
-H "Authorization: Bearer $STK" | jq .Confirm definition matches your UI expectations (asset universe, risk bands).
Artifact: artifacts/02-strategy.json.
3. Mirror order — suitability path
Pick a test user email you control (no production PII).
RUN_ID="$(date +%s)-$RANDOM"
EMAIL="[email protected]"
curl -sS -X POST "$BASE/api/v1/mirror-orders" \
-H "Authorization: Bearer $STK" \
-H "Content-Type: application/json" \
-d @- <<EOF | jq .
{
"partnerUserId": "partner_runbook_$RUN_ID",
"pilotId": "$PILOT",
"side": "BUY",
"instrumentSymbol": "VWCE",
"notionalEur": 100,
"idempotencyKey": "runbook-$RUN_ID",
"userProfile": {
"email": "$EMAIL",
"suitabilityAnswers": {
"k.derivatives_familiarity": "basic",
"k.copy_trading_understanding": true,
"f.annual_net_income_eur": 80000,
"f.liquid_assets_eur": 120000,
"f.intended_investment_eur": 10000,
"f.can_afford_total_loss": true,
"o.horizon_years": 10,
"o.risk_tolerance": "medium"
}
}
}
EOF201/200: order accepted — notepropagatedOrderId/ leg ids if returned.409 suitability_failed: answers failed MiFID-II gate — expected if you sent borderline data; adjust answers per Stratify suitability spec (do not invent wording for end users).
Artifact: artifacts/03-mirror-order-response.json.
Re-send the same idempotencyKey once — response must be identical (idempotency proof).
4. Inbound execution webhook (optional sandbox hook)
If Stratify gave you a signing secret for inbound POST /api/v1/webhooks/execution-status, replay the OpenAPI example payload with valid HMAC. Otherwise skip — outbound delivery is covered next.
5. Outbound webhook — signature verification
Configure webhookUrl on the partner record to a request inspector (e.g. webhook.site) or your staging ingress.
Trigger an execution status update (mirror order above + sandbox propagation). Stratify POSTs JSON with header:
X-Stratify-Signature: sha256=<hex>
Verify:
expected = HMAC_SHA256(webhookSecret, rawBody)Constant-time compare with sha256= prefix.
Artifact: one captured raw request + your verifier script output.
6. Audit read scope
After a successful mirror order, fetch audit entries for the same partnerUserId you sent in step 3 (the path param is your id, not an internal UUID). Reuse the exact partnerUserId string from the JSON body in step 3 (same shell session as $RUN_ID, or copy-paste from artifacts/03).
curl -sS "$BASE/api/v1/audit-log/partner_runbook_$RUN_ID" \
-H "Authorization: Bearer $STK" | jq .If you used a different partnerUserId, substitute it literally. Expect entries for b2c_user, user_order_leg, and propagated_order subjects tied to that user.
Artifact: artifacts/06-audit-log.json.
7. Done criteria (partner self-check)
- [ ]
01–06artifacts attached to internal ticket - [ ] Idempotency re-play confirmed
- [ ] Webhook signature verified OR documented skip with reason
- [ ] No Stratify engineer contacted during steps 1–6
Escalation only for: HTTP 5xx >15 minutes, unexpected 401, or schema mismatch vs openapi/stratify-api.yaml.