# Key Management

> Rotate and revoke MyStocks Partner API keys and manage scoped read-only data keys, including one-time credential responses and immediate suspension behavior.

Rotate, revoke, and manage scoped read-only data keys. Production revoke uses a Firebase ID token —
not the compromised key — while sandbox key-management calls use the sandbox key.

## Rotate a key

<MethodTag m="POST" /> `/api-keys/rotate`

Generate a new `pk_live_` key. The old key is suspended immediately. Webhooks, sub-accounts, wallet,
holdings, and audit history remain attached to the same stable partner identity; no records are copied
or migrated. A `key.rotated` audit event is logged.

```bash
curl -X POST "https://mystocks.africa/api/v1/partner/api-keys/rotate" \
  -H "Authorization: Bearer pk_live_<current_key>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: key-rotation-2026-08-10" \
  -d '{"confirm":true}'
```

```json
{
  "message": "API key rotated. Update your integration immediately.",
  "newApiKey": "pk_live_new_xxxxxxxxxxxxxxxx",
  "oldApiKey": "pk_live_old_••••••••",
  "note": "The old key is now suspended. This is the only time the new key is shown. All your data carries over automatically — no action needed."
}
```

<Callout type="warn">
  Update all services with the new key before discarding the response — the old key is suspended
  immediately and the new key is shown only once. Data keys (`pk_data_`) are unaffected by rotation.
</Callout>

## Revoke a key

<MethodTag m="POST" /> `/api-keys/revoke`

Permanently revoke a partner API key. **This action cannot be undone.** A new key must be issued by
MyStocks operations. This endpoint uses a **Firebase ID token** (`Authorization: Bearer <firebase-id-token>`),
not a partner key, so it remains callable even after a key compromise. A `key.revoked` audit event is logged.

```bash
curl -X POST "https://mystocks.africa/api/v1/partner/api-keys/revoke" \
  -H "Authorization: Bearer <firebase-id-token>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: revoke-compromised-key-2026-08-10" \
  -d '{"apiKey":"pk_live_compromised_xxxxxxxxx"}'
```

```json
{ "message": "API key revoked. All requests using this key will now be rejected.", "apiKey": "pk_live_comp••••••••" }
```

## Data key

<MethodTag m="POST" /> <MethodTag m="GET" /> <MethodTag m="DELETE" /> `/api-keys/data-key`

Create, fetch, or delete a read-only `pk_data_` key for market-data access (no trading, funds, or
PII). For production apps, proxy through your backend rather than embedding the key in client bundles.
Only one data key exists per partner at a time — creating a new one replaces the previous. `GET`
returns a masked version of the key (`maskedKey`); the full key is only shown on `POST`. See
[Authentication](/partners/docs/auth) for the allowed endpoint list.

<UITabs items={['Create', 'Read', 'Delete']}>
  <Tab>
    ```bash
    curl -X POST "https://mystocks.africa/api/v1/partner/api-keys/data-key" \
      -H "Authorization: Bearer pk_live_<key>" \
      -H "Idempotency-Key: create-data-key-2026-08-10"
    ```
  </Tab>
  <Tab>
    ```bash
    curl "https://mystocks.africa/api/v1/partner/api-keys/data-key" \
      -H "Authorization: Bearer pk_live_<key>"
    ```
  </Tab>
  <Tab>
    ```bash
    curl -X DELETE "https://mystocks.africa/api/v1/partner/api-keys/data-key" \
      -H "Authorization: Bearer pk_live_<key>" \
      -H "Idempotency-Key: revoke-data-key-2026-08-10"
    ```
  </Tab>
</UITabs>

```json
{ "dataKey": "pk_data_xxxxxxxxxxxxxxxx", "note": "This is the only time the full data key is shown." }
```
