import IfApp from '_core/components/IfApp.tsx'; # Static Sandbox The static sandbox lets you build and test your integration against every API endpoint without hitting the real backend. Same auth, same schemas, same rate limits — but deterministic mock responses, zero side effects, and no dependency on backend health. Use it to validate request shape, response parsing, header handling, auth flows, and `429` retry logic before you ever touch production. ## Getting started The static sandbox is a drop-in replacement for the production host. Keep your path, body, headers, and credentials exactly as they are — just change where you send the request.
EnvironmentHost
Productionnoon-api-gateway.noon.partners
Static Sandboxnoon-sandbox-api-gateway.noon.partners
EnvironmentHost
Productionnamshi-api-gateway.noon.partners
Static Sandboxnamshi-sandbox-api-gateway.noon.partners
EnvironmentHost
Productiondubai-mall-api-gateway.noon.partners
Static Sandboxdubai-mall-sandbox-api-gateway.noon.partners
## What stays the same as production - **Authentication.** OAuth tokens, project codes, and partner IDs behave identically. - **Rate limits.** Sandbox traffic counts against your per-project quota, so you can exercise real `429` handling. - **Request validation.** Malformed requests are rejected with the same `400` errors you'd see in production. Schema validation runs before the mock layer. - **Response schemas.** Every response is a real instance of the documented message, marshaled exactly as in production. ## What's different - **No backend.** Backend outages, latency spikes, and bugs never affect the sandbox. - **No side effects.** Nothing is persisted, no events are emitted, no downstream systems are called. - **No business validation.** Inventory, pricing, permissions, and similar checks are skipped. - **No simulated server errors.** The sandbox never returns `5xx`. You can observe `400` (bad request), `401` (bad auth), and `429` (rate-limited); everything else returns `200`. ## When to use the static sandbox vs production | Use the static sandbox to… | Use production to… | | :--- | :--- | | Wire up a new endpoint and verify your client deserializes the response | Run end-to-end tests that depend on real data | | Validate `400`, `401`, and `429` handling | Verify business rules (pricing, inventory, permissions) | | Smoke-test in CI without flakiness from upstream outages | Test `5xx` and other server-side error paths | | Develop offline against a stable contract | Anything that needs a real side effect | ## How responses are generated For each field in the response, the sandbox walks through these checks in order and uses the first one that applies. | Response field | Request has matching field? | Result | | :--- | :--- | :--- | | Any type | Yes | Copy the value as-is. Lists keep their length and order; nested objects are filled by re-running these same checks on each of their fields. | | String | No | Fill with the uppercased field name (e.g. `tag` → `"TAG"`). If the field is optional, prefix it: `OPTIONAL_TAG`. | | Anything else | No | Fill with the zero value for the type: `0` for numbers, `false` for booleans, `[]` for lists, `{}` for objects. If the field is optional, omit it from the response entirely. | :::info[Exception] The standard `status` field is always filled with `{ "code": 0, "message": "OK" }`, regardless of the request. ::: ### Examples > The endpoints below — `/dummy-service/v1/whoami`, `/dummy-service/v1/lookup`, `/dummy-service/v1/orders` — are **illustrative only**. This services does not exist and the APIs shown below do not exist. They're here to demonstrate how the sandbox builds responses from requests. For the actual endpoints you can call, see the [API reference][api-domains]. #### Example 1 — empty request A trivial endpoint that returns who you are. The request has no body, so the sandbox has nothing to copy from. **Endpoint:** `GET /dummy-service/v1/whoami` **Request body:** none. **Response schema:** | Field | Type | Required | | :--- | :--- | :--- | | `user_code` | string | yes | | `username` | string | yes | **Static Sandbox response:** ```json { "user_code": "USER_CODE", "username": "USERNAME" } ``` **How the sandbox built it:** no request body means no fields to copy. Both response fields are required strings with no request counterpart, so each is filled with its uppercased name. #### Example 2 — request fields echoed back A flat lookup endpoint that shows how request fields flow into the response and how missing fields are filled by type. **Endpoint:** `POST /dummy-service/v1/lookup` **Request schema:** | Field | Type | Required | | :--- | :--- | :--- | | `sku` | string | yes | | `locale` | string | no | **Example request:** ```json { "sku": "ABC-123", "locale": "en-AE" } ``` **Response schema:** | Field | Type | Required | | :--- | :--- | :--- | | `sku` | string | yes | | `locale` | string | no | | `title` | string | yes | | `price` | number | yes | | `in_stock` | boolean | yes | | `tags` | list of strings | yes | **Static Sandbox response:** ```json { "sku": "ABC-123", "locale": "en-AE", "title": "TITLE", "price": 0, "in_stock": false, "tags": [] } ``` **How the sandbox built it:** `sku` and `locale` match fields on the request, so they're copied verbatim. `title` is a required string with no counterpart → uppercased name. `price`, `in_stock`, and `tags` are non-string fields with no counterpart → zero values for their types. #### Example 3 — nested objects, lists, and optional fields An order-creation endpoint that exercises every rule at once: copying, recursion into nested objects, list preservation, optional-field handling, and the `status` rule. **Endpoint:** `POST /dummy-service/v1/orders` **Request schema:** | Field | Type | Required | | :--- | :--- | :--- | | `customer` | object | yes | | `customer.email` | string | yes | | `items` | list of objects | yes | | `items[].sku` | string | yes | | `items[].qty` | integer | yes | **Example request:** ```json { "customer": { "email": "x@y.com" }, "items": [ { "sku": "ABC-123", "qty": 2 }, { "sku": "XYZ-789", "qty": 1 } ] } ``` **Response schema:** | Field | Type | Required | | :--- | :--- | :--- | | `order_code` | string | yes | | `customer` | object | yes | | `customer.email` | string | yes | | `customer.name` | string | yes | | `customer.phone` | string | no | | `items` | list of objects | yes | | `items[].sku` | string | yes | | `items[].qty` | integer | yes | | `items[].line_total` | number | yes | | `status` | object | yes | **Static Sandbox response:** ```json { "order_code": "ORDER_CODE", "customer": { "email": "x@y.com", "name": "NAME", "phone": "OPTIONAL_PHONE" }, "items": [ { "sku": "ABC-123", "qty": 2, "line_total": 0 }, { "sku": "XYZ-789", "qty": 1, "line_total": 0 } ], "status": { "code": 0, "message": "OK" } } ``` **How the Static Sandbox built it, field by field:** - `order_code` — required string, no counterpart → uppercased name. - `customer` — nested object, filled recursively. `email` is copied from the request. `name` is a required string with no counterpart → uppercased name. `phone` is an optional string with no counterpart → `OPTIONAL_` prefix. - `items` — list with two entries on the request, preserved in order. Inside each entry, `sku` and `qty` are copied; `line_total` is a required number with no counterpart → `0`. - `status` — always succeeds. ## FAQ **Which error responses can the sandbox return?** `400` for malformed requests (same schema validation as production), `401` for invalid credentials, and `429` when you exceed your quota. The sandbox never returns `5xx`. To exercise server-error paths, mock at your client layer. **Do sandbox requests count against my rate limit?** Yes. This is intentional — it means your `429` handling can be validated against the same quota you'll see in production. **Are responses stable across calls?** Yes. The same request always produces the same response. Responses are a pure function of the request. **Can I tell from the response that I hit the sandbox?** The host you called is the source of truth. Response bodies don't carry an environment marker, so make sure your client logs which host it's pointing at.