# 4. Public API & Webhooks — Test Cases

User Type: **Super Administrator**
Source: *Mi Digital Academy - Education CRM Features Document*
Spec: public_api_webhooks.md — every feature, sub-feature, and rule covered

## Test Execution Policy

- Zero tolerance: any deviation from the documented behavior is a defect.
- Every failed test is logged with a Bug ID, the feature, the sub-feature, the expected vs actual result, and the severity; 100% of bugs are fixed before the group passes.
- 100% pass rate is required for the group to be marked complete.

## Coverage Matrix

| Feature | Sub-feature / Rule | Test IDs |
|---------|--------------------|----------|
| 4.1 API Key Management | Key issuance (per developer, description) | TC-SA-INT-20-001 |
| 4.1 API Key Management | Key scoping (read, write, admin; per resource) | TC-SA-INT-20-002 |
| 4.1 API Key Management | Key rotation (new, deprecate with grace) | TC-SA-INT-20-003 |
| 4.1 API Key Management | Key revocation (immediate, scheduled) | TC-SA-INT-20-004 |
| 4.1 API Key Management | Key usage summary (requests, last used, status) | TC-SA-INT-20-005 |
| 4.1 API Key Management | Rule: key shown in full only once | TC-SA-INT-20-006 |
| 4.1 API Key Management | Rule: revoked key rejected immediately | TC-SA-INT-20-007 |
| 4.1 API Key Management | Rule: rotated old key works until grace ends | TC-SA-INT-20-008 |
| 4.1 API Key Management | Rule: no scopes → rejected | TC-SA-INT-20-009 |
| 4.1 API Key Management | Rule: over-scope request → 403, logged | TC-SA-INT-20-010 |
| 4.1 API Key Management | Audit logging of API key management | TC-SA-INT-20-011 |
| 4.2 Rate Limiting Configuration | Global rate limit | TC-SA-INT-21-001 |
| 4.2 Rate Limiting Configuration | Per-key rate limit overrides | TC-SA-INT-21-002 |
| 4.2 Rate Limiting Configuration | Per-endpoint rate limits | TC-SA-INT-21-003 |
| 4.2 Rate Limiting Configuration | Per-plan-tier limits | TC-SA-INT-21-004 |
| 4.2 Rate Limiting Configuration | Rate limit headers and 429 behavior | TC-SA-INT-21-005 |
| 4.2 Rate Limiting Configuration | Rule: over limit → 429 with Retry-After | TC-SA-INT-21-006 |
| 4.2 Rate Limiting Configuration | Rule: per-key override precedence | TC-SA-INT-21-007 |
| 4.2 Rate Limiting Configuration | Rule: per-endpoint stricter than global | TC-SA-INT-21-008 |
| 4.2 Rate Limiting Configuration | Rule: tier change applies to new requests | TC-SA-INT-21-009 |
| 4.2 Rate Limiting Configuration | Rule: burst allowed, sustained overage throttled | TC-SA-INT-21-010 |
| 4.2 Rate Limiting Configuration | Audit logging of rate limiting configuration | TC-SA-INT-21-011 |
| 4.3 Webhook Event Configuration | Event catalog (enrollment, grade, payment, content) | TC-SA-INT-22-001 |
| 4.3 Webhook Event Configuration | Endpoint registration (URL, per event/group) | TC-SA-INT-22-002 |
| 4.3 Webhook Event Configuration | Retry policy (attempts, backoff, dead-letter) | TC-SA-INT-22-003 |
| 4.3 Webhook Event Configuration | Payload signing (HMAC secret, header) | TC-SA-INT-22-004 |
| 4.3 Webhook Event Configuration | Delivery log (status, latency, last result) | TC-SA-INT-22-005 |
| 4.3 Webhook Event Configuration | Rule: non-2xx → retry per policy | TC-SA-INT-22-006 |
| 4.3 Webhook Event Configuration | Rule: exhausted retries → dead-letter, flagged | TC-SA-INT-22-007 |
| 4.3 Webhook Event Configuration | Rule: at-least-once delivery | TC-SA-INT-22-008 |
| 4.3 Webhook Event Configuration | Rule: unreachable endpoint marked down, alerted | TC-SA-INT-22-009 |
| 4.3 Webhook Event Configuration | Audit logging of webhook event configuration | TC-SA-INT-22-010 |
| 4.4 Embed Widgets | Widget catalog (progress, schedule, announcements, leaderboard) | TC-SA-INT-23-001 |
| 4.4 Embed Widgets | Widget configuration (theme, data scope, refresh) | TC-SA-INT-23-002 |
| 4.4 Embed Widgets | Embed code generation (script with token) | TC-SA-INT-23-003 |
| 4.4 Embed Widgets | Domain allowlist | TC-SA-INT-23-004 |
| 4.4 Embed Widgets | Rule: non-allowlisted domain blocked | TC-SA-INT-23-005 |
| 4.4 Embed Widgets | Rule: token scoped to data scope only | TC-SA-INT-23-006 |
| 4.4 Embed Widgets | Rule: refresh below minimum clamped | TC-SA-INT-23-007 |
| 4.4 Embed Widgets | Rule: revoked token stops data loading | TC-SA-INT-23-008 |
| 4.4 Embed Widgets | Rule: never exposes data outside scope | TC-SA-INT-23-009 |
| 4.4 Embed Widgets | Audit logging of embed widgets | TC-SA-INT-23-010 |
| 4.5 Developer Documentation & Sandbox | API reference (endpoints, params, responses, errors) | TC-SA-INT-24-001 |
| 4.5 Developer Documentation & Sandbox | SDK and code samples (per language) | TC-SA-INT-24-002 |
| 4.5 Developer Documentation & Sandbox | Sandbox environment (isolated, test data) | TC-SA-INT-24-003 |
| 4.5 Developer Documentation & Sandbox | Sandbox key issuance (separate from production) | TC-SA-INT-24-004 |
| 4.5 Developer Documentation & Sandbox | Changelog (version changes, deprecations) | TC-SA-INT-24-005 |
| 4.5 Developer Documentation & Sandbox | Rule: sandbox key cannot access production | TC-SA-INT-24-006 |
| 4.5 Developer Documentation & Sandbox | Rule: deprecated endpoint returns sunset date | TC-SA-INT-24-007 |
| 4.5 Developer Documentation & Sandbox | Rule: breaking change requires new version | TC-SA-INT-24-008 |
| 4.5 Developer Documentation & Sandbox | Rule: sandbox reset clears test data, logged | TC-SA-INT-24-009 |
| 4.5 Developer Documentation & Sandbox | Rule: doc change versioned in changelog | TC-SA-INT-24-010 |
| 4.5 Developer Documentation & Sandbox | Audit logging of developer documentation & sandbox | TC-SA-INT-24-011 |

## 4.1 API Key Management

### TC-SA-INT-20-001 — Key issuance (per developer, description)
**Type:** Positive
**Covers:** 4.1 → Key issuance
**Preconditions:** A Super Admin account is active.
**Steps:**
1. As a Super Admin, open Integrations & APIs → Public API → API Keys and issue a new key with a description.
2. Verify the key is created and shown in full once.
**Expected Result:** Key issuance — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-20-002 — Key scoping (read, write, admin; per resource)
**Type:** Positive
**Covers:** 4.1 → Key scoping
**Preconditions:** A Super Admin is issuing an API key.
**Steps:**
1. Set the key scopes (read, write, admin; per resource).
2. Use the key and verify it can only perform scoped actions.
**Expected Result:** Key scoping — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-20-003 — Key rotation (new, deprecate with grace)
**Type:** Positive
**Covers:** 4.1 → Key rotation
**Preconditions:** An API key exists.
**Steps:**
1. Rotate the key (generate new, deprecate old with grace period).
2. Verify the new key works and the old key works until the grace period ends.
**Expected Result:** Key rotation — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-20-004 — Key revocation (immediate, scheduled)
**Type:** Positive
**Covers:** 4.1 → Key revocation
**Preconditions:** An API key exists.
**Steps:**
1. Revoke the key immediately and verify it is rejected on the next request.
2. Schedule a revocation and verify it takes effect at the scheduled time.
**Expected Result:** Key revocation — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-20-005 — Key usage summary (requests, last used, status)
**Type:** Positive
**Covers:** 4.1 → Usage summary
**Preconditions:** An API key has been used.
**Steps:**
1. Open the key usage summary.
2. Verify it shows requests, last used, and status.
**Expected Result:** Key usage summary — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-20-006 — Rule: key shown in full only once
**Type:** Negative
**Covers:** 4.1 → Rule: key visibility
**Preconditions:** An API key was created.
**Steps:**
1. Navigate away and return to the key.
2. Verify the key is shown only as a masked prefix (full value shown only once).
**Expected Result:** A key is shown in full only once at creation; afterward only a masked prefix — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-20-007 — Rule: revoked key rejected immediately
**Type:** Negative
**Covers:** 4.1 → Rule: revocation
**Preconditions:** An API key is revoked.
**Steps:**
1. Make a request with the revoked key.
2. Verify the request is rejected immediately.
**Expected Result:** A revoked key is rejected immediately on the next request — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-20-008 — Rule: rotated old key works until grace ends
**Type:** Edge
**Covers:** 4.1 → Rule: grace period
**Preconditions:** A key is rotated with a grace period.
**Steps:**
1. Use the old key within the grace period and verify it works.
2. Use it after the grace period and verify it is rejected.
**Expected Result:** A rotated key's old key works until the grace period ends, then is rejected — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-20-009 — Rule: no scopes → rejected
**Type:** Negative
**Covers:** 4.1 → Rule: scope required
**Preconditions:** A Super Admin is issuing a key.
**Steps:**
1. Attempt to issue a key with no scopes.
2. Verify the key is rejected (at least one scope required).
**Expected Result:** A key with no scopes is rejected (at least one scope is required) — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-20-010 — Rule: over-scope request → 403, logged
**Type:** Negative
**Covers:** 4.1 → Rule: scope enforcement
**Preconditions:** A key has read scope only.
**Steps:**
1. Make a write request with the key.
2. Verify it receives a 403 and the attempt is logged.
**Expected Result:** A key exceeding its scope on a request receives a 403 and the attempt is logged — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-20-011 — Audit logging of API key management
**Type:** Positive
**Covers:** 4.1 → Audit logging
**Preconditions:** API key management actions have been performed.
**Steps:**
1. Open the audit trail and filter by API key management.
2. Verify entries show the action, the key, and the timestamp.
**Expected Result:** Audit logging of API key management — delivered exactly as documented.
**Priority:** Critical

## 4.2 Rate Limiting Configuration

### TC-SA-INT-21-001 — Global rate limit
**Type:** Positive
**Covers:** 4.2 → Global rate limit
**Preconditions:** A Super Admin is configuring rate limiting.
**Steps:**
1. Open Public API → Rate Limiting and set the global rate limit (requests per minute/hour).
2. Send requests and verify the global limit is enforced.
**Expected Result:** Global rate limit — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-21-002 — Per-key rate limit overrides
**Type:** Positive
**Covers:** 4.2 → Per-key overrides
**Preconditions:** The global rate limit is set.
**Steps:**
1. Define a per-key rate limit override.
2. Send requests with that key and verify the override is enforced.
**Expected Result:** Per-key rate limit overrides — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-21-003 — Per-endpoint rate limits
**Type:** Positive
**Covers:** 4.2 → Per-endpoint limits
**Preconditions:** Rate limiting is configured.
**Steps:**
1. Set per-endpoint rate limits (stricter for expensive endpoints).
2. Send requests to the endpoint and verify the limit is enforced.
**Expected Result:** Per-endpoint rate limits — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-21-004 — Per-plan-tier limits
**Type:** Positive
**Covers:** 4.2 → Per-plan-tier limits
**Preconditions:** Rate limiting is configured.
**Steps:**
1. Set the per-plan-tier limits (higher tiers get higher limits).
2. Send requests from different tiers and verify each tier's limit applies.
**Expected Result:** Per-plan-tier limits — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-21-005 — Rate limit headers and 429 behavior
**Type:** Positive
**Covers:** 4.2 → Headers and 429
**Preconditions:** Rate limiting is configured.
**Steps:**
1. Send requests and inspect the rate limit headers.
2. Exceed the limit and verify the 429 response behavior.
**Expected Result:** Rate limit headers and 429 response behavior — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-21-006 — Rule: over limit → 429 with Retry-After
**Type:** Negative
**Covers:** 4.2 → Rule: 429
**Preconditions:** A request exceeds the rate limit.
**Steps:**
1. Send a request over the limit.
2. Verify it receives a 429 with a Retry-After header.
**Expected Result:** A request over the limit receives a 429 with a Retry-After header — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-21-007 — Rule: per-key override precedence
**Type:** Negative
**Covers:** 4.2 → Rule: precedence
**Preconditions:** A key has a per-key override different from the global limit.
**Steps:**
1. Send requests with the key.
2. Verify the per-key override takes precedence over the global limit.
**Expected Result:** A per-key override takes precedence over the global limit — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-21-008 — Rule: per-endpoint stricter than global
**Type:** Negative
**Covers:** 4.2 → Rule: endpoint strictness
**Preconditions:** An endpoint has a per-endpoint limit.
**Steps:**
1. Configure a per-endpoint limit looser than the global limit.
2. Verify the per-endpoint limit is stricter than (never looser than) the global limit.
**Expected Result:** A per-endpoint limit is stricter than (never looser than) the global limit — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-21-009 — Rule: tier change applies to new requests
**Type:** Edge
**Covers:** 4.2 → Rule: tier timing
**Preconditions:** A plan-tier limit is changed.
**Steps:**
1. Change the plan-tier limit.
2. Verify the change applies to new requests immediately.
**Expected Result:** A plan-tier limit change applies to new requests immediately — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-21-010 — Rule: burst allowed, sustained overage throttled
**Type:** Edge
**Covers:** 4.2 → Rule: burst vs sustained
**Preconditions:** Rate limiting is configured.
**Steps:**
1. Send a short burst within the limit and verify it is allowed.
2. Send sustained overage and verify it is throttled.
**Expected Result:** A burst within the limit is allowed; sustained overage is throttled — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-21-011 — Audit logging of rate limiting configuration
**Type:** Positive
**Covers:** 4.2 → Audit logging
**Preconditions:** Rate limiting configuration changes have been made.
**Steps:**
1. Open the audit trail and filter by rate limiting configuration.
2. Verify entries show the setting, the change, and the timestamp.
**Expected Result:** Audit logging of rate limiting configuration — delivered exactly as documented.
**Priority:** Critical

## 4.3 Webhook Event Configuration

### TC-SA-INT-22-001 — Event catalog (enrollment, grade, payment, content)
**Type:** Positive
**Covers:** 4.3 → Event catalog
**Preconditions:** A Super Admin is configuring webhooks.
**Steps:**
1. Open Public API → Webhooks and review the event catalog (enrollment, grade, payment, content).
2. Verify the available events are listed.
**Expected Result:** Event catalog — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-22-002 — Endpoint registration (URL, per event/group)
**Type:** Positive
**Covers:** 4.3 → Endpoint registration
**Preconditions:** Webhooks are being configured.
**Steps:**
1. Select the events to subscribe to and register the endpoint URL.
2. Trigger an event and verify it is delivered to the endpoint.
**Expected Result:** Endpoint registration — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-22-003 — Retry policy (attempts, backoff, dead-letter)
**Type:** Positive
**Covers:** 4.3 → Retry policy
**Preconditions:** Webhooks are configured.
**Steps:**
1. Configure the retry policy (attempts, backoff, dead-letter).
2. Trigger a failing delivery and verify the retry policy is applied.
**Expected Result:** Retry policy — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-22-004 — Payload signing (HMAC secret, header)
**Type:** Positive
**Covers:** 4.3 → Payload signing
**Preconditions:** Webhooks are configured.
**Steps:**
1. Generate the signing secret.
2. Trigger an event and verify the payload includes the signature header.
**Expected Result:** Payload signing — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-22-005 — Delivery log (status, latency, last result)
**Type:** Positive
**Covers:** 4.3 → Delivery log
**Preconditions:** Webhook deliveries have occurred.
**Steps:**
1. Open the delivery log.
2. Verify it shows status, latency, and last success/failure.
**Expected Result:** Delivery log — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-22-006 — Rule: non-2xx → retry per policy
**Type:** Negative
**Covers:** 4.3 → Rule: retry trigger
**Preconditions:** The endpoint returns a non-2xx response.
**Steps:**
1. Trigger an event to the failing endpoint.
2. Verify a retry is triggered per the retry policy.
**Expected Result:** A non-2xx response triggers a retry per the retry policy — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-22-007 — Rule: exhausted retries → dead-letter, flagged
**Type:** Negative
**Covers:** 4.3 → Rule: dead-letter
**Preconditions:** A webhook exhausts its retries.
**Steps:**
1. Let a webhook exhaust its retries.
2. Verify it is moved to the dead-letter queue and flagged.
**Expected Result:** A webhook that exhausts retries is moved to the dead-letter queue and flagged — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-22-008 — Rule: at-least-once delivery
**Type:** Edge
**Covers:** 4.3 → Rule: delivery semantics
**Preconditions:** A webhook event is delivered.
**Steps:**
1. Deliver an event and inspect the delivery log.
2. Verify the event is delivered at-least-once (receivers must be idempotent).
**Expected Result:** A webhook event is delivered at-least-once (receivers must be idempotent) — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-22-009 — Rule: unreachable endpoint marked down, alerted
**Type:** Negative
**Covers:** 4.3 → Rule: endpoint down
**Preconditions:** An endpoint is unreachable for a sustained period.
**Steps:**
1. Let the endpoint be unreachable.
2. Verify it is marked down and an alert is raised.
**Expected Result:** An endpoint unreachable for a sustained period is marked down and alerted — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-22-010 — Audit logging of webhook event configuration
**Type:** Positive
**Covers:** 4.3 → Audit logging
**Preconditions:** Webhook configuration changes have been made.
**Steps:**
1. Open the audit trail and filter by webhook event configuration.
2. Verify entries show the setting, the change, and the timestamp.
**Expected Result:** Audit logging of webhook event configuration — delivered exactly as documented.
**Priority:** Critical

## 4.4 Embed Widgets

### TC-SA-INT-23-001 — Widget catalog (progress, schedule, announcements, leaderboard)
**Type:** Positive
**Covers:** 4.4 → Widget catalog
**Preconditions:** A Super Admin is configuring embed widgets.
**Steps:**
1. Open Public API → Embed Widgets and review the widget catalog (progress, schedule, announcements, leaderboard).
2. Verify the available widget types are listed.
**Expected Result:** Widget catalog — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-23-002 — Widget configuration (theme, data scope, refresh)
**Type:** Positive
**Covers:** 4.4 → Widget configuration
**Preconditions:** A widget type is selected.
**Steps:**
1. Configure the theme, data scope, and refresh interval.
2. Verify the widget reflects the configuration.
**Expected Result:** Widget configuration — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-23-003 — Embed code generation (script with token)
**Type:** Positive
**Covers:** 4.4 → Embed code generation
**Preconditions:** A widget is configured.
**Steps:**
1. Generate the embed code (script tag with token).
2. Verify the code loads the widget with the token.
**Expected Result:** Embed code generation — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-23-004 — Domain allowlist
**Type:** Positive
**Covers:** 4.4 → Domain allowlist
**Preconditions:** Embed widgets are configured.
**Steps:**
1. Add allowed domains to the allowlist.
2. Embed the widget on an allowed domain and verify it loads.
**Expected Result:** Domain allowlist — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-23-005 — Rule: non-allowlisted domain blocked
**Type:** Negative
**Covers:** 4.4 → Rule: allowlist enforcement
**Preconditions:** A domain is not on the allowlist.
**Steps:**
1. Embed the widget on the non-allowlisted domain.
2. Verify the widget is blocked (shows an error state).
**Expected Result:** An embed on a non-allowlisted domain is blocked (widget shows an error state) — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-23-006 — Rule: token scoped to data scope only
**Type:** Negative
**Covers:** 4.4 → Rule: token scope
**Preconditions:** A widget token has a data scope.
**Steps:**
1. Use the token to request data outside its scope.
2. Verify the token is scoped to the configured data scope only.
**Expected Result:** A widget token is scoped to the configured data scope only — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-23-007 — Rule: refresh below minimum clamped
**Type:** Negative
**Covers:** 4.4 → Rule: refresh minimum
**Preconditions:** A widget refresh interval is set below the minimum.
**Steps:**
1. Set the refresh interval below the minimum.
2. Verify it is clamped to the minimum.
**Expected Result:** A widget refresh interval below the minimum is clamped to the minimum — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-23-008 — Rule: revoked token stops data loading
**Type:** Negative
**Covers:** 4.4 → Rule: token revocation
**Preconditions:** A widget token is revoked.
**Steps:**
1. Revoke the widget token.
2. Verify the widget stops loading data.
**Expected Result:** A revoked widget token stops the widget from loading data — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-23-009 — Rule: never exposes data outside scope
**Type:** Negative
**Covers:** 4.4 → Rule: data scope
**Preconditions:** A widget has a configured data scope.
**Steps:**
1. Inspect the widget's data output.
2. Verify it never exposes data outside its configured scope.
**Expected Result:** A widget never exposes data outside its configured scope — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-23-010 — Audit logging of embed widgets
**Type:** Positive
**Covers:** 4.4 → Audit logging
**Preconditions:** Embed widget configuration changes have been made.
**Steps:**
1. Open the audit trail and filter by embed widgets.
2. Verify entries show the setting, the change, and the timestamp.
**Expected Result:** Audit logging of embed widgets — delivered exactly as documented.
**Priority:** Critical

## 4.5 Developer Documentation & Sandbox

### TC-SA-INT-24-001 — API reference (endpoints, params, responses, errors)
**Type:** Positive
**Covers:** 4.5 → API reference
**Preconditions:** A Super Admin is managing developer docs.
**Steps:**
1. Open Public API → Developer Docs and review the API reference (endpoints, parameters, responses, errors).
2. Verify the reference is complete and accurate.
**Expected Result:** API reference — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-24-002 — SDK and code samples (per language)
**Type:** Positive
**Covers:** 4.5 → SDK and code samples
**Preconditions:** Developer docs are being managed.
**Steps:**
1. Review the SDK and code samples (per language).
2. Verify the samples are present and correct.
**Expected Result:** SDK and code samples — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-24-003 — Sandbox environment (isolated, test data)
**Type:** Positive
**Covers:** 4.5 → Sandbox environment
**Preconditions:** Developer docs are being managed.
**Steps:**
1. Access the sandbox environment.
2. Verify it is isolated with test data and no production side effects.
**Expected Result:** Sandbox environment — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-24-004 — Sandbox key issuance (separate from production)
**Type:** Positive
**Covers:** 4.5 → Sandbox key issuance
**Preconditions:** The sandbox is available.
**Steps:**
1. Issue a sandbox key.
2. Verify it is separate from production keys.
**Expected Result:** Sandbox key issuance — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-24-005 — Changelog (version changes, deprecations)
**Type:** Positive
**Covers:** 4.5 → Changelog
**Preconditions:** Developer docs are being managed.
**Steps:**
1. Review the changelog (API version changes, deprecations).
2. Verify the changelog reflects the changes.
**Expected Result:** Changelog — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-24-006 — Rule: sandbox key cannot access production
**Type:** Negative
**Covers:** 4.5 → Rule: isolation
**Preconditions:** A sandbox key is issued.
**Steps:**
1. Attempt to access production data with the sandbox key.
2. Verify it cannot access production data (strictly isolated).
**Expected Result:** A sandbox key cannot access production data (strictly isolated) — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-24-007 — Rule: deprecated endpoint returns sunset date
**Type:** Negative
**Covers:** 4.5 → Rule: deprecation
**Preconditions:** An endpoint is deprecated.
**Steps:**
1. Call the deprecated endpoint.
2. Verify it returns a deprecation header and a sunset date.
**Expected Result:** A deprecated endpoint returns a deprecation header and a sunset date — delivered exactly as documented.
**Priority:** High

### TC-SA-INT-24-008 — Rule: breaking change requires new version
**Type:** Negative
**Covers:** 4.5 → Rule: versioning
**Preconditions:** A breaking API change is made.
**Steps:**
1. Publish the breaking change.
2. Verify it requires a new version (old version kept until sunset).
**Expected Result:** A breaking API change requires a new version (old version kept until sunset) — delivered exactly as documented.
**Priority:** Critical

### TC-SA-INT-24-009 — Rule: sandbox reset clears test data, logged
**Type:** Negative
**Covers:** 4.5 → Rule: sandbox reset
**Preconditions:** The sandbox has test data.
**Steps:**
1. Reset the sandbox.
2. Verify the test data is cleared and the reset is logged.
**Expected Result:** A sandbox reset clears test data and is logged — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-24-010 — Rule: doc change versioned in changelog
**Type:** Negative
**Covers:** 4.5 → Rule: doc versioning
**Preconditions:** A documentation change is made.
**Steps:**
1. Publish the documentation change.
2. Verify it is versioned and reflected in the changelog.
**Expected Result:** A documentation change is versioned and reflected in the changelog — delivered exactly as documented.
**Priority:** Medium

### TC-SA-INT-24-011 — Audit logging of developer documentation & sandbox
**Type:** Positive
**Covers:** 4.5 → Audit logging
**Preconditions:** Developer documentation/sandbox changes have been made.
**Steps:**
1. Open the audit trail and filter by developer documentation & sandbox.
2. Verify entries show the change and the timestamp.
**Expected Result:** Audit logging of developer documentation & sandbox — delivered exactly as documented.
**Priority:** Critical
