# Going Live

> Move from sandbox to a controlled production pilot using the documented environment capability matrix and pre-launch checks across security, reliability, correctness, and observability.

Production begins with a limited [Controlled Production Pilot](/partners/docs/controlled-production-pilot). MyStocks must approve the pilot policy, owners, limits, feature flags, and current reconciliation before production mutations are accepted.

Once your integration is tested, switch to the production endpoints. Operations listed as mirrored use
the same public schemas and business rules, but settlement timing, real-money behavior, governance
controls, and production-only operations differ as shown below.

| | Sandbox | Production |
| --- | --- | --- |
| Base URL | `https://mystocks.africa/api/sandbox/v1/partner` | `https://mystocks.africa/api/v1/partner` |
| API key prefix | `sk_sandbox_` | `pk_live_` |
| Order execution | Accelerated simulated execution; canonical terminal state `FILLED` | `PENDING` → `FILLED` / `REJECTED`; v1 may emit legacy `COMPLETED` as an alias for `FILLED` |
| Custody settlement | Virtual and accelerated | Separate from execution; tracked as `PENDING`, `SETTLED`, or `FAILED` |
| Stock prices | Same exchange-supplied, 15-minute-delayed feed; inspect `asOf` and `stale` | Exchange-supplied, 15-minute-delayed feed; API refresh target 900 seconds |
| Wallet funding | Auto $100k on register | Admin deposits real funds |
| Register/reset utilities | `POST /api/sandbox/v1/register` and `POST /api/sandbox/v1/reset` | Not available |

## Onboarding steps

<Steps>
<Step>Register at [mystocks.africa/partners/register](/partners/register) and submit your application.</Step>
<Step>MyStocks reviews your application within 1–2 business days.</Step>
<Step>Upon approval, you receive your `pk_live_` API key and access to the partner dashboard.</Step>
<Step>Swap the base URL and key prefix — no other code changes needed.</Step>
<Step>Submit trades via `POST /api/v1/partner/trade` → orders enter the live market fill flow.</Step>
<Step>Live market orders submitted during exchange hours target fill within 5 minutes. Monitor via `GET /orders/{orderId}` or the `order.filled` / `order.rejected` webhooks. Settlement cycles: `GET /market/settlement`.</Step>
</Steps>

## Pre-launch checklist

**Security**

- [ ] API key stored in environment variables — never committed to source control.
- [ ] Webhook endpoint validates the HMAC-SHA256 signature using `timingSafeEqual` before processing events.
- [ ] Sub-account IDs treated as internal identifiers — never exposed directly to end-users.

**Reliability**

- [ ] `Idempotency-Key` set on every authenticated POST/PATCH/PUT/DELETE request except the documented auth/portal exceptions.
- [ ] Exponential backoff implemented for `429` and `500` responses.
- [ ] Webhook endpoint returns `2xx` within 8 seconds; heavy processing deferred to a background queue.
- [ ] Webhook delivery failures reconciled from the deliveries endpoint or partner dashboard.

**Integration correctness**

- [ ] All sandbox scenarios passed: BUY, SELL, insufficient funds, KYC rejection.
- [ ] Order status polling (or webhook) handles WORKING, PENDING, PARTIALLY_FILLED, FILLED, REJECTED, CANCELLED, and EXPIRED; v1 `COMPLETED` is normalized to `FILLED`.
- [ ] FX rate recorded on each deposit and withdrawal for your own audit trail.
- [ ] Sub-account KYC tier verified before allowing trades above tier-1 limits.
- [ ] The UI handles `INSUFFICIENT_FUNDS` (400), `KYC_REQUIRED` (403), quote conflicts (409), `MARKET_CLOSED` (422), and `RATE_LIMITED` (429) by `error.code`.
- [ ] African equity quotes and charts are labelled “15-minute delayed,” never live or real-time, and display `asOf`.
- [ ] Every stock can fall back to an EOD line chart; candlesticks and volume are enabled only when the candle quality metadata supports them.

**Observability**

- [ ] Audit log (`GET /audit`) integrated into your compliance reporting.
- [ ] Usage analytics (`GET /usage`) monitored to stay within your rate-limit tier.
- [ ] Alert configured when `X-RateLimit-Remaining` drops below 20% of your tier ceiling.
