--- id: fbpi-service-create-sandbox-order title: "CreateSandboxOrder" description: "Creates a test order in the sandbox environment so you can safely test FBPI APIs end-to-end without affecting real data or fulfillment." sidebar_label: "CreateSandboxOrder" hide_title: true hide_table_of_contents: true sidebar_class_name: "post api-method" --- # CreateSandboxOrder `POST /v1/sandbox-order/create` ## Usage Plan | Type | Requests | Time limit (seconds) | | --- | ---: | ---: | | Rate | 1500 | 60 | | Burst | 1500 | 60 | Learn more about rate limits and usage plans in the [Rate Limiting](/docs/overview/rate-limiting) guide. Creates a test order in the sandbox environment so you can safely test FBPI APIs end-to-end without affecting real data or fulfillment. The sandbox order is created with the same shape as a real marketplace order and triggers the standard order-creation webhook to your configured endpoint. Once created, you can call any FBPI API against this order to fetch its details, update item statuses, create shipments, cancel shipments, and explore the full integration flow. Sandbox orders never result in real fulfillment, and any identifiers returned (such as AWBs) are for testing purposes only and cannot be tracked. Sandbox orders are automatically deleted after a fixed retention period. ## Request No parameters documented. ### application/json - `warehouse_code` (string, required): The integration warehouse code where the sandbox order will be placed. Must be a warehouse you have already configured to receive order webhooks. - `idempotency_key` (string, required) - `items` (object[], required): The items to include in the sandbox order. Each entry creates one item on the order with the specified status. - `status` (string enum, required): The marketplace status to assign to this sandbox item (confirmed or cancelled). Allowed values: `MP_ITEM_STATUS_UNSPECIFIED`, `MP_ITEM_STATUS_CONFIRMED`, `MP_ITEM_STATUS_CANCELLED`. Default: `MP_ITEM_STATUS_UNSPECIFIED`. - `partner_sku` (string): Optional partner SKU for sandbox orders. If omitted or empty, the server assigns a dummy value. No validation is performed and it does not need to match a real SKU. Nullable. - `country_code` (string): Nullable. ## Responses ### 200 A successful response. ### application/json - `fbpi_order_nr` (string, required) ### default An unexpected error response. ### application/json - `status_id` (integer (int32)) - `status_code` (string) - `message` (string) - `details` (object[]) ## Code Examples ### python ```python # Authentiction code is added below, to know more about authentication # visit: https://noon-docs.noonpartners.dev/docs/authentication/authenticating-requests import json import time import uuid import jwt import requests BASE_URL = "https://noon-api-gateway.noon.partners" USER_AGENT = "NoonApiClient/1.0" with open("noon_credentials_sensitive.json", "r", encoding="utf-8") as file: credentials = json.load(file) # Create a signed RS256 JWT for the login request. def create_jwt(): return jwt.encode( { "sub": credentials["key_id"], "iat": int(time.time()), "jti": str(uuid.uuid4()), }, credentials["private_key"], algorithm="RS256", ) # Log in and return a requests session that keeps auth cookies. def get_authenticated_session(): session = requests.Session() session.headers.update({"User-Agent": USER_AGENT}) response = session.post( f"{BASE_URL}/identity/public/v1/api/login", json={ "token": create_jwt(), "default_project_code": credentials["project_code"], }, ) if response.status_code != 200: raise Exception(f"Login failed with HTTP {response.status_code}: {response.text}") return session session = get_authenticated_session() payload = '' headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' } res = session.post("https://{{baseUrl}}/v1/sandbox-order/create", data=json.dumps(payload), headers=headers) ``` ### go ```go // Authentiction code is added below, to know more about authentication // visit: https://noon-docs.noonpartners.dev/docs/authentication/authenticating-requests package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "net/http/cookiejar" "os" "time" // go get github.com/google/uuid github.com/golang-jwt/jwt/v5 "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" ) const BASE_URL = "https://noon-api-gateway.noon.partners" const USER_AGENT = "NoonApiClient/1.0" type Credentials struct { PrivateKey string `json:"private_key"` KeyID string `json:"key_id"` ProjectCode string `json:"project_code"` } var credentials Credentials func check(err error) { if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func read_credentials() Credentials { file, err := os.ReadFile("noon_credentials_sensitive.json") check(err) var credentials Credentials check(json.Unmarshal(file, &credentials)) return credentials } func create_jwt() string { private_key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(credentials.PrivateKey)) check(err) token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{ "sub": credentials.KeyID, "iat": time.Now().Unix(), "jti": uuid.NewString(), }) signed_token, err := token.SignedString(private_key) check(err) return signed_token } func get_authenticated_session() *http.Client { jar, err := cookiejar.New(nil) check(err) client := &http.Client{Jar: jar} body, _ := json.Marshal(map[string]string{ "token": create_jwt(), "default_project_code": credentials.ProjectCode, }) req, err := http.NewRequest( "POST", BASE_URL+"/identity/public/v1/api/login", bytes.NewReader(body), ) check(err) req.Header.Set("User-Agent", USER_AGENT) req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) check(err) defer resp.Body.Close() response_body, _ := io.ReadAll(resp.Body) if resp.StatusCode != 200 { fmt.Fprintf(os.Stderr, "Login failed with HTTP %d: %s\n", resp.StatusCode, response_body) os.Exit(1) } return client } func main() { credentials = read_credentials() client := get_authenticated_session() url := "{{baseUrl}}/v1/sandbox-order/create" method := "POST" payload := strings.NewReader(``) req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return } req.Header.Add("Content-Type", "application/json") req.Header.Add("Accept", "application/json") res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := io.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) } ``` ### java ```java // Authentiction code is added below, to know more about authentication // visit: https://noon-docs.noonpartners.dev/docs/authentication/authenticating-requests import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.*; import java.io.File; import java.security.KeyFactory; import java.security.interfaces.RSAPrivateKey; import java.security.spec.PKCS8EncodedKeySpec; import java.time.Instant; import java.util.*; public class Main { private static RSAPrivateKey readPrivateKey(String pem) throws Exception { String stripped = pem .replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") .replaceAll("\\s", ""); byte[] encoded = Base64.getDecoder().decode(stripped); return (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(encoded)); } static OkHttpClient getAuthenticatedClient() throws Exception { ObjectMapper mapper = new ObjectMapper(); Map credentials = mapper.readValue(new File("noon_credentials_sensitive.json"), Map.class); String privateKeyPem = (String) credentials.get("private_key"); String keyId = (String) credentials.get("key_id"); String projectCode = (String) credentials.get("project_code"); RSAPrivateKey privateKey = readPrivateKey(privateKeyPem); long now = Instant.now().getEpochSecond(); String jti = UUID.randomUUID().toString(); String token = JWT.create() .withSubject(keyId) .withIssuedAt(java.util.Date.from(Instant.ofEpochSecond(now))) .withJWTId(jti) .sign(Algorithm.RSA256(null, privateKey)); OkHttpClient client = new OkHttpClient.Builder() .cookieJar(new CookieJar() { private List cookies = new ArrayList<>(); @Override public void saveFromResponse(HttpUrl url, List cookies) { this.cookies = cookies; } @Override public List loadForRequest(HttpUrl url) { return cookies != null ? cookies : new ArrayList<>(); } }) .build(); Map loginPayload = new HashMap<>(); loginPayload.put("token", token); loginPayload.put("default_project_code", projectCode); RequestBody loginBody = RequestBody.create( mapper.writeValueAsString(loginPayload), MediaType.parse("application/json") ); Request loginRequest = new Request.Builder() .url("https://noon-api-gateway.noon.partners/identity/public/v1/api/login") .post(loginBody) .header("User-Agent", "REPLACE_WITH_YOUR_USER_AGENT") .build(); try (Response loginResponse = client.newCall(loginRequest).execute()) { if (!loginResponse.isSuccessful()) { throw new RuntimeException( "Login failed: " + loginResponse.code() + " " + loginResponse.body().string() ); } } return client; } public static void main(String[] args) throws Exception { OkHttpClient client = getAuthenticatedClient(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("{{baseUrl}}/v1/sandbox-order/create") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); } } ``` ### nodejs ```javascript // Authentiction code is added below, to know more about authentication // visit: https://noon-docs.noonpartners.dev/docs/authentication/authenticating-requests import fs from 'fs'; import crypto from 'crypto' const credentials = JSON.parse( fs.readFileSync('noon_credentials_sensitive.json', 'utf8'), ); const BASE_URL = 'https://noon-api-gateway.noon.partners'; const USER_AGENT = 'NoonApiClient/1.0'; function base64url(value) { return Buffer.from(value).toString('base64url'); } function create_jwt() { const header = base64url(JSON.stringify({ alg: 'RS256', typ: 'JWT' })); const payload = base64url(JSON.stringify({ sub: credentials.key_id, iat: Math.floor(Date.now() / 1000), jti: crypto.randomUUID(), })); const signing_input = `${header}.${payload}`; const signature = crypto.sign( 'RSA-SHA256', Buffer.from(signing_input), credentials.private_key, ); return `${signing_input}.${base64url(signature)}`; } function get_cookie_header(response) { const set_cookie_headers = response.headers.getSetCookie?.() || [response.headers.get('set-cookie')].filter(Boolean); return set_cookie_headers .map((cookie) => cookie.split(';')[0]) .join('; '); } async function get_authenticated_session() { const response = await fetch(`${BASE_URL}/identity/public/v1/api/login`, { method: 'POST', headers: { 'User-Agent': USER_AGENT, 'Content-Type': 'application/json', }, body: JSON.stringify({ token: create_jwt(), default_project_code: credentials.project_code, }), }); if (response.status !== 200) { throw new Error(`Login failed with HTTP ${response.status}: ${await response.text()}`); } const cookie_header = get_cookie_header(response); return { get: (path) => fetch(`${BASE_URL}${path}`, { headers: { 'User-Agent': USER_AGENT, Cookie: cookie_header }, }), post: (path, body) => fetch(`${BASE_URL}${path}`, { method: 'POST', headers: { 'User-Agent': USER_AGENT, 'Content-Type': 'application/json', Cookie: cookie_header }, body: JSON.stringify(body), }), }; } const session = await get_authenticated_session(); const res = await session.post('/v1/sandbox-order/create'); const data = await res.text(); ``` ### php ```php $credentials['key_id'], 'iat' => time(), 'jti' => Uuid::uuid4()->toString(), ], $credentials['private_key'], 'RS256'); } function get_authenticated_session(): Client { global $credentials; $client = new Client([ 'base_uri' => BASE_URL, 'cookies' => new CookieJar(), 'http_errors' => false, 'headers' => ['User-Agent' => USER_AGENT], ]); $response = $client->post('/identity/public/v1/api/login', [ 'json' => [ 'token' => create_jwt(), 'default_project_code' => $credentials['project_code'], ], ]); if ($response->getStatusCode() !== 200) { throw new Exception( 'Login failed with HTTP ' . $response->getStatusCode() . ': ' . $response->getBody() ); } return $client; } $session = get_authenticated_session(); $body = ''; $response = $session->get('', ['json' => json_decode($body, true)]); $data = $response->getBody()->getContents(); ``` ### csharp ```csharp // Authentiction code is added below, to know more about authentication // visit: https://noon-docs.noonpartners.dev/docs/authentication/authenticating-requests using System.Net; using System.Net.Http.Json; using System.Security.Cryptography; using System.Text; using System.Text.Json; const string BASE_URL = "https://noon-api-gateway.noon.partners"; const string USER_AGENT = "NoonApiClient/1.0"; var credentials = JsonSerializer.Deserialize>( File.ReadAllText("noon_credentials_sensitive.json") )!; string base64url(byte[] value) => Convert.ToBase64String(value).TrimEnd('=').Replace('+', '-').Replace('/', '_'); string create_jwt() { var header = base64url(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new { alg = "RS256", typ = "JWT" }))); var payload = base64url(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new { sub = credentials["key_id"], iat = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), jti = Guid.NewGuid().ToString() }))); var signingInput = $"{header}.{payload}"; using var rsa = RSA.Create(); rsa.ImportFromPem(credentials["private_key"]); var signature = rsa.SignData( Encoding.UTF8.GetBytes(signingInput), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1 ); return $"{signingInput}.{base64url(signature)}"; } async Task get_authenticated_session() { var handler = new HttpClientHandler { CookieContainer = new CookieContainer() }; var client = new HttpClient(handler) { BaseAddress = new Uri(BASE_URL) }; client.DefaultRequestHeaders.UserAgent.ParseAdd(USER_AGENT); var response = await client.PostAsJsonAsync("/identity/public/v1/api/login", new { token = create_jwt(), default_project_code = credentials["project_code"] }); if (response.StatusCode != HttpStatusCode.OK) { throw new Exception( $"Login failed with HTTP {(int)response.StatusCode}: {await response.Content.ReadAsStringAsync()}" ); } return client; } var session = await get_authenticated_session(); var content = new StringContent("", null, "application/json"); var response = await session.GetAsync("", content); response.EnsureSuccessStatusCode(); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` ### curl ```bash # Authentiction code is added below, to know more about authentication # visit: https://noon-docs.noonpartners.dev/docs/authentication/authenticating-requests #!/usr/bin/env bash set -euo pipefail NOON_BASE_URL="${NOON_BASE_URL:-https://noon-api-gateway.noon.partners}" CREDENTIALS_FILE="${NOON_CREDENTIALS_FILE:-noon_credentials_sensitive.json}" NOON_USER_AGENT="${NOON_USER_AGENT:-NoonApiClient/1.0}" COOKIE_JAR="$(mktemp "${TMPDIR:-/tmp}/noon_cookies.XXXXXX")" PRIVATE_KEY_FILE="$(mktemp "${TMPDIR:-/tmp}/noon_private_key.XXXXXX")" trap 'rm -f "$COOKIE_JAR" "$PRIVATE_KEY_FILE"' EXIT cred() { jq -r --arg key "$1" '.[$key]' "$CREDENTIALS_FILE"; } b64url() { openssl base64 -A | tr '+/' '-_' | tr -d '='; } create_jwt() { cred private_key > "$PRIVATE_KEY_FILE" chmod 600 "$PRIVATE_KEY_FILE" header_b64="$(printf '%s' '{"alg":"RS256","typ":"JWT"}' | b64url)" payload_json="$( jq -cn \ --arg sub "$(cred key_id)" \ --argjson iat "$(date +%s)" \ --arg jti "$(uuidgen | tr '[:upper:]' '[:lower:]')" \ '{sub:$sub,iat:$iat,jti:$jti}' )" payload_b64="$(printf '%s' "$payload_json" | b64url)" signing_input="${header_b64}.${payload_b64}" signature_b64="$( printf '%s' "$signing_input" \ | openssl dgst -sha256 -sign "$PRIVATE_KEY_FILE" -binary \ | b64url )" printf '%s.%s\n' "$signing_input" "$signature_b64" } get_authenticated_session() { body="$( jq -cn \ --arg token "$(create_jwt)" \ --arg project_code "$(cred project_code)" \ '{token:$token,default_project_code:$project_code}' )" login_result="$( curl --silent --show-error \ --request POST "${NOON_BASE_URL}/identity/public/v1/api/login" \ --header "User-Agent: ${NOON_USER_AGENT}" \ --header "Content-Type: application/json" \ --cookie-jar "$COOKIE_JAR" \ --data "$body" \ --write-out $'\n%{http_code}' )" login_status="${login_result##*$'\n'}" login_body="${login_result%$'\n'*}" if [ "$login_status" != "200" ]; then echo "Login failed with HTTP $login_status:" >&2 echo "$login_body" >&2 exit 1 fi printf '%s\n' "$COOKIE_JAR" } SESSION_COOKIE_JAR="$(get_authenticated_session)" curl -L -g -X POST '{{baseUrl}}/v1/sandbox-order/create' \ --cookie "$SESSION_COOKIE_JAR" \ --header "User-Agent: ${NOON_USER_AGENT}" \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '' ```