Skip to main content

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

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 responseRun end-to-end tests that depend on real data
Validate 400, 401, and 429 handlingVerify business rules (pricing, inventory, permissions)
Smoke-test in CI without flakiness from upstream outagesTest 5xx and other server-side error paths
Develop offline against a stable contractAnything 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 fieldRequest has matching field?Result
Any typeYesCopy 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.
StringNoFill with the uppercased field name (e.g. tag"TAG"). If the field is optional, prefix it: OPTIONAL_TAG.
Anything elseNoFill 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.
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.

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:

FieldTypeRequired
user_codestringyes
usernamestringyes

Static Sandbox response:

{
"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:

FieldTypeRequired
skustringyes
localestringno

Example request:

{
"sku": "ABC-123",
"locale": "en-AE"
}

Response schema:

FieldTypeRequired
skustringyes
localestringno
titlestringyes
pricenumberyes
in_stockbooleanyes
tagslist of stringsyes

Static Sandbox response:

{
"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:

FieldTypeRequired
customerobjectyes
customer.emailstringyes
itemslist of objectsyes
items[].skustringyes
items[].qtyintegeryes

Example request:

{
"customer": { "email": "[email protected]" },
"items": [
{ "sku": "ABC-123", "qty": 2 },
{ "sku": "XYZ-789", "qty": 1 }
]
}

Response schema:

FieldTypeRequired
order_codestringyes
customerobjectyes
customer.emailstringyes
customer.namestringyes
customer.phonestringno
itemslist of objectsyes
items[].skustringyes
items[].qtyintegeryes
items[].line_totalnumberyes
statusobjectyes

Static Sandbox response:

{
"order_code": "ORDER_CODE",
"customer": {
"email": "[email protected]",
"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.