# Sooquna theme docs URL: https://sooquna.com/docs > Build and customise Sooquna storefront themes with Liquid, sections, blocks and settings. A Sooquna theme is a folder of Liquid templates, sections, blocks, CSS and JavaScript that draws a store's storefront. If you've built a Shopify Online Store 2.0 theme, you already know most of it: the same folders, the same JSON templates, the same Liquid objects and filters. The differences that matter are listed in [Migrating from Shopify](/docs/migrating). Every store starts with **Sahil**, our first-party theme. It's Arabic-first, right-to-left ready and fast, so it's the best place to see how things fit together. Change a section of Sahil in the code editor and see it live. [Quick start](/docs/getting-started/quick-start) Request, layout, template, sections, blocks. [How rendering works](/docs/getting-started/how-rendering-works) Every tag, filter and object, with examples that are tested against the renderer. [Filters](/docs/liquid/filters) One theme for both directions: logical CSS, bidi-safe text, Arabic plurals. [RTL guide](/docs/best-practices/rtl-arabic) ## What's in a theme | Folder | What it holds | | --- | --- | | `layout/` | The page frame: ``, ``, header and footer groups. | | `templates/` | One per page type (product, collection…), usually JSON listing sections. | | `sections/` | Reusable, merchant-arrangeable parts of a page, each with a schema. | | `blocks/` | Theme blocks that sections (and other blocks) can hold. | | `snippets/` | Liquid partials you `render`. | | `custom_pages/` | Standalone pages such as a size guide, at `/custom/`. | | `assets/` | CSS, JavaScript, fonts and images. | | `config/` | Theme settings and their current values. | | `locales/` | Storefront and editor translations. | Read [Directory structure](/docs/architecture/directory-structure) for the rules of each folder. ## Where to go next :::note[For AI assistants] A plain-text index of these docs is at [/llms.txt](/llms.txt), and the whole English docs in one file at [/llms-full.txt](/llms-full.txt). The machine-readable Liquid reference is at [/docs/liquid/spec.json](/docs/liquid/spec.json). ::: --- # API overview URL: https://sooquna.com/docs/api > The Admin API, the Storefront API and webhooks, for apps and integrations. Themes draw the storefront; apps and integrations use the APIs. Both are versioned by date: the current version is **2026-10**, supported for 12 months. ## Admin API Read and change a store's data: products, orders, customers, inventory, discounts, content and more. - **Base URL**: `https://api.sooquna.com/admin/api/2026-10` - **Auth**: an app's access token in `X-Sooquna-Access-Token` (or `Authorization: Bearer`). Merchants create custom apps in **Settings › Apps and API** and choose their scopes; tokens are shown once. - **Scopes**: `read_products`, `write_orders`… An endpoint needs the scope in the [reference](/docs/api/admin); `write_` includes `read_`. - **Rate limit**: a bucket of 40 requests per app and store, refilled at the plan's rate. Read `X-RateLimit-Remaining`; a `429` comes with `Retry-After`. - **Pagination**: `?limit=` and `?after=`. - **Versions**: in the last three months of a version, responses carry `Deprecation` and `Sunset` headers. The [Admin API reference](/docs/api/admin) has every endpoint with code in cURL, Node.js, Python, PHP, Go and C#, and the [OpenAPI document](/docs/api/admin-2026-10.json) generates clients. ### Idempotency Requests that create orders, move stock or money (draft orders and their completion, refunds, fulfilments, cancellations, marking paid, stock adjustments and moves, receiving transfers and purchase orders, creating customers) need an `Idempotency-Key` header: a random value, such as a UUID, new for each operation. If a request times out, send it again with the same key: within 24 hours it's applied once and the retry gets the first answer. The same key with a different request is refused (`idempotency_key_reused`), and a retry while the first is still running gets `409` (`idempotency_in_flight`). Keys are up to 255 characters. ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/$ORDER_ID/mark-paid" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: 4f7c1e8a-2b6d-4e0f-9a31-6c5d8e2b7f10" ``` ### Versions of a resource Resources have a `version`. Send the version you read with an update; if someone changed the resource since, you get `409` and can read it again before retrying. `PUT` replaces the resource (fields left out are cleared, variants left out are deleted); `PATCH` changes only the fields you send. ### Errors Errors are [problem details](https://www.rfc-editor.org/rfc/rfc9457) JSON with a stable `code`, a human `detail`, and `errors` per field for invalid input: ```json { "status": 422, "code": "invalid_invalid", "detail": "Unknown sort order.", "errors": [{ "field": "sort_order", "code": "invalid", "message": "Unknown sort order." }] } ``` ## Storefront API Public, read-mostly access for headless storefronts and mobile apps: products, collections, search, menus, pages, carts and customer sign-in. - **Base URL**: `/api/storefront/2026-10/…` on the store's domain or the API host. - **Auth**: a public storefront token (`sooquna_sf_…`) from **Settings › Apps and API**. - **Language**: `?locale=` or `Accept-Language`, among the store's published languages. - **Carts** use the same engine as the storefront; `checkout_url` opens the hosted checkout. ## Webhooks Subscribe to events (`orders/create`, `products/update`…) per app. Each delivery is signed: ```js const crypto = require("node:crypto"); function verified(rawBody, header, secret) { const digest = crypto.createHmac("sha256", secret).update(rawBody).digest(); const given = Buffer.from(header || "", "base64"); return given.length === digest.length && crypto.timingSafeEqual(digest, given); } ``` Compute the HMAC over the raw body (header `X-Sooquna-Hmac-Sha256`) before parsing it. Answer with a 2xx within 5 seconds and do the work afterwards; failures are retried for about 48 hours. `X-Sooquna-Webhook-Id` is the same across retries: use it to ignore duplicates. --- # Admin API 2026-10 URL: https://sooquna.com/docs/api/admin > Every endpoint of the Admin API version 2026-10, with code in cURL, Node.js, Python, PHP, Go and C#. Generated from the OpenAPI document and examples that run against a real store in Sooquna's tests. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. */} Every endpoint of the Admin API version 2026-10, with code in cURL, Node.js, Python, PHP, Go and C#. Generated from the OpenAPI document and examples that run against a real store in Sooquna's tests. Base URL: `https://api.sooquna.com/admin/api/2026-10`. Download the [OpenAPI 3.1 document](/docs/api/admin-2026-10.json) to generate a client. Authentication, rate limits, idempotency and webhooks are in the [API overview](/docs/api). | Resource | Endpoints | | | --- | --- | --- | | [Access scopes](/docs/api/admin/access-scopes) | 1 | | | [Bulk operations](/docs/api/admin/bulk-operations) | 4 | | | [Content](/docs/api/admin/content) | 25 | Pages, blogs, articles, menus, redirects and policies. | | [Customers](/docs/api/admin/customers) | 22 | Customers, their addresses and segments (contact details need read_customer_pii). | | [Discounts](/docs/api/admin/discounts) | 14 | Discounts and discount codes. | | [Draft orders](/docs/api/admin/draft-orders) | 7 | Draft orders. | | [Files](/docs/api/admin/files) | 9 | Files and uploads. | | [Fulfillments](/docs/api/admin/fulfillments) | 11 | Fulfillment orders, fulfillments, shipping labels and tracking. | | [Gift cards](/docs/api/admin/gift-cards) | 7 | Gift cards and their balances. | | [Inventory](/docs/api/admin/inventory) | 27 | Stock levels, adjustments, transfers, suppliers and purchase orders. | | [Locations](/docs/api/admin/locations) | 7 | Warehouses, shops and pickup points. | | [Metaobjects](/docs/api/admin/metaobjects) | 15 | Metafields, their definitions, and metaobjects. | | [Orders](/docs/api/admin/orders) | 17 | Orders, transactions, refunds and abandoned checkouts (the last 60 days without read_all_orders). | | [Products](/docs/api/admin/products) | 23 | Products, variants, collections and the product taxonomy. | | [Reports](/docs/api/admin/reports) | 2 | Analytics reports. | | [Returns](/docs/api/admin/returns) | 4 | Return requests. | | [Shipping](/docs/api/admin/shipping) | 8 | Shipping profiles, zones, rates, local delivery and pickup. | | [Shop](/docs/api/admin/shop) | 1 | | | [Themes](/docs/api/admin/themes) | 27 | Themes and theme files. | | [Translations](/docs/api/admin/translations) | 4 | Languages and translated content. | | [Webhooks](/docs/api/admin/webhooks) | 10 | | --- # Access scopes URL: https://sooquna.com/docs/api/admin/access-scopes > Admin API 2026-10: Access scopes {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Endpoints for access scopes. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [List the scopes this token has](#list-the-scopes-this-token-has) | GET | `/access_scopes` | ## List the scopes this token has GET `/access_scopes` · Any token ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/access_scopes" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/access_scopes", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/access_scopes", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/access_scopes", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/access_scopes"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "access_scopes": [{"handle": "read_all_orders"}, {"handle": "read_customer_pii"}] } ```
--- # Bulk operations URL: https://sooquna.com/docs/api/admin/bulk-operations > Admin API 2026-10: Bulk operations {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Endpoints for bulk operations. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Start a bulk export](#start-a-bulk-export) | POST | `/bulk-operations` | | [List bulk exports](#list-bulk-exports) | GET | `/bulk-operations` | | [Get a bulk export](#get-a-bulk-export) | GET | `/bulk-operations/{id}` | | [Cancel a bulk export](#cancel-a-bulk-export) | POST | `/bulk-operations/{id}/cancel` | ## Start a bulk export POST `/bulk-operations` · Any token Exports a resource as JSONL to a signed download URL. ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/bulk-operations" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"resource": "products", "query": {"status": "active"}}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/bulk-operations", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"resource": "products", "query": {"status": "active"}}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/bulk-operations", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"resource": "products", "query": {"status": "active"}}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['resource' => 'products', 'query' => ['status' => 'active']], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"resource": "products", "query": {"status": "active"}}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/bulk-operations", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/bulk-operations"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"resource": "products", "query": {"status": "active"}} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "completed_at": null, "created_at": "2026-10-18T09:30:00Z", "file_size": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000003", "object_count": 0, "query": {"status": "active"}, "resource": "products", "status": "created" } ```
## List bulk exports GET `/bulk-operations` · Any token ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/bulk-operations" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/bulk-operations", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/bulk-operations", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/bulk-operations", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/bulk-operations"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "completed_at": null, "created_at": "2026-10-18T09:30:00Z", "file_size": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000003", "object_count": 0, "query": {"status": "active"}, "resource": "products", "status": "created" } ] } ```
## Get a bulk export GET `/bulk-operations/{id}` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "completed_at": null, "created_at": "2026-10-18T09:30:00Z", "file_size": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000003", "object_count": 0, "query": {"status": "active"}, "resource": "products", "status": "created" } ```
## Cancel a bulk export POST `/bulk-operations/{id}/cancel` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003/cancel" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003/cancel", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003/cancel", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003/cancel", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/bulk-operations/0193a1b2-c3d4-7e5f-8a6b-000000000003/cancel"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Content URL: https://sooquna.com/docs/api/admin/content > Admin API 2026-10: Pages, blogs, articles, menus, redirects and policies. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Pages, blogs, articles, menus, redirects and policies. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Create a page](#create-a-page) | POST | `/pages` | | [List pages](#list-pages) | GET | `/pages` | | [Get a page](#get-a-page) | GET | `/pages/{id}` | | [Update a page](#update-a-page) | PUT | `/pages/{id}` | | [Show, hide or delete many pages](#show-hide-or-delete-many-pages) | POST | `/pages/bulk` | | [Create a blog](#create-a-blog) | POST | `/blogs` | | [List blogs](#list-blogs) | GET | `/blogs` | | [Update a blog](#update-a-blog) | PUT | `/blogs/{id}` | | [Create a blog post](#create-a-blog-post) | POST | `/articles` | | [List blog posts](#list-blog-posts) | GET | `/articles` | | [Get a blog post](#get-a-blog-post) | GET | `/articles/{id}` | | [Update a blog post](#update-a-blog-post) | PUT | `/articles/{id}` | | [Delete many blog posts](#delete-many-blog-posts) | POST | `/articles/bulk` | | [Delete a blog and its posts](#delete-a-blog-and-its-posts) | DELETE | `/blogs/{id}` | | [Create a navigation menu](#create-a-navigation-menu) | POST | `/menus` | | [List navigation menus](#list-navigation-menus) | GET | `/menus` | | [Get a navigation menu](#get-a-navigation-menu) | GET | `/menus/{id}` | | [Update a navigation menu](#update-a-navigation-menu) | PUT | `/menus/{id}` | | [Delete a navigation menu](#delete-a-navigation-menu) | DELETE | `/menus/{id}` | | [List store policies](#list-store-policies) | GET | `/policies` | | [Update a store policy](#update-a-store-policy) | PUT | `/policies/{kind}` | | [Create a URL redirect](#create-a-url-redirect) | POST | `/redirects` | | [List URL redirects](#list-url-redirects) | GET | `/redirects` | | [Update a URL redirect](#update-a-url-redirect) | PUT | `/redirects/{id}` | | [Delete URL redirects](#delete-url-redirects) | POST | `/redirects/delete` | ## Create a page POST `/pages` · Scope: `write_content` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/pages" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "visible": true, "seo_description": "Our story." }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/pages", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "visible": true, "seo_description": "Our story." }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/pages", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "visible": True, "seo_description": "Our story.", }, ) res.raise_for_status() print(res.json()) ```
```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'title' => 'About us', 'body_html' => '

A family-run abaya house in Doha since 2009.

', 'visible' => true, 'seo_description' => 'Our story.', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "visible": true, "seo_description": "Our story." }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/pages", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/pages"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "visible": true, "seo_description": "Our story." } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "author": "Docs", "body_html": "

A family-run abaya house in Doha since 2009.

", "created_at": "2026-10-18T09:30:00Z", "custom_page_name": "", "handle": "about-us", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000029", "publish_at": null, "published_at": "2026-10-18T09:30:00Z", "seo_description": "Our story.", "seo_title": "", "template_suffix": "", "title": "About us", "updated_at": "2026-10-18T09:30:00Z", "version": 1, "visible": true } ```
## List pages GET `/pages` · Scope: `read_content` | Parameter | In | Description | | --- | --- | --- | | `visibility` | query | For example `visible`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/pages?visibility=visible" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/pages?visibility=visible", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/pages?visibility=visible", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/pages?visibility=visible", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/pages?visibility=visible"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "author": "Docs", "body_html": "

A family-run abaya house in Doha since 2009.

", "created_at": "2026-10-18T09:30:00Z", "custom_page_name": "", "handle": "about-us", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000029", "publish_at": null, "published_at": "2026-10-18T09:30:00Z", "seo_description": "Our story.", "seo_title": "", "template_suffix": "", "title": "About us", "updated_at": "2026-10-18T09:30:00Z", "version": 1, "visible": true } ], "total": 1 } ```
## Get a page GET `/pages/{id}` · Scope: `read_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "author": "Docs", "body_html": "

A family-run abaya house in Doha since 2009.

", "created_at": "2026-10-18T09:30:00Z", "custom_page_name": "", "handle": "about-us", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000029", "publish_at": null, "published_at": "2026-10-18T09:30:00Z", "seo_description": "Our story.", "seo_title": "", "template_suffix": "", "title": "About us", "updated_at": "2026-10-18T09:30:00Z", "version": 1, "visible": true } ```
## Update a page PUT `/pages/{id}` · Scope: `write_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "custom_page_name": "", "visible": true, "version": 1 }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "custom_page_name": "", "visible": true, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "custom_page_name": "", "visible": True, "version": 1, }, ) res.raise_for_status() print(res.json()) ```
```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'title' => 'About us', 'body_html' => '

A family-run abaya house in Doha since 2009.

', 'custom_page_name' => '', 'visible' => true, 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "custom_page_name": "", "visible": true, "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/pages/0193a1b2-c3d4-7e5f-8a6b-000000000029"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "title": "About us", "body_html": "

A family-run abaya house in Doha since 2009.

", "custom_page_name": "", "visible": true, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "author": "Docs", "body_html": "

A family-run abaya house in Doha since 2009.

", "created_at": "2026-10-18T09:30:00Z", "custom_page_name": "", "handle": "about-us", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000029", "publish_at": null, "published_at": "2026-10-18T09:30:00Z", "seo_description": "", "seo_title": "", "template_suffix": "", "title": "About us", "updated_at": "2026-10-18T09:30:00Z", "version": 2, "visible": true } ```
## Show, hide or delete many pages POST `/pages/bulk` · Scope: `write_content` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/pages/bulk" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"action": "hide", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000029"]}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/pages/bulk", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"action": "hide", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000029"]}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/pages/bulk", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"action": "hide", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000029"]}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'action' => 'hide', 'ids' => ['0193a1b2-c3d4-7e5f-8a6b-000000000029'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"action": "hide", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000029"]}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/pages/bulk", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/pages/bulk"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"action": "hide", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000029"]} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"ok": true} ```
## Create a blog POST `/blogs` · Scope: `write_content` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/blogs" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"title": "Journal", "comments": "moderated"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/blogs", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"title": "Journal", "comments": "moderated"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/blogs", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"title": "Journal", "comments": "moderated"}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['title' => 'Journal', 'comments' => 'moderated'], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"title": "Journal", "comments": "moderated"}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/blogs", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/blogs"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"title": "Journal", "comments": "moderated"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "articles_count": 0, "comments": "moderated", "created_at": "2026-10-18T09:30:00Z", "handle": "journal", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "seo_description": "", "seo_title": "", "template_suffix": "", "title": "Journal", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## List blogs GET `/blogs` · Scope: `read_content` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/blogs" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/blogs", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/blogs", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/blogs", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/blogs"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "articles_count": 0, "comments": "moderated", "created_at": "2026-10-18T09:30:00Z", "handle": "journal", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "seo_description": "", "seo_title": "", "template_suffix": "", "title": "Journal", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ] } ```
## Update a blog PUT `/blogs/{id}` · Scope: `write_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"title": "Journal", "comments": "disabled", "version": 1}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"title": "Journal", "comments": "disabled", "version": 1}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"title": "Journal", "comments": "disabled", "version": 1}, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['title' => 'Journal', 'comments' => 'disabled', 'version' => 1], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"title": "Journal", "comments": "disabled", "version": 1}` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"title": "Journal", "comments": "disabled", "version": 1} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "articles_count": 0, "comments": "disabled", "created_at": "2026-10-18T09:30:00Z", "handle": "journal", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "seo_description": "", "seo_title": "", "template_suffix": "", "title": "Journal", "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Create a blog post POST `/articles` · Scope: `write_content` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/articles" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Five looks for Eid gatherings, from morning prayers to evening visits.

", "tags": ["eid", "style"], "visible": true }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/articles", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Five looks for Eid gatherings, from morning prayers to evening visits.

", "tags": ["eid", "style"], "visible": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/articles", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Five looks for Eid gatherings, from morning prayers to evening visits.

", "tags": ["eid", "style"], "visible": True, }, ) res.raise_for_status() print(res.json()) ```
```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'blog_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000001', 'title' => 'Dressing for Eid', 'author' => 'Mariam', 'body_html' => '

Five looks for Eid gatherings, from morning prayers to evening visits.

', 'tags' => ['eid', 'style'], 'visible' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Five looks for Eid gatherings, from morning prayers to evening visits.

", "tags": ["eid", "style"], "visible": true }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/articles", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/articles"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Five looks for Eid gatherings, from morning prayers to evening visits.

", "tags": ["eid", "style"], "visible": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "author": "Mariam", "blog_handle": "journal", "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "blog_title": "Journal", "body_html": "

Five looks for Eid gatherings, from morning prayers to evening visits.

", "comments_count": 0, "created_at": "2026-10-18T09:30:00Z", "handle": "dressing-for-eid", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000002", "image_alt": "", "image_asset_id": null, "publish_at": null, "published_at": "2026-10-18T09:30:00Z", "seo_description": "", "seo_title": "", "summary_html": "", "tags": ["eid", "style"], "template_suffix": "", "title": "Dressing for Eid", "updated_at": "2026-10-18T09:30:00Z", "version": 1, "visible": true } ```
## List blog posts GET `/articles` · Scope: `read_content` | Parameter | In | Description | | --- | --- | --- | | `blog_id` | query | An ID, as in the example. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/articles?blog_id=0193a1b2-c3d4-7e5f-8a6b-000000000001" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/articles?blog_id=0193a1b2-c3d4-7e5f-8a6b-000000000001", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/articles?blog_id=0193a1b2-c3d4-7e5f-8a6b-000000000001", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/articles?blog_id=0193a1b2-c3d4-7e5f-8a6b-000000000001", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/articles?blog_id=0193a1b2-c3d4-7e5f-8a6b-000000000001"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "author": "Mariam", "blog_handle": "journal", "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "blog_title": "Journal", "body_html": "

Five looks for Eid gatherings, from morning prayers to evening visits.

", "comments_count": 0, "created_at": "2026-10-18T09:30:00Z", "handle": "dressing-for-eid", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000002", "image_alt": "", "image_asset_id": null, "publish_at": null, "published_at": "2026-10-18T09:30:00Z", "seo_description": "", "seo_title": "", "summary_html": "", "tags": ["eid", "style"], "template_suffix": "", "title": "Dressing for Eid", "updated_at": "2026-10-18T09:30:00Z", "version": 1, "visible": true } ], "total": 1 } ```
## Get a blog post GET `/articles/{id}` · Scope: `read_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "author": "Mariam", "blog_handle": "journal", "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "blog_title": "Journal", "body_html": "

Five looks for Eid gatherings, from morning prayers to evening visits.

", "comments_count": 0, "created_at": "2026-10-18T09:30:00Z", "handle": "dressing-for-eid", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000002", "image_alt": "", "image_asset_id": null, "publish_at": null, "published_at": "2026-10-18T09:30:00Z", "seo_description": "", "seo_title": "", "summary_html": "", "tags": ["eid", "style"], "template_suffix": "", "title": "Dressing for Eid", "updated_at": "2026-10-18T09:30:00Z", "version": 1, "visible": true } ```
## Update a blog post PUT `/articles/{id}` · Scope: `write_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Six looks for Eid gatherings.

", "visible": true, "version": 1 }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Six looks for Eid gatherings.

", "visible": true, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Six looks for Eid gatherings.

", "visible": True, "version": 1, }, ) res.raise_for_status() print(res.json()) ```
```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'blog_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000001', 'title' => 'Dressing for Eid', 'author' => 'Mariam', 'body_html' => '

Six looks for Eid gatherings.

', 'visible' => true, 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Six looks for Eid gatherings.

", "visible": true, "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/articles/0193a1b2-c3d4-7e5f-8a6b-000000000002"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "title": "Dressing for Eid", "author": "Mariam", "body_html": "

Six looks for Eid gatherings.

", "visible": true, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "author": "Mariam", "blog_handle": "journal", "blog_id": "0193a1b2-c3d4-7e5f-8a6b-000000000001", "blog_title": "Journal", "body_html": "

Six looks for Eid gatherings.

", "comments_count": 0, "created_at": "2026-10-18T09:30:00Z", "handle": "dressing-for-eid", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000002", "image_alt": "", "image_asset_id": null, "publish_at": null, "published_at": "2026-10-18T09:30:00Z", "seo_description": "", "seo_title": "", "summary_html": "", "tags": [], "template_suffix": "", "title": "Dressing for Eid", "updated_at": "2026-10-18T09:30:00Z", "version": 2, "visible": true } ```
## Delete many blog posts POST `/articles/bulk` · Scope: `write_content` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/articles/bulk" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"action": "delete", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000002"]}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/articles/bulk", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"action": "delete", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000002"]}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/articles/bulk", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "action": "delete", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000002"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'action' => 'delete', 'ids' => ['0193a1b2-c3d4-7e5f-8a6b-000000000002'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"action": "delete", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000002"]}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/articles/bulk", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/articles/bulk"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"action": "delete", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000002"]} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"ok": true} ```
## Delete a blog and its posts DELETE `/blogs/{id}` · Scope: `write_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/blogs/0193a1b2-c3d4-7e5f-8a6b-000000000001"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Create a navigation menu POST `/menus` · Scope: `write_content` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/menus" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "handle": "eid-menu", "title": "Eid menu", "items": [ { "title": "About us", "type": "page", "ref": "0193a1b2-c3d4-7e5f-8a6b-000000000029" }, {"title": "Size guide", "type": "custom_page", "ref": "size-guide"}, {"title": "Shop all", "type": "url", "url": "/collections/all"} ] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/menus", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "handle": "eid-menu", "title": "Eid menu", "items": [ { "title": "About us", "type": "page", "ref": "0193a1b2-c3d4-7e5f-8a6b-000000000029" }, {"title": "Size guide", "type": "custom_page", "ref": "size-guide"}, {"title": "Shop all", "type": "url", "url": "/collections/all"} ] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/menus", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "handle": "eid-menu", "title": "Eid menu", "items": [ { "title": "About us", "type": "page", "ref": "0193a1b2-c3d4-7e5f-8a6b-000000000029", }, { "title": "Size guide", "type": "custom_page", "ref": "size-guide", }, { "title": "Shop all", "type": "url", "url": "/collections/all", }, ], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'handle' => 'eid-menu', 'title' => 'Eid menu', 'items' => [ [ 'title' => 'About us', 'type' => 'page', 'ref' => '0193a1b2-c3d4-7e5f-8a6b-000000000029', ], [ 'title' => 'Size guide', 'type' => 'custom_page', 'ref' => 'size-guide', ], [ 'title' => 'Shop all', 'type' => 'url', 'url' => '/collections/all', ], ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "handle": "eid-menu", "title": "Eid menu", "items": [ { "title": "About us", "type": "page", "ref": "0193a1b2-c3d4-7e5f-8a6b-000000000029" }, {"title": "Size guide", "type": "custom_page", "ref": "size-guide"}, {"title": "Shop all", "type": "url", "url": "/collections/all"} ] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/menus", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/menus"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "handle": "eid-menu", "title": "Eid menu", "items": [ { "title": "About us", "type": "page", "ref": "0193a1b2-c3d4-7e5f-8a6b-000000000029" }, {"title": "Size guide", "type": "custom_page", "ref": "size-guide"}, {"title": "Shop all", "type": "url", "url": "/collections/all"} ] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "handle": "eid-menu", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000027", "items": [ { "href": "/pages/about-us", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000028", "items": [], "ref": "0193a1b2-c3d4-7e5f-8a6b-000000000029", "title": "About us", "type": "page" }, { "href": "/custom/size-guide", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000030", "items": [], "ref": "size-guide", "title": "Size guide", "type": "custom_page" } ], "title": "Eid menu", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## List navigation menus GET `/menus` · Scope: `read_content` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/menus" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/menus", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/menus", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/menus", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/menus"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "handle": "eid-menu", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000027", "items": [ { "href": "/pages/about-us", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000028", "items": [], "ref": "0193a1b2-c3d4-7e5f-8a6b-000000000029", "title": "About us", "type": "page" }, { "href": "/custom/size-guide", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000030", "items": [], "ref": "size-guide", "title": "Size guide", "type": "custom_page" } ], "title": "Eid menu", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ] } ```
## Get a navigation menu GET `/menus/{id}` · Scope: `read_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "handle": "eid-menu", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000027", "items": [ { "href": "/pages/about-us", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000028", "items": [], "ref": "0193a1b2-c3d4-7e5f-8a6b-000000000029", "title": "About us", "type": "page" }, { "href": "/custom/size-guide", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000030", "items": [], "ref": "size-guide", "title": "Size guide", "type": "custom_page" } ], "title": "Eid menu", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## Update a navigation menu PUT `/menus/{id}` · Scope: `write_content` Item types: url, page, collection, product, blog, article, policy, custom_page, home, catalog, search; ref is the resource ID (or the policy kind, or the custom page name). | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "handle": "eid-menu", "title": "Eid menu", "items": [{"title": "Shop all", "type": "url", "url": "/collections/all"}], "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "handle": "eid-menu", "title": "Eid menu", "items": [{"title": "Shop all", "type": "url", "url": "/collections/all"}], "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "handle": "eid-menu", "title": "Eid menu", "items": [ { "title": "Shop all", "type": "url", "url": "/collections/all", }, ], "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'handle' => 'eid-menu', 'title' => 'Eid menu', 'items' => [ [ 'title' => 'Shop all', 'type' => 'url', 'url' => '/collections/all', ], ], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "handle": "eid-menu", "title": "Eid menu", "items": [{"title": "Shop all", "type": "url", "url": "/collections/all"}], "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "handle": "eid-menu", "title": "Eid menu", "items": [{"title": "Shop all", "type": "url", "url": "/collections/all"}], "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "handle": "eid-menu", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000027", "items": [ { "href": "/collections/all", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000064", "items": [], "title": "Shop all", "type": "url", "url": "/collections/all" } ], "title": "Eid menu", "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Delete a navigation menu DELETE `/menus/{id}` · Scope: `write_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/menus/0193a1b2-c3d4-7e5f-8a6b-000000000027"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## List store policies GET `/policies` · Scope: `read_content` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/policies" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/policies", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/policies", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/policies", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/policies"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "body_html": "

You can return unused items in their original condition within 14 days of delivery. To start a return, contact us at .

Once we receive and inspect the return, we refund the original payment method within 5–10 business days. Cash on delivery orders are refunded by bank transfer or store cr…", "handle": "refund-policy", "kind": "refund", "title": "Refund policy", "updated_at": "2026-10-18T09:30:00Z", "version": 1 }, { "body_html": "

Shop collects what we need to fulfil your order: your name, contact details, address and order history. We don't store card details; payments are handled by our payment provider.

We use your information to deliver orders and contact you, and for marketing only if you agreed to it. You can a…", "handle": "privacy-policy", "kind": "privacy", "title": "Privacy policy", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ] } ```

## Update a store policy PUT `/policies/{kind}` · Scope: `write_content` kind: refund, privacy, terms, shipping, contact or legal. | Parameter | In | Description | | --- | --- | --- | | `kind` | path | The kind ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/policies/refund" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Refund policy", "body_html": "

Unworn items can be returned within 14 days of delivery.

", "version": 1 }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/policies/refund", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "title": "Refund policy", "body_html": "

Unworn items can be returned within 14 days of delivery.

", "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/policies/refund", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "title": "Refund policy", "body_html": "

Unworn items can be returned within 14 days of delivery.

", "version": 1, }, ) res.raise_for_status() print(res.json()) ```
```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'title' => 'Refund policy', 'body_html' => '

Unworn items can be returned within 14 days of delivery.

', 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "title": "Refund policy", "body_html": "

Unworn items can be returned within 14 days of delivery.

", "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/policies/refund", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/policies/refund"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "title": "Refund policy", "body_html": "

Unworn items can be returned within 14 days of delivery.

", "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
## Create a URL redirect POST `/redirects` · Scope: `write_content` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/redirects" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"path": "/abayas-old", "target": "/collections/abayas", "kind": 301}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/redirects", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"path": "/abayas-old", "target": "/collections/abayas", "kind": 301}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/redirects", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "path": "/abayas-old", "target": "/collections/abayas", "kind": 301, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'path' => '/abayas-old', 'target' => '/collections/abayas', 'kind' => 301, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"path": "/abayas-old", "target": "/collections/abayas", "kind": 301}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/redirects", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/redirects"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"path": "/abayas-old", "target": "/collections/abayas", "kind": 301} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "automatic": false, "created_at": "2026-10-18T09:30:00Z", "force": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000043", "kind": 301, "path": "/abayas-old", "target": "/collections/abayas", "updated_at": "2026-10-18T09:30:00Z" } ```
## List URL redirects GET `/redirects` · Scope: `read_content` | Parameter | In | Description | | --- | --- | --- | | `q` | query | For example `abayas`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/redirects?q=abayas" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/redirects?q=abayas", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/redirects?q=abayas", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/redirects?q=abayas", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/redirects?q=abayas"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "automatic": false, "created_at": "2026-10-18T09:30:00Z", "force": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000043", "kind": 301, "path": "/abayas-old", "target": "/collections/abayas", "updated_at": "2026-10-18T09:30:00Z" } ], "total": 1 } ```
## Update a URL redirect PUT `/redirects/{id}` · Scope: `write_content` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/redirects/0193a1b2-c3d4-7e5f-8a6b-000000000043" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"path": "/abayas-old", "target": "/collections/eid-edit", "kind": 301}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/redirects/0193a1b2-c3d4-7e5f-8a6b-000000000043", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"path": "/abayas-old", "target": "/collections/eid-edit", "kind": 301}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/redirects/0193a1b2-c3d4-7e5f-8a6b-000000000043", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "path": "/abayas-old", "target": "/collections/eid-edit", "kind": 301, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'path' => '/abayas-old', 'target' => '/collections/eid-edit', 'kind' => 301, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"path": "/abayas-old", "target": "/collections/eid-edit", "kind": 301}` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/redirects/0193a1b2-c3d4-7e5f-8a6b-000000000043", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/redirects/0193a1b2-c3d4-7e5f-8a6b-000000000043"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"path": "/abayas-old", "target": "/collections/eid-edit", "kind": 301} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "automatic": false, "created_at": "2026-10-18T09:30:00Z", "force": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000043", "kind": 301, "path": "/abayas-old", "target": "/collections/eid-edit", "updated_at": "2026-10-18T09:30:00Z" } ```
## Delete URL redirects POST `/redirects/delete` · Scope: `write_content` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/redirects/delete" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000043"]}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/redirects/delete", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000043"]}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/redirects/delete", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000043"]}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['ids' => ['0193a1b2-c3d4-7e5f-8a6b-000000000043']], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000043"]}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/redirects/delete", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/redirects/delete"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000043"]} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"deleted": 1} ```
--- # Customers URL: https://sooquna.com/docs/api/admin/customers > Admin API 2026-10: Customers, their addresses and segments (contact details need read_customer_pii). {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Customers, their addresses and segments (contact details need read_customer_pii). Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Create a customer](#create-a-customer) | POST | `/customers` | | [List customers](#list-customers) | GET | `/customers` | | [Count customers](#count-customers) | GET | `/customers/count` | | [List customer tags](#list-customer-tags) | GET | `/customers/tags` | | [Get a customer](#get-a-customer) | GET | `/customers/{id}` | | [Update a customer](#update-a-customer) | PATCH | `/customers/{id}` | | [Add an address](#add-an-address) | POST | `/customers/{id}/addresses` | | [Update an address](#update-an-address) | PATCH | `/customers/{id}/addresses/{address_id}` | | [Make an address the default](#make-an-address-the-default) | POST | `/customers/{id}/addresses/{address_id}/default` | | [Delete an address](#delete-an-address) | DELETE | `/customers/{id}/addresses/{address_id}` | | [Change marketing consent](#change-marketing-consent) | PUT | `/customers/{id}/marketing` | | [List a customer's consent history](#list-a-customer-s-consent-history) | GET | `/customers/{id}/consents` | | [List a customer's orders](#list-a-customer-s-orders) | GET | `/customers/{id}/orders` | | [Invite a customer to create an account](#invite-a-customer-to-create-an-account) | POST | `/customers/{id}/send-invite` | | [Tag or delete many customers](#tag-or-delete-many-customers) | POST | `/customers/bulk` | | [Create a customer segment](#create-a-customer-segment) | POST | `/segments` | | [List customer segments](#list-customer-segments) | GET | `/segments` | | [List the fields segment queries can use](#list-the-fields-segment-queries-can-use) | GET | `/segments/fields` | | [Get a segment](#get-a-segment) | GET | `/segments/{id}` | | [Update a segment](#update-a-segment) | PUT | `/segments/{id}` | | [Delete a segment](#delete-a-segment) | DELETE | `/segments/{id}` | | [Delete a customer](#delete-a-customer) | DELETE | `/customers/{id}` | ## Create a customer POST `/customers` · Scope: `write_customers` · Needs an `Idempotency-Key` header ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/customers" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "first_name": "Noora", "last_name": "Al-Kuwari", "email": "noora@example.com", "phone": "+97455123456", "locale": "ar", "tags": ["vip"], "email_marketing": {"state": "subscribed", "opt_in_level": "single_opt_in"}, "addresses": [ { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456", "default": true } ] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "first_name": "Noora", "last_name": "Al-Kuwari", "email": "noora@example.com", "phone": "+97455123456", "locale": "ar", "tags": ["vip"], "email_marketing": {"state": "subscribed", "opt_in_level": "single_opt_in"}, "addresses": [ { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456", "default": true } ] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/customers", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "first_name": "Noora", "last_name": "Al-Kuwari", "email": "noora@example.com", "phone": "+97455123456", "locale": "ar", "tags": ["vip"], "email_marketing": {"state": "subscribed", "opt_in_level": "single_opt_in"}, "addresses": [ { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456", "default": True, }, ], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'first_name' => 'Noora', 'last_name' => 'Al-Kuwari', 'email' => 'noora@example.com', 'phone' => '+97455123456', 'locale' => 'ar', 'tags' => ['vip'], 'email_marketing' => ['state' => 'subscribed', 'opt_in_level' => 'single_opt_in'], 'addresses' => [ [ 'first_name' => 'Noora', 'last_name' => 'Al-Kuwari', 'address1' => 'Zone 66, Street 801, Building 12', 'city' => 'Doha', 'country_code' => 'QA', 'phone' => '+97455123456', 'default' => true, ], ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "first_name": "Noora", "last_name": "Al-Kuwari", "email": "noora@example.com", "phone": "+97455123456", "locale": "ar", "tags": ["vip"], "email_marketing": {"state": "subscribed", "opt_in_level": "single_opt_in"}, "addresses": [ { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456", "default": true } ] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/customers", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/customers"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "first_name": "Noora", "last_name": "Al-Kuwari", "email": "noora@example.com", "phone": "+97455123456", "locale": "ar", "tags": ["vip"], "email_marketing": {"state": "subscribed", "opt_in_level": "single_opt_in"}, "addresses": [ { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456", "default": true } ] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "accepts_email_marketing": true, "accepts_sms_marketing": false, "addresses": [ { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000006", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" } ], "amount_spent": "0.00", "average_order_value": "0.00", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "default_address": { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000006", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" }, "display_name": "Noora Al-Kuwari", "email": "noora@example.com", "email_marketing": { "opt_in_level": "single_opt_in", "state": "subscribed", "updated_at": "2026-10-18T09:30:00Z" }, "first_name": "Noora", "first_order_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "last_name": "Al-Kuwari", "last_order_at": null, "locale": "ar", "note": "", "orders_count": 0, "phone": "+97455123456", "pii_masked": false, "sms_marketing": { "opt_in_level": "single_opt_in", "state": "not_subscribed", "updated_at": null }, "state": "enabled", "tags": ["vip"], "tax_exempt": false, "tax_exemptions": [], "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## List customers GET `/customers` · Scope: `read_customers` | Parameter | In | Description | | --- | --- | --- | | `q` | query | For example `noora`. | | `limit` | query | For example `10`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/customers?q=noora&limit=10" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers?q=noora&limit=10", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/customers?q=noora&limit=10", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/customers?q=noora&limit=10", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/customers?q=noora&limit=10"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "accepts_email_marketing": true, "accepts_sms_marketing": false, "amount_spent": "0.00", "average_order_value": "0.00", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "default_address": { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000006", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" }, "display_name": "Noora Al-Kuwari", "email": "noora@example.com", "email_marketing": { "opt_in_level": "single_opt_in", "state": "subscribed", "updated_at": "2026-10-18T09:30:00Z" }, "first_name": "Noora", "first_order_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "last_name": "Al-Kuwari", "last_order_at": null, "locale": "ar", "note": "", "orders_count": 0, "phone": "+97455123456", "pii_masked": false, "sms_marketing": { "opt_in_level": "single_opt_in", "state": "not_subscribed", "updated_at": null }, "state": "enabled", "tags": ["vip"], "tax_exempt": false, "tax_exemptions": [], "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ], "page_info": {"has_next_page": false} } ```
## Count customers GET `/customers/count` · Scope: `read_customers` | Parameter | In | Description | | --- | --- | --- | | `tag` | query | For example `vip`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/customers/count?tag=vip" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/count?tag=vip", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/customers/count?tag=vip", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/customers/count?tag=vip", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/customers/count?tag=vip"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"count": 1} ```
## List customer tags GET `/customers/tags` · Scope: `read_customers` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/customers/tags" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/tags", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/customers/tags", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/customers/tags", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/customers/tags"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": [{"customers": 1, "tag": "vip"}]} ```
## Get a customer GET `/customers/{id}` · Scope: `read_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "accepts_email_marketing": true, "accepts_sms_marketing": false, "addresses": [ { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000006", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" } ], "amount_spent": "0.00", "average_order_value": "0.00", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "default_address": { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000006", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" }, "display_name": "Noora Al-Kuwari", "email": "noora@example.com", "email_marketing": { "opt_in_level": "single_opt_in", "state": "subscribed", "updated_at": "2026-10-18T09:30:00Z" }, "first_name": "Noora", "first_order_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "last_name": "Al-Kuwari", "last_order_at": null, "locale": "ar", "note": "", "orders_count": 0, "phone": "+97455123456", "pii_masked": false, "sms_marketing": { "opt_in_level": "single_opt_in", "state": "not_subscribed", "updated_at": null }, "state": "enabled", "tags": ["vip"], "tax_exempt": false, "tax_exemptions": [], "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Update a customer PATCH `/customers/{id}` · Scope: `write_customers` Fields you leave out stay as they are. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "note": "Prefers delivery after Maghrib", "tags": ["vip", "abaya"], "version": 2 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "note": "Prefers delivery after Maghrib", "tags": ["vip", "abaya"], "version": 2 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "note": "Prefers delivery after Maghrib", "tags": ["vip", "abaya"], "version": 2, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'note' => 'Prefers delivery after Maghrib', 'tags' => ['vip', 'abaya'], 'version' => 2, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "note": "Prefers delivery after Maghrib", "tags": ["vip", "abaya"], "version": 2 }` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "note": "Prefers delivery after Maghrib", "tags": ["vip", "abaya"], "version": 2 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "accepts_email_marketing": true, "accepts_sms_marketing": false, "addresses": [ { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000006", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" } ], "amount_spent": "0.00", "average_order_value": "0.00", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "default_address": { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000006", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" }, "display_name": "Noora Al-Kuwari", "email": "noora@example.com", "email_marketing": { "opt_in_level": "single_opt_in", "state": "subscribed", "updated_at": "2026-10-18T09:30:00Z" }, "first_name": "Noora", "first_order_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "last_name": "Al-Kuwari", "last_order_at": null, "locale": "ar", "note": "Prefers delivery after Maghrib", "orders_count": 0, "phone": "+97455123456", "pii_masked": false, "sms_marketing": { "opt_in_level": "single_opt_in", "state": "not_subscribed", "updated_at": null }, "state": "enabled", "tags": ["abaya", "vip"], "tax_exempt": false, "tax_exemptions": [], "updated_at": "2026-10-18T09:30:00Z", "version": 3 } ```
## Add an address POST `/customers/{id}/addresses` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1204", "city": "Lusail", "country_code": "QA", "phone": "+97455123456" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1204", "city": "Lusail", "country_code": "QA", "phone": "+97455123456" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1204", "city": "Lusail", "country_code": "QA", "phone": "+97455123456", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'first_name' => 'Noora', 'last_name' => 'Al-Kuwari', 'address1' => 'Lusail Marina, Tower 3, Apt 1204', 'city' => 'Lusail', 'country_code' => 'QA', 'phone' => '+97455123456', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1204", "city": "Lusail", "country_code": "QA", "phone": "+97455123456" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1204", "city": "Lusail", "country_code": "QA", "phone": "+97455123456" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "address1": "Lusail Marina, Tower 3, Apt 1204", "address2": "", "city": "Lusail", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000049", "is_default": false, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" } ```
## Update an address PATCH `/customers/{id}/addresses/{address_id}` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `address_id` | path | The address ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1205", "city": "Lusail", "country_code": "QA" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1205", "city": "Lusail", "country_code": "QA" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1205", "city": "Lusail", "country_code": "QA", }, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'first_name' => 'Noora', 'last_name' => 'Al-Kuwari', 'address1' => 'Lusail Marina, Tower 3, Apt 1205', 'city' => 'Lusail', 'country_code' => 'QA', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1205", "city": "Lusail", "country_code": "QA" }` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Lusail Marina, Tower 3, Apt 1205", "city": "Lusail", "country_code": "QA" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "address1": "Lusail Marina, Tower 3, Apt 1205", "address2": "", "city": "Lusail", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000049", "is_default": false, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" } ```
## Make an address the default POST `/customers/{id}/addresses/{address_id}/default` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `address_id` | path | The address ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049/default" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049/default", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049/default", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049/default", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049/default"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Delete an address DELETE `/customers/{id}/addresses/{address_id}` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `address_id` | path | The address ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/addresses/0193a1b2-c3d4-7e5f-8a6b-000000000049"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Change marketing consent PUT `/customers/{id}/marketing` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/marketing" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "email": {"state": "subscribed", "opt_in_level": "confirmed_opt_in"}, "sms": {"state": "unsubscribed"} }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/marketing", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "email": {"state": "subscribed", "opt_in_level": "confirmed_opt_in"}, "sms": {"state": "unsubscribed"} }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/marketing", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "email": {"state": "subscribed", "opt_in_level": "confirmed_opt_in"}, "sms": {"state": "unsubscribed"}, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'email' => ['state' => 'subscribed', 'opt_in_level' => 'confirmed_opt_in'], 'sms' => ['state' => 'unsubscribed'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "email": {"state": "subscribed", "opt_in_level": "confirmed_opt_in"}, "sms": {"state": "unsubscribed"} }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/marketing", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/marketing"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "email": {"state": "subscribed", "opt_in_level": "confirmed_opt_in"}, "sms": {"state": "unsubscribed"} } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "accepts_email_marketing": true, "accepts_sms_marketing": false, "addresses": [ { "address1": "Lusail Marina, Tower 3, Apt 1205", "address2": "", "city": "Lusail", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000049", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" }, { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000006", "is_default": false, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" } ], "amount_spent": "0.00", "average_order_value": "0.00", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "default_address": { "address1": "Lusail Marina, Tower 3, Apt 1205", "address2": "", "city": "Lusail", "company": "", "country_code": "QA", "extra": {}, "first_name": "Noora", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000049", "is_default": true, "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" }, "display_name": "Noora Al-Kuwari", "email": "noora@example.com", "email_marketing": { "opt_in_level": "confirmed_opt_in", "state": "subscribed", "updated_at": "2026-10-18T09:30:00Z" }, "first_name": "Noora", "first_order_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "last_name": "Al-Kuwari", "last_order_at": null, "locale": "ar", "note": "Prefers delivery after Maghrib", "orders_count": 0, "phone": "+97455123456", "pii_masked": false, "sms_marketing": { "opt_in_level": "single_opt_in", "state": "unsubscribed", "updated_at": "2026-10-18T09:30:00Z" }, "state": "enabled", "tags": ["abaya", "vip"], "tax_exempt": false, "tax_exemptions": [], "updated_at": "2026-10-18T09:30:00Z", "version": 6 } ```
## List a customer's consent history GET `/customers/{id}/consents` · Scope: `read_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/consents" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/consents", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/consents", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/consents", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/consents"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "actor": "Docs", "channel": "email", "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000008", "opt_in_level": "confirmed_opt_in", "source": "admin", "state": "subscribed" }, { "actor": "Docs", "channel": "sms", "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000009", "opt_in_level": "single_opt_in", "source": "admin", "state": "unsubscribed" } ] } ```
## List a customer's orders GET `/customers/{id}/orders` · Scope: `read_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/orders" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/orders", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/orders", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/orders", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/orders"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Invite a customer to create an account POST `/customers/{id}/send-invite` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/send-invite" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/send-invite", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/send-invite", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/send-invite", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007/send-invite"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Tag or delete many customers POST `/customers/bulk` · Scope: `write_customers` Actions: add_tags, remove_tags, delete. ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/customers/bulk" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "add_tags", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000007"], "tags": ["ramadan-2026"] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/bulk", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "action": "add_tags", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000007"], "tags": ["ramadan-2026"] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/customers/bulk", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "action": "add_tags", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000007"], "tags": ["ramadan-2026"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'action' => 'add_tags', 'ids' => ['0193a1b2-c3d4-7e5f-8a6b-000000000007'], 'tags' => ['ramadan-2026'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "action": "add_tags", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000007"], "tags": ["ramadan-2026"] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/customers/bulk", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/customers/bulk"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "action": "add_tags", "ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000007"], "tags": ["ramadan-2026"] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"skipped": 0, "updated": 1} ```
## Create a customer segment POST `/segments` · Scope: `write_customers` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/segments" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Big spenders", "query": "amount_spent > 500"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/segments", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"name": "Big spenders", "query": "amount_spent > 500"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/segments", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"name": "Big spenders", "query": "amount_spent > 500"}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['name' => 'Big spenders', 'query' => 'amount_spent > 500'], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"name": "Big spenders", "query": "amount_spent > 500"}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/segments", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/segments"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"name": "Big spenders", "query": "amount_spent > 500"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "count": 0, "counted_at": "2026-10-18T09:30:00Z", "created_at": "2026-10-18T09:30:00Z", "default_key": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000044", "materialized_at": null, "name": "Big spenders", "query": "amount_spent > 500", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## List customer segments GET `/segments` · Scope: `read_customers` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/segments" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/segments", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/segments", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/segments", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/segments"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "count": 0, "counted_at": "2026-10-18T09:30:00Z", "created_at": "2026-10-18T09:30:00Z", "default_key": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000044", "materialized_at": null, "name": "Big spenders", "query": "amount_spent > 500", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ] } ```
## List the fields segment queries can use GET `/segments/fields` · Scope: `read_customers` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/segments/fields" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/segments/fields", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/segments/fields", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/segments/fields", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/segments/fields"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "available": false, "description": { "ar": "تتوفر البيانات عند إطلاق الدفع.", "en": "Fills in once checkout launches." }, "example": "abandoned_checkout_date > -30d", "label": {"ar": "تاريخ السلة المتروكة", "en": "Abandoned checkout date"}, "name": "abandoned_checkout_date", "operators": ["=", ">"], "type": "date" }, { "available": true, "description": { "ar": "إجمالي الإنفاق بعملة المتجر.", "en": "Total spent, in the store currency." }, "example": "amount_spent > 500", "label": {"ar": "المبلغ المنفق", "en": "Amount spent"}, "name": "amount_spent", "operators": ["=", "!="], "type": "money" } ] } ```
## Get a segment GET `/segments/{id}` · Scope: `read_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "count": 0, "counted_at": "2026-10-18T09:30:00Z", "created_at": "2026-10-18T09:30:00Z", "default_key": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000044", "materialized_at": null, "name": "Big spenders", "query": "amount_spent > 500", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## Update a segment PUT `/segments/{id}` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Big spenders", "query": "amount_spent > 1000", "version": 1}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"name": "Big spenders", "query": "amount_spent > 1000", "version": 1}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "name": "Big spenders", "query": "amount_spent > 1000", "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'name' => 'Big spenders', 'query' => 'amount_spent > 1000', 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"name": "Big spenders", "query": "amount_spent > 1000", "version": 1}` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"name": "Big spenders", "query": "amount_spent > 1000", "version": 1} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "count": 0, "counted_at": "2026-10-18T09:30:00Z", "created_at": "2026-10-18T09:30:00Z", "default_key": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000044", "materialized_at": null, "name": "Big spenders", "query": "amount_spent > 1000", "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Delete a segment DELETE `/segments/{id}` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/segments/0193a1b2-c3d4-7e5f-8a6b-000000000044"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Delete a customer DELETE `/customers/{id}` · Scope: `write_customers` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/customers/0193a1b2-c3d4-7e5f-8a6b-000000000007"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Discounts URL: https://sooquna.com/docs/api/admin/discounts > Admin API 2026-10: Discounts and discount codes. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Discounts and discount codes. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Create a discount](#create-a-discount) | POST | `/discounts` | | [List discounts](#list-discounts) | GET | `/discounts` | | [Find a discount by code](#find-a-discount-by-code) | GET | `/discounts/lookup` | | [Get a discount](#get-a-discount) | GET | `/discounts/{id}` | | [Update a discount](#update-a-discount) | PUT | `/discounts/{id}` | | [Add codes to a discount](#add-codes-to-a-discount) | POST | `/discounts/{id}/codes` | | [Generate unique codes](#generate-unique-codes) | POST | `/discounts/{id}/codes/generate` | | [List a discount's codes](#list-a-discount-s-codes) | GET | `/discounts/{id}/codes` | | [Delete a code](#delete-a-code) | DELETE | `/discounts/{id}/codes/{code_id}` | | [List a discount's redemptions](#list-a-discount-s-redemptions) | GET | `/discounts/{id}/redemptions` | | [Duplicate a discount](#duplicate-a-discount) | POST | `/discounts/{id}/duplicate` | | [End a discount now](#end-a-discount-now) | POST | `/discounts/{id}/deactivate` | | [Start a discount now](#start-a-discount-now) | POST | `/discounts/{id}/activate` | | [Delete a discount](#delete-a-discount) | DELETE | `/discounts/{id}` | ## Create a discount POST `/discounts` · Scope: `write_discounts` method code or automatic; type order, product, shipping or bxgy; value_type percentage or fixed_amount. ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/discounts" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "min_requirement": {"type": "amount", "amount": "200.00"}, "combines_with": {"shipping": true}, "once_per_customer": true, "starts_at": "2026-03-18T00:00:00Z", "ends_at": "2026-03-23T23:59:59Z" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "min_requirement": {"type": "amount", "amount": "200.00"}, "combines_with": {"shipping": true}, "once_per_customer": true, "starts_at": "2026-03-18T00:00:00Z", "ends_at": "2026-03-23T23:59:59Z" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/discounts", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "min_requirement": {"type": "amount", "amount": "200.00"}, "combines_with": {"shipping": True}, "once_per_customer": True, "starts_at": "2026-03-18T00:00:00Z", "ends_at": "2026-03-23T23:59:59Z", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'method' => 'code', 'type' => 'order', 'code' => 'EID10', 'title' => 'Eid 10% off', 'value_type' => 'percentage', 'value' => '10', 'min_requirement' => ['type' => 'amount', 'amount' => '200.00'], 'combines_with' => ['shipping' => true], 'once_per_customer' => true, 'starts_at' => '2026-03-18T00:00:00Z', 'ends_at' => '2026-03-23T23:59:59Z', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "min_requirement": {"type": "amount", "amount": "200.00"}, "combines_with": {"shipping": true}, "once_per_customer": true, "starts_at": "2026-03-18T00:00:00Z", "ends_at": "2026-03-23T23:59:59Z" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/discounts", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/discounts"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "min_requirement": {"type": "amount", "amount": "200.00"}, "combines_with": {"shipping": true}, "once_per_customer": true, "starts_at": "2026-03-18T00:00:00Z", "ends_at": "2026-03-23T23:59:59Z" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "applies_to": { "all": true, "collection_ids": [], "exclude_sale_items": false, "once_per_order": false, "product_ids": [], "variant_ids": [] }, "code": "EID10", "codes_count": 1, "combines_with": {"order": false, "product": false, "shipping": true}, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer_eligibility": {"all": true, "customer_ids": [], "segment_ids": []}, "ends_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000010", "method": "code", "min_requirement": {"amount": "200.00", "type": "amount"}, "once_per_customer": true, "shipping": {"countries": [], "max_rate": null}, "starts_at": "2026-10-18T09:30:00Z", "status": "expired", "title": "Eid 10% off", "type": "order", "updated_at": "2026-10-18T09:30:00Z", "usage_count": 0, "usage_limit": null, "value": "10", "value_type": "percentage", "version": 1 } ```
## List discounts GET `/discounts` · Scope: `read_discounts` | Parameter | In | Description | | --- | --- | --- | | `status` | query | For example `scheduled`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/discounts?status=scheduled" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts?status=scheduled", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/discounts?status=scheduled", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/discounts?status=scheduled", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/discounts?status=scheduled"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": [], "page_info": {"has_next_page": false}} ```
## Find a discount by code GET `/discounts/lookup` · Scope: `read_discounts` | Parameter | In | Description | | --- | --- | --- | | `code` | query | For example `EID10`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/discounts/lookup?code=EID10" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/lookup?code=EID10", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/discounts/lookup?code=EID10", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/discounts/lookup?code=EID10", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/discounts/lookup?code=EID10"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "applies_to": { "all": true, "collection_ids": [], "exclude_sale_items": false, "once_per_order": false, "product_ids": [], "variant_ids": [] }, "code": "EID10", "codes_count": 1, "combines_with": {"order": false, "product": false, "shipping": true}, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer_eligibility": {"all": true, "customer_ids": [], "segment_ids": []}, "ends_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000010", "method": "code", "min_requirement": {"amount": "200.00", "type": "amount"}, "once_per_customer": true, "shipping": {"countries": [], "max_rate": null}, "starts_at": "2026-10-18T09:30:00Z", "status": "expired", "title": "Eid 10% off", "type": "order", "updated_at": "2026-10-18T09:30:00Z", "usage_count": 0, "usage_limit": null, "value": "10", "value_type": "percentage", "version": 1 } ```
## Get a discount GET `/discounts/{id}` · Scope: `read_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "applies_to": { "all": true, "collection_ids": [], "exclude_sale_items": false, "once_per_order": false, "product_ids": [], "variant_ids": [] }, "code": "EID10", "codes_count": 1, "combines_with": {"order": false, "product": false, "shipping": true}, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer_eligibility": {"all": true, "customer_ids": [], "segment_ids": []}, "ends_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000010", "method": "code", "min_requirement": {"amount": "200.00", "type": "amount"}, "once_per_customer": true, "shipping": {"countries": [], "max_rate": null}, "starts_at": "2026-10-18T09:30:00Z", "status": "expired", "title": "Eid 10% off", "type": "order", "updated_at": "2026-10-18T09:30:00Z", "usage_count": 0, "usage_limit": null, "value": "10", "value_type": "percentage", "version": 1 } ```
## Update a discount PUT `/discounts/{id}` · Scope: `write_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "usage_limit": 500, "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "usage_limit": 500, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "usage_limit": 500, "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'method' => 'code', 'type' => 'order', 'code' => 'EID10', 'title' => 'Eid 10% off', 'value_type' => 'percentage', 'value' => '10', 'usage_limit' => 500, 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "usage_limit": 500, "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "method": "code", "type": "order", "code": "EID10", "title": "Eid 10% off", "value_type": "percentage", "value": "10", "usage_limit": 500, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "applies_to": { "all": true, "collection_ids": [], "exclude_sale_items": false, "once_per_order": false, "product_ids": [], "variant_ids": [] }, "code": "EID10", "codes_count": 1, "combines_with": {"order": false, "product": false, "shipping": false}, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer_eligibility": {"all": true, "customer_ids": [], "segment_ids": []}, "ends_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000010", "method": "code", "min_requirement": {"type": "none"}, "once_per_customer": false, "shipping": {"countries": [], "max_rate": null}, "starts_at": "2026-10-18T09:30:00Z", "status": "active", "title": "Eid 10% off", "type": "order", "updated_at": "2026-10-18T09:30:00Z", "usage_count": 0, "usage_limit": 500, "value": "10", "value_type": "percentage", "version": 2 } ```
## Add codes to a discount POST `/discounts/{id}/codes` · Scope: `write_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"codes": ["EID10-VIP", "EID10-STAFF"]}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"codes": ["EID10-VIP", "EID10-STAFF"]}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"codes": ["EID10-VIP", "EID10-STAFF"]}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['codes' => ['EID10-VIP', 'EID10-STAFF']], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"codes": ["EID10-VIP", "EID10-STAFF"]}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"codes": ["EID10-VIP", "EID10-STAFF"]} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json {"added": 2} ```
## Generate unique codes POST `/discounts/{id}/codes/generate` · Scope: `write_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/generate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"count": 50, "prefix": "EID-", "length": 8}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/generate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"count": 50, "prefix": "EID-", "length": 8}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/generate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"count": 50, "prefix": "EID-", "length": 8}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['count' => 50, 'prefix' => 'EID-', 'length' => 8], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"count": 50, "prefix": "EID-", "length": 8}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/generate", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/generate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"count": 50, "prefix": "EID-", "length": 8} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json {"added": 50} ```
## List a discount's codes GET `/discounts/{id}/codes` · Scope: `read_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `q` | query | For example `EID10`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes?q=EID10" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes?q=EID10", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes?q=EID10", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes?q=EID10", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes?q=EID10"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "code": "EID10", "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000011", "usage_count": 0 }, { "code": "EID10-STAFF", "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000012", "usage_count": 0 } ], "total": 53 } ```
## Delete a code DELETE `/discounts/{id}/codes/{code_id}` · Scope: `write_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `code_id` | path | The code ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/0193a1b2-cca6-7dfb-8a6f-306035bfda1c" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/0193a1b2-cca6-7dfb-8a6f-306035bfda1c", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/0193a1b2-cca6-7dfb-8a6f-306035bfda1c", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/0193a1b2-cca6-7dfb-8a6f-306035bfda1c", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/codes/0193a1b2-cca6-7dfb-8a6f-306035bfda1c"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List a discount's redemptions GET `/discounts/{id}/redemptions` · Scope: `read_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/redemptions" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/redemptions", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/redemptions", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/redemptions", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/redemptions"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
## Duplicate a discount POST `/discounts/{id}/duplicate` · Scope: `write_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/duplicate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/duplicate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/duplicate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/duplicate", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000010/duplicate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "applies_to": { "all": true, "collection_ids": [], "exclude_sale_items": false, "once_per_order": false, "product_ids": [], "variant_ids": [] }, "code": "NGT2NMQSV8", "codes_count": 1, "combines_with": {"order": false, "product": false, "shipping": false}, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer_eligibility": {"all": true, "customer_ids": [], "segment_ids": []}, "ends_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000052", "method": "code", "min_requirement": {"type": "none"}, "once_per_customer": false, "shipping": {"countries": [], "max_rate": null}, "starts_at": "2026-10-18T09:30:00Z", "status": "active", "title": "NGT2NMQSV8", "type": "order", "updated_at": "2026-10-18T09:30:00Z", "usage_count": 0, "usage_limit": 500, "value": "10", "value_type": "percentage", "version": 1 } ```
## End a discount now POST `/discounts/{id}/deactivate` · Scope: `write_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/deactivate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/deactivate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/deactivate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/deactivate", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/deactivate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "applies_to": { "all": true, "collection_ids": [], "exclude_sale_items": false, "once_per_order": false, "product_ids": [], "variant_ids": [] }, "code": "NGT2NMQSV8", "codes_count": 1, "combines_with": {"order": false, "product": false, "shipping": false}, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer_eligibility": {"all": true, "customer_ids": [], "segment_ids": []}, "ends_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000052", "method": "code", "min_requirement": {"type": "none"}, "once_per_customer": false, "shipping": {"countries": [], "max_rate": null}, "starts_at": "2026-10-18T09:30:00Z", "status": "expired", "title": "NGT2NMQSV8", "type": "order", "updated_at": "2026-10-18T09:30:00Z", "usage_count": 0, "usage_limit": 500, "value": "10", "value_type": "percentage", "version": 2 } ```
## Start a discount now POST `/discounts/{id}/activate` · Scope: `write_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/activate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/activate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/activate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/activate", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052/activate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "applies_to": { "all": true, "collection_ids": [], "exclude_sale_items": false, "once_per_order": false, "product_ids": [], "variant_ids": [] }, "code": "NGT2NMQSV8", "codes_count": 1, "combines_with": {"order": false, "product": false, "shipping": false}, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer_eligibility": {"all": true, "customer_ids": [], "segment_ids": []}, "ends_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000052", "method": "code", "min_requirement": {"type": "none"}, "once_per_customer": false, "shipping": {"countries": [], "max_rate": null}, "starts_at": "2026-10-18T09:30:00Z", "status": "active", "title": "NGT2NMQSV8", "type": "order", "updated_at": "2026-10-18T09:30:00Z", "usage_count": 0, "usage_limit": 500, "value": "10", "value_type": "percentage", "version": 3 } ```
## Delete a discount DELETE `/discounts/{id}` · Scope: `write_discounts` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/discounts/0193a1b2-c3d4-7e5f-8a6b-000000000052"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
--- # Draft orders URL: https://sooquna.com/docs/api/admin/draft-orders > Admin API 2026-10: Draft orders. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Draft orders. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Price a draft order without saving it](#price-a-draft-order-without-saving-it) | POST | `/draft-orders/calculate` | | [Create a draft order](#create-a-draft-order) | POST | `/draft-orders` | | [List draft orders](#list-draft-orders) | GET | `/draft-orders` | | [Get a draft order](#get-a-draft-order) | GET | `/draft-orders/{id}` | | [Update a draft order](#update-a-draft-order) | PUT | `/draft-orders/{id}` | | [Turn a draft into an order](#turn-a-draft-into-an-order) | POST | `/draft-orders/{id}/complete` | | [Delete a draft order](#delete-a-draft-order) | DELETE | `/draft-orders/{id}` | ## Price a draft order without saving it POST `/draft-orders/calculate` · Scope: `write_draft_orders` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/draft-orders/calculate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"} }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/draft-orders/calculate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"} }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/draft-orders/calculate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1, }, ], "shipping": {"title": "Doha delivery", "price": "15.00"}, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'customer_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000007', 'lines' => [ [ 'variant_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000014', 'quantity' => 1, ], ], 'shipping' => ['title' => 'Doha delivery', 'price' => '15.00'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"} }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/draft-orders/calculate", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/draft-orders/calculate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"} } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "billing_address": null, "completed_at": null, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 0, "phone": "+97455123456" }, "discount": null, "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000018", "item_count": 1, "lines": [ { "available": 5, "custom": false, "discount": null, "discount_amount": "0.00", "image": "", "missing": false, "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "quantity": 1, "requires_shipping": true, "sku": "ABY-LIN-M", "taxable": true, "title": "Embroidered linen abaya", "total": "450.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M" } ], "name": "#D0", "note": "", "order_discount": "0.00", "order_id": null, "order_name": "", "phone": "+97455123456", "shipping": {"price": "15.00", "title": "Doha delivery"}, "shipping_address": null, "shipping_total": "15.00", "status": "open", "subtotal": "450.00", "tags": [], "tax": "0.00", "tax_exempt": false, "tax_lines": [], "taxes_included": true, "total": "465.00", "updated_at": "2026-10-18T09:30:00Z", "version": 0 } ```
## Create a draft order POST `/draft-orders` · Scope: `write_draft_orders` · Needs an `Idempotency-Key` header ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/draft-orders" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 2 }, { "custom": { "title": "Gift wrapping", "price": "20.00", "taxable": false, "requires_shipping": false }, "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "shipping_address": { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456" }, "note": "Phone order", "tags": ["phone"] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/draft-orders", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 2 }, { "custom": { "title": "Gift wrapping", "price": "20.00", "taxable": false, "requires_shipping": false }, "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "shipping_address": { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456" }, "note": "Phone order", "tags": ["phone"] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/draft-orders", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 2, }, { "custom": { "title": "Gift wrapping", "price": "20.00", "taxable": False, "requires_shipping": False, }, "quantity": 1, }, ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "shipping_address": { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456", }, "note": "Phone order", "tags": ["phone"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'customer_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000007', 'email' => 'noora@example.com', 'lines' => [ [ 'variant_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000014', 'quantity' => 2, ], [ 'custom' => [ 'title' => 'Gift wrapping', 'price' => '20.00', 'taxable' => false, 'requires_shipping' => false, ], 'quantity' => 1, ], ], 'shipping' => ['title' => 'Doha delivery', 'price' => '15.00'], 'shipping_address' => [ 'first_name' => 'Noora', 'last_name' => 'Al-Kuwari', 'address1' => 'Zone 66, Street 801, Building 12', 'city' => 'Doha', 'country_code' => 'QA', 'phone' => '+97455123456', ], 'note' => 'Phone order', 'tags' => ['phone'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 2 }, { "custom": { "title": "Gift wrapping", "price": "20.00", "taxable": false, "requires_shipping": false }, "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "shipping_address": { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456" }, "note": "Phone order", "tags": ["phone"] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/draft-orders", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/draft-orders"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 2 }, { "custom": { "title": "Gift wrapping", "price": "20.00", "taxable": false, "requires_shipping": false }, "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "shipping_address": { "first_name": "Noora", "last_name": "Al-Kuwari", "address1": "Zone 66, Street 801, Building 12", "city": "Doha", "country_code": "QA", "phone": "+97455123456" }, "note": "Phone order", "tags": ["phone"] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "billing_address": null, "completed_at": null, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 0, "phone": "+97455123456" }, "discount": null, "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "item_count": 3, "lines": [ { "available": 5, "custom": false, "discount": null, "discount_amount": "0.00", "image": "", "missing": false, "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "quantity": 2, "requires_shipping": true, "sku": "ABY-LIN-M", "taxable": true, "title": "Embroidered linen abaya", "total": "900.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M" }, { "available": null, "custom": true, "discount": null, "discount_amount": "0.00", "image": "", "missing": false, "price": "20.00", "product_id": null, "quantity": 1, "requires_shipping": false, "sku": "", "taxable": false, "title": "Gift wrapping", "total": "20.00", "variant_id": null, "variant_title": "" } ], "name": "#D1", "note": "Phone order", "order_discount": "0.00", "order_id": null, "order_name": "", "phone": "+97455123456", "shipping": {"price": "15.00", "title": "Doha delivery"}, "shipping_address": { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": null, "first_name": "Noora", "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" }, "shipping_total": "15.00", "status": "open", "subtotal": "920.00", "tags": ["phone"], "tax": "0.00", "tax_exempt": false, "tax_lines": [], "taxes_included": true, "total": "935.00", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## List draft orders GET `/draft-orders` · Scope: `read_draft_orders` | Parameter | In | Description | | --- | --- | --- | | `status` | query | For example `open`. | | `limit` | query | For example `10`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/draft-orders?status=open&limit=10" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/draft-orders?status=open&limit=10", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/draft-orders?status=open&limit=10", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/draft-orders?status=open&limit=10", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/draft-orders?status=open&limit=10"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 0, "phone": "+97455123456" }, "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "item_count": 3, "name": "#D1", "order_id": null, "order_name": "", "status": "open", "total": "935.00", "updated_at": "2026-10-18T09:30:00Z" } ], "total": 1 } ```
## Get a draft order GET `/draft-orders/{id}` · Scope: `read_draft_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "billing_address": null, "completed_at": null, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 0, "phone": "+97455123456" }, "discount": null, "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "item_count": 3, "lines": [ { "available": 5, "custom": false, "discount": null, "discount_amount": "0.00", "image": "", "missing": false, "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "quantity": 2, "requires_shipping": true, "sku": "ABY-LIN-M", "taxable": true, "title": "Embroidered linen abaya", "total": "900.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M" }, { "available": null, "custom": true, "discount": null, "discount_amount": "0.00", "image": "", "missing": false, "price": "20.00", "product_id": null, "quantity": 1, "requires_shipping": false, "sku": "", "taxable": false, "title": "Gift wrapping", "total": "20.00", "variant_id": null, "variant_title": "" } ], "name": "#D1", "note": "Phone order", "order_discount": "0.00", "order_id": null, "order_name": "", "phone": "+97455123456", "shipping": {"price": "15.00", "title": "Doha delivery"}, "shipping_address": { "address1": "Zone 66, Street 801, Building 12", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": null, "first_name": "Noora", "last_name": "Al-Kuwari", "latitude": null, "longitude": null, "phone": "+97455123456", "province_code": "", "zip": "" }, "shipping_total": "15.00", "status": "open", "subtotal": "920.00", "tags": ["phone"], "tax": "0.00", "tax_exempt": false, "tax_lines": [], "taxes_included": true, "total": "935.00", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## Update a draft order PUT `/draft-orders/{id}` · Scope: `write_draft_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "discount": {"type": "percentage", "value": "10", "title": "Loyal customer"}, "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "discount": {"type": "percentage", "value": "10", "title": "Loyal customer"}, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1, }, ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "discount": {"type": "percentage", "value": "10", "title": "Loyal customer"}, "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'customer_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000007', 'email' => 'noora@example.com', 'lines' => [ [ 'variant_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000014', 'quantity' => 1, ], ], 'shipping' => ['title' => 'Doha delivery', 'price' => '15.00'], 'discount' => [ 'type' => 'percentage', 'value' => '10', 'title' => 'Loyal customer', ], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "discount": {"type": "percentage", "value": "10", "title": "Loyal customer"}, "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "customer_id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "email": "noora@example.com", "lines": [ { "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "quantity": 1 } ], "shipping": {"title": "Doha delivery", "price": "15.00"}, "discount": {"type": "percentage", "value": "10", "title": "Loyal customer"}, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "billing_address": null, "completed_at": null, "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 0, "phone": "+97455123456" }, "discount": {"title": "Loyal customer", "type": "percentage", "value": "10"}, "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "item_count": 1, "lines": [ { "available": 5, "custom": false, "discount": null, "discount_amount": "0.00", "image": "", "missing": false, "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "quantity": 1, "requires_shipping": true, "sku": "ABY-LIN-M", "taxable": true, "title": "Embroidered linen abaya", "total": "450.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M" } ], "name": "#D1", "note": "", "order_discount": "45.00", "order_id": null, "order_name": "", "phone": "+97455123456", "shipping": {"price": "15.00", "title": "Doha delivery"}, "shipping_address": null, "shipping_total": "15.00", "status": "open", "subtotal": "450.00", "tags": [], "tax": "0.00", "tax_exempt": false, "tax_lines": [], "taxes_included": true, "total": "420.00", "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Turn a draft into an order POST `/draft-orders/{id}/complete` · Scope: `write_draft_orders` · Needs an `Idempotency-Key` header payment_pending true creates an unpaid order (cash on delivery, bank transfer). | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013/complete" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"payment_pending": true}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013/complete", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({"payment_pending": true}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013/complete", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={"payment_pending": True}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['payment_pending' => true], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{"payment_pending": true}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013/complete", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013/complete"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" {"payment_pending": true} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": null, "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "pending", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "open" } ], "fulfillment_status": "unfulfilled", "fulfillments": [], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 0, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 0, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "0.00", "note": "", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "open", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": [], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "420.00", "total_received": "0.00", "total_refunded": "0.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [], "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Delete a draft order DELETE `/draft-orders/{id}` · Scope: `write_draft_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/draft-orders/0193a1b2-c3d4-7e5f-8a6b-000000000013"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Files URL: https://sooquna.com/docs/api/admin/files > Admin API 2026-10: Files and uploads. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Files and uploads. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Start a file upload](#start-a-file-upload) | POST | `/files/uploads` | | [Finish a file upload](#finish-a-file-upload) | POST | `/files/uploads/{id}/complete` | | [Import a file from a URL](#import-a-file-from-a-url) | POST | `/files/imports` | | [List files](#list-files) | GET | `/files` | | [Get a file](#get-a-file) | GET | `/files/{id}` | | [Update a file's alt text](#update-a-file-s-alt-text) | PATCH | `/files/{id}` | | [Download a file](#download-a-file) | GET | `/files/{id}/download` | | [List where a file is used](#list-where-a-file-is-used) | GET | `/files/{id}/usage` | | [Delete a file](#delete-a-file) | DELETE | `/files/{id}` | ## Start a file upload POST `/files/uploads` · Scope: `write_files` Returns a signed URL; PUT the file there, then complete the upload. ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/files/uploads" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "filename": "abaya-front.jpg", "content_type": "image/jpeg", "size": 482113, "purpose": "product_media" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files/uploads", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "filename": "abaya-front.jpg", "content_type": "image/jpeg", "size": 482113, "purpose": "product_media" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/files/uploads", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "filename": "abaya-front.jpg", "content_type": "image/jpeg", "size": 482113, "purpose": "product_media", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'filename' => 'abaya-front.jpg', 'content_type' => 'image/jpeg', 'size' => 482113, 'purpose' => 'product_media', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "filename": "abaya-front.jpg", "content_type": "image/jpeg", "size": 482113, "purpose": "product_media" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/files/uploads", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/files/uploads"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "filename": "abaya-front.jpg", "content_type": "image/jpeg", "size": 482113, "purpose": "product_media" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Finish a file upload POST `/files/uploads/{id}/complete` · Scope: `write_files` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/files/uploads/0193a1b2-e283-7594-8a2c-0c28281e9c62/complete" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files/uploads/0193a1b2-e283-7594-8a2c-0c28281e9c62/complete", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/files/uploads/0193a1b2-e283-7594-8a2c-0c28281e9c62/complete", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/files/uploads/0193a1b2-e283-7594-8a2c-0c28281e9c62/complete", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/files/uploads/0193a1b2-e283-7594-8a2c-0c28281e9c62/complete"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Import a file from a URL POST `/files/imports` · Scope: `write_files` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/files/imports" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://cdn.example.com/abaya-front.jpg", "purpose": "product_media" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files/imports", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "url": "https://cdn.example.com/abaya-front.jpg", "purpose": "product_media" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/files/imports", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "url": "https://cdn.example.com/abaya-front.jpg", "purpose": "product_media", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'url' => 'https://cdn.example.com/abaya-front.jpg', 'purpose' => 'product_media', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "url": "https://cdn.example.com/abaya-front.jpg", "purpose": "product_media" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/files/imports", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/files/imports"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "url": "https://cdn.example.com/abaya-front.jpg", "purpose": "product_media" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List files GET `/files` · Scope: `read_files` | Parameter | In | Description | | --- | --- | --- | | `kind` | query | For example `image`. | | `limit` | query | For example `20`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/files?kind=image&limit=20" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files?kind=image&limit=20", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/files?kind=image&limit=20", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/files?kind=image&limit=20", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/files?kind=image&limit=20"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": [], "page_info": {"has_next_page": false}} ```
## Get a file GET `/files/{id}` · Scope: `read_files` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Update a file's alt text PATCH `/files/{id}` · Scope: `write_files` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "alt": "Embroidered linen abaya", "alt_translations": {"ar": "عباية كتان مطرزة"}, "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "alt": "Embroidered linen abaya", "alt_translations": {"ar": "عباية كتان مطرزة"}, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "alt": "Embroidered linen abaya", "alt_translations": {"ar": "عباية كتان مطرزة"}, "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'alt' => 'Embroidered linen abaya', 'alt_translations' => ['ar' => 'عباية كتان مطرزة'], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "alt": "Embroidered linen abaya", "alt_translations": {"ar": "عباية كتان مطرزة"}, "version": 1 }` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "alt": "Embroidered linen abaya", "alt_translations": {"ar": "عباية كتان مطرزة"}, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Download a file GET `/files/{id}/download` · Scope: `read_files` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-98fc-7bd2-8bf0-91459d0341d6/download" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -o abaya-front.jpg ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-98fc-7bd2-8bf0-91459d0341d6/download", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); await writeFile("abaya-front.jpg", Buffer.from(await res.arrayBuffer())); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-98fc-7bd2-8bf0-91459d0341d6/download", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() with open("abaya-front.jpg", "wb") as f: f.write(res.content) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } file_put_contents('abaya-front.jpg', $response); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-98fc-7bd2-8bf0-91459d0341d6/download", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } out, err := os.Create("abaya-front.jpg") if err != nil { panic(err) } defer out.Close() io.Copy(out, res.Body) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-98fc-7bd2-8bf0-91459d0341d6/download"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); await File.WriteAllBytesAsync("abaya-front.jpg", await res.Content.ReadAsByteArrayAsync()); ``` ## List where a file is used GET `/files/{id}/usage` · Scope: `read_files` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-346e-7c53-8e35-095de053aa58/usage" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-346e-7c53-8e35-095de053aa58/usage", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-346e-7c53-8e35-095de053aa58/usage", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-346e-7c53-8e35-095de053aa58/usage", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-346e-7c53-8e35-095de053aa58/usage"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Delete a file DELETE `/files/{id}` · Scope: `write_files` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/files/0193a1b2-b156-780e-84f5-048f32443475"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Fulfillments URL: https://sooquna.com/docs/api/admin/fulfillments > Admin API 2026-10: Fulfillment orders, fulfillments, shipping labels and tracking. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Fulfillment orders, fulfillments, shipping labels and tracking. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Fulfil items of an order](#fulfil-items-of-an-order) | POST | `/orders/{id}/fulfillments` | | [Update a shipment's tracking or status](#update-a-shipment-s-tracking-or-status) | PATCH | `/orders/{id}/fulfillments/{fulfillment_id}` | | [Cancel a fulfillment](#cancel-a-fulfillment) | POST | `/orders/{id}/fulfillments/{fulfillment_id}/cancel` | | [List an order's shipments](#list-an-order-s-shipments) | GET | `/orders/{id}/shipments` | | [Put fulfilment on hold](#put-fulfilment-on-hold) | POST | `/orders/{id}/fulfillment-orders/{fo_id}/hold` | | [Release a fulfilment hold](#release-a-fulfilment-hold) | POST | `/orders/{id}/fulfillment-orders/{fo_id}/release-hold` | | [Mark items ready for pickup](#mark-items-ready-for-pickup) | POST | `/orders/{id}/fulfillment-orders/{fo_id}/ready-for-pickup` | | [Get courier quotes for a label](#get-courier-quotes-for-a-label) | POST | `/orders/{id}/shipping-labels/quotes` | | [Buy a shipping label](#buy-a-shipping-label) | POST | `/orders/{id}/shipping-labels` | | [Refresh a shipment's tracking](#refresh-a-shipment-s-tracking) | POST | `/shipments/{id}/track` | | [Cancel a courier shipment](#cancel-a-courier-shipment) | POST | `/shipments/{id}/cancel` | ## Fulfil items of an order POST `/orders/{id}/fulfillments` · Scope: `write_fulfillments` · Needs an `Idempotency-Key` header | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "tracking_company": "Aramex", "tracking_number": "47012233441", "notify_customer": true }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "tracking_company": "Aramex", "tracking_number": "47012233441", "notify_customer": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, }, ], "tracking_company": "Aramex", "tracking_number": "47012233441", "notify_customer": True, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'fulfillment_order_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000036', 'lines' => [ [ 'line_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000037', 'quantity' => 1, ], ], 'tracking_company' => 'Aramex', 'tracking_number' => '47012233441', 'notify_customer' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "tracking_company": "Aramex", "tracking_number": "47012233441", "notify_customer": true }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "tracking_company": "Aramex", "tracking_number": "47012233441", "notify_customer": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": null, "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "paid", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 0 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "closed" } ], "fulfillment_status": "fulfilled", "fulfillments": [ { "created_at": "2026-10-18T09:30:00Z", "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000050", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "name": "#1001-F1", "shipment_status": "", "status": "success", "tracking_company": "Aramex", "tracking_number": "47012233441", "tracking_url": "https://www.aramex.com/track/results?ShipmentNumber=47012233441" } ], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 1, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 0, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "420.00", "note": "Call before delivery", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "open", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": ["phone", "priority"], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "0.00", "total_received": "420.00", "total_refunded": "0.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [ { "actor": "Docs", "amount": "420.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000051", "kind": "sale", "method": "manual", "provider": "manual", "status": "success", "test": false } ], "updated_at": "2026-10-18T09:30:00Z", "version": 5 } ```
## Update a shipment's tracking or status PATCH `/orders/{id}/fulfillments/{fulfillment_id}` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `fulfillment_id` | path | The fulfillment ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "shipment_status": "in_transit", "tracking_number": "47012233442", "notify_customer": false }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "shipment_status": "in_transit", "tracking_number": "47012233442", "notify_customer": false }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "shipment_status": "in_transit", "tracking_number": "47012233442", "notify_customer": False, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'shipment_status' => 'in_transit', 'tracking_number' => '47012233442', 'notify_customer' => false, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "shipment_status": "in_transit", "tracking_number": "47012233442", "notify_customer": false }` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "shipment_status": "in_transit", "tracking_number": "47012233442", "notify_customer": false } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": null, "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "paid", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 0 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "closed" } ], "fulfillment_status": "fulfilled", "fulfillments": [ { "created_at": "2026-10-18T09:30:00Z", "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000050", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "name": "#1001-F1", "shipment_status": "in_transit", "status": "success", "tracking_company": "Aramex", "tracking_number": "47012233442", "tracking_url": "https://www.aramex.com/track/results?ShipmentNumber=47012233442" } ], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 1, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 0, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "420.00", "note": "Call before delivery", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "open", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": ["phone", "priority"], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "0.00", "total_received": "420.00", "total_refunded": "0.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [ { "actor": "Docs", "amount": "420.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000051", "kind": "sale", "method": "manual", "provider": "manual", "status": "success", "test": false } ], "updated_at": "2026-10-18T09:30:00Z", "version": 5 } ```
## Cancel a fulfillment POST `/orders/{id}/fulfillments/{fulfillment_id}/cancel` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `fulfillment_id` | path | The fulfillment ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050/cancel" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050/cancel", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050/cancel", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050/cancel", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillments/0193a1b2-c3d4-7e5f-8a6b-000000000050/cancel"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List an order's shipments GET `/orders/{id}/shipments` · Scope: `read_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipments" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipments", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipments", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipments", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipments"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
## Put fulfilment on hold POST `/orders/{id}/fulfillment-orders/{fo_id}/hold` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `fo_id` | path | The fo ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/hold" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"reason": "awaiting_payment", "note": "Waiting for the bank transfer"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/hold", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"reason": "awaiting_payment", "note": "Waiting for the bank transfer"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/hold", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "reason": "awaiting_payment", "note": "Waiting for the bank transfer", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'reason' => 'awaiting_payment', 'note' => 'Waiting for the bank transfer', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"reason": "awaiting_payment", "note": "Waiting for the bank transfer"}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/hold", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/hold"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"reason": "awaiting_payment", "note": "Waiting for the bank transfer"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Release a fulfilment hold POST `/orders/{id}/fulfillment-orders/{fo_id}/release-hold` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `fo_id` | path | The fo ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/release-hold" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/release-hold", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/release-hold", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/release-hold", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/release-hold"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Mark items ready for pickup POST `/orders/{id}/fulfillment-orders/{fo_id}/ready-for-pickup` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `fo_id` | path | The fo ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/ready-for-pickup" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"notify_customer": true}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/ready-for-pickup", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"notify_customer": true}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/ready-for-pickup", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"notify_customer": True}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['notify_customer' => true], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"notify_customer": true}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/ready-for-pickup", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/fulfillment-orders/0193a1b2-c3d4-7e5f-8a6b-000000000036/ready-for-pickup"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"notify_customer": true} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Get courier quotes for a label POST `/orders/{id}/shipping-labels/quotes` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels/quotes" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "weight_kg": "1.2", "collect_cod": true }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels/quotes", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "weight_kg": "1.2", "collect_cod": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels/quotes", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "weight_kg": "1.2", "collect_cod": True, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'fulfillment_order_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000036', 'carrier' => 'aramex', 'weight_kg' => '1.2', 'collect_cod' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "weight_kg": "1.2", "collect_cod": true }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels/quotes", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels/quotes"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "weight_kg": "1.2", "collect_cod": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Buy a shipping label POST `/orders/{id}/shipping-labels` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "service": "domestic_express", "weight_kg": "1.2", "collect_cod": true, "notify_customer": true }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "service": "domestic_express", "weight_kg": "1.2", "collect_cod": true, "notify_customer": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "service": "domestic_express", "weight_kg": "1.2", "collect_cod": True, "notify_customer": True, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'fulfillment_order_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000036', 'carrier' => 'aramex', 'service' => 'domestic_express', 'weight_kg' => '1.2', 'collect_cod' => true, 'notify_customer' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "service": "domestic_express", "weight_kg": "1.2", "collect_cod": true, "notify_customer": true }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/shipping-labels"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "carrier": "aramex", "service": "domestic_express", "weight_kg": "1.2", "collect_cod": true, "notify_customer": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Refresh a shipment's tracking POST `/shipments/{id}/track` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1d42-7f74-8582-da5d056e14a3/track" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1d42-7f74-8582-da5d056e14a3/track", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1d42-7f74-8582-da5d056e14a3/track", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1d42-7f74-8582-da5d056e14a3/track", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1d42-7f74-8582-da5d056e14a3/track"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Cancel a courier shipment POST `/shipments/{id}/cancel` · Scope: `write_fulfillments` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1bff-7dd8-893c-b1cea75cd4ca/cancel" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1bff-7dd8-893c-b1cea75cd4ca/cancel", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1bff-7dd8-893c-b1cea75cd4ca/cancel", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1bff-7dd8-893c-b1cea75cd4ca/cancel", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/shipments/0193a1b2-1bff-7dd8-893c-b1cea75cd4ca/cancel"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Gift cards URL: https://sooquna.com/docs/api/admin/gift-cards > Admin API 2026-10: Gift cards and their balances. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Gift cards and their balances. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Issue a gift card](#issue-a-gift-card) | POST | `/gift-cards` | | [List gift cards](#list-gift-cards) | GET | `/gift-cards` | | [Get a gift card](#get-a-gift-card) | GET | `/gift-cards/{id}` | | [Update a gift card](#update-a-gift-card) | PUT | `/gift-cards/{id}` | | [Adjust a gift card's balance](#adjust-a-gift-card-s-balance) | POST | `/gift-cards/{id}/adjust` | | [Disable a gift card](#disable-a-gift-card) | POST | `/gift-cards/{id}/disable` | | [Enable a gift card](#enable-a-gift-card) | POST | `/gift-cards/{id}/enable` | ## Issue a gift card POST `/gift-cards` · Scope: `write_gift_cards` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/gift-cards" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "value": "250.00", "recipient_email": "noora@example.com", "recipient_name": "Noora", "message": "Eid Mubarak!", "no_expiry": true, "notify": false }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/gift-cards", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "value": "250.00", "recipient_email": "noora@example.com", "recipient_name": "Noora", "message": "Eid Mubarak!", "no_expiry": true, "notify": false }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/gift-cards", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "value": "250.00", "recipient_email": "noora@example.com", "recipient_name": "Noora", "message": "Eid Mubarak!", "no_expiry": True, "notify": False, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'value' => '250.00', 'recipient_email' => 'noora@example.com', 'recipient_name' => 'Noora', 'message' => 'Eid Mubarak!', 'no_expiry' => true, 'notify' => false, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "value": "250.00", "recipient_email": "noora@example.com", "recipient_name": "Noora", "message": "Eid Mubarak!", "no_expiry": true, "notify": false }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/gift-cards", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/gift-cards"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "value": "250.00", "recipient_email": "noora@example.com", "recipient_name": "Noora", "message": "Eid Mubarak!", "no_expiry": true, "notify": false } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "balance": 25000, "code": "F99N Y2QF CNQ5 5Z99", "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "currency": "QAR", "customer_id": null, "disabled_at": null, "expires_on": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000015", "initial_value": 25000, "last4": "5Z99", "message": "Eid Mubarak!", "note": "", "order_id": null, "recipient_email": "noora@example.com", "recipient_name": "Noora", "send_at": null, "sent_at": null, "source": "manual", "status": "active", "transactions": [ { "actor": "Docs", "amount": 25000, "balance_after": 25000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000016", "kind": "issue", "note": "Issued", "order_id": null } ], "version": 1 } ```
## List gift cards GET `/gift-cards` · Scope: `read_gift_cards` | Parameter | In | Description | | --- | --- | --- | | `status` | query | For example `active`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/gift-cards?status=active" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/gift-cards?status=active", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/gift-cards?status=active", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/gift-cards?status=active", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/gift-cards?status=active"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "balance": 25000, "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "currency": "QAR", "customer_id": null, "disabled_at": null, "expires_on": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000015", "initial_value": 25000, "last4": "5Z99", "message": "Eid Mubarak!", "note": "", "order_id": null, "recipient_email": "noora@example.com", "recipient_name": "Noora", "send_at": null, "sent_at": null, "source": "manual", "status": "active", "version": 1 } ], "page_info": {"end_cursor": "", "has_next_page": false} } ```
## Get a gift card GET `/gift-cards/{id}` · Scope: `read_gift_cards` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "balance": 25000, "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "currency": "QAR", "customer_id": null, "disabled_at": null, "expires_on": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000015", "initial_value": 25000, "last4": "5Z99", "message": "Eid Mubarak!", "note": "", "order_id": null, "recipient_email": "noora@example.com", "recipient_name": "Noora", "send_at": null, "sent_at": null, "source": "manual", "status": "active", "transactions": [ { "actor": "Docs", "amount": 25000, "balance_after": 25000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000016", "kind": "issue", "note": "Issued", "order_id": null } ], "version": 1 } ```
## Update a gift card PUT `/gift-cards/{id}` · Scope: `write_gift_cards` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "expires_on": "2027-12-31", "note": "Customer service goodwill", "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "expires_on": "2027-12-31", "note": "Customer service goodwill", "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "expires_on": "2027-12-31", "note": "Customer service goodwill", "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'expires_on' => '2027-12-31', 'note' => 'Customer service goodwill', 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "expires_on": "2027-12-31", "note": "Customer service goodwill", "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "expires_on": "2027-12-31", "note": "Customer service goodwill", "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "balance": 25000, "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "currency": "QAR", "customer_id": null, "disabled_at": null, "expires_on": "2027-12-31", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000015", "initial_value": 25000, "last4": "5Z99", "message": "Eid Mubarak!", "note": "Customer service goodwill", "order_id": null, "recipient_email": "noora@example.com", "recipient_name": "Noora", "send_at": null, "sent_at": null, "source": "manual", "status": "active", "transactions": [ { "actor": "Docs", "amount": 25000, "balance_after": 25000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000016", "kind": "issue", "note": "Issued", "order_id": null } ], "version": 2 } ```
## Adjust a gift card's balance POST `/gift-cards/{id}/adjust` · Scope: `write_gift_cards` A signed amount: +50.00 adds, -20.00 takes off. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/adjust" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"amount": "+50.00", "reason": "Delivery delay apology", "version": 1}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/adjust", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"amount": "+50.00", "reason": "Delivery delay apology", "version": 1}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/adjust", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "amount": "+50.00", "reason": "Delivery delay apology", "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'amount' => '+50.00', 'reason' => 'Delivery delay apology', 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"amount": "+50.00", "reason": "Delivery delay apology", "version": 1}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/adjust", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/adjust"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"amount": "+50.00", "reason": "Delivery delay apology", "version": 1} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "balance": 30000, "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "currency": "QAR", "customer_id": null, "disabled_at": null, "expires_on": "2027-12-31", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000015", "initial_value": 25000, "last4": "5Z99", "message": "Eid Mubarak!", "note": "Customer service goodwill", "order_id": null, "recipient_email": "noora@example.com", "recipient_name": "Noora", "send_at": null, "sent_at": null, "source": "manual", "status": "active", "transactions": [ { "actor": "Docs", "amount": 5000, "balance_after": 30000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000053", "kind": "adjust", "note": "Delivery delay apology", "order_id": null }, { "actor": "Docs", "amount": 25000, "balance_after": 25000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000016", "kind": "issue", "note": "Issued", "order_id": null } ], "version": 3 } ```
## Disable a gift card POST `/gift-cards/{id}/disable` · Scope: `write_gift_cards` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/disable" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/disable", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/disable", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/disable", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/disable"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "balance": 30000, "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "currency": "QAR", "customer_id": null, "disabled_at": "2026-10-18T09:30:00Z", "expires_on": "2027-12-31", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000015", "initial_value": 25000, "last4": "5Z99", "message": "Eid Mubarak!", "note": "Customer service goodwill", "order_id": null, "recipient_email": "noora@example.com", "recipient_name": "Noora", "send_at": null, "sent_at": null, "source": "manual", "status": "disabled", "transactions": [ { "actor": "Docs", "amount": 5000, "balance_after": 30000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000053", "kind": "adjust", "note": "Delivery delay apology", "order_id": null }, { "actor": "Docs", "amount": 25000, "balance_after": 25000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000016", "kind": "issue", "note": "Issued", "order_id": null } ], "version": 4 } ```
## Enable a gift card POST `/gift-cards/{id}/enable` · Scope: `write_gift_cards` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/enable" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/enable", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/enable", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/enable", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/gift-cards/0193a1b2-c3d4-7e5f-8a6b-000000000015/enable"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "balance": 30000, "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "currency": "QAR", "customer_id": null, "disabled_at": null, "expires_on": "2027-12-31", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000015", "initial_value": 25000, "last4": "5Z99", "message": "Eid Mubarak!", "note": "Customer service goodwill", "order_id": null, "recipient_email": "noora@example.com", "recipient_name": "Noora", "send_at": null, "sent_at": null, "source": "manual", "status": "active", "transactions": [ { "actor": "Docs", "amount": 5000, "balance_after": 30000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000053", "kind": "adjust", "note": "Delivery delay apology", "order_id": null }, { "actor": "Docs", "amount": 25000, "balance_after": 25000, "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000016", "kind": "issue", "note": "Issued", "order_id": null } ], "version": 5 } ```
--- # Inventory URL: https://sooquna.com/docs/api/admin/inventory > Admin API 2026-10: Stock levels, adjustments, transfers, suppliers and purchase orders. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Stock levels, adjustments, transfers, suppliers and purchase orders. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [List inventory items with stock](#list-inventory-items-with-stock) | GET | `/inventory` | | [Get stock levels of items](#get-stock-levels-of-items) | GET | `/inventory/levels` | | [Adjust stock](#adjust-stock) | POST | `/inventory/adjust` | | [Move stock between states](#move-stock-between-states) | POST | `/inventory/move` | | [Update an inventory item](#update-an-inventory-item) | PATCH | `/inventory/items/{id}` | | [List an item's stock changes](#list-an-item-s-stock-changes) | GET | `/inventory/items/{id}/history` | | [Create a stock transfer](#create-a-stock-transfer) | POST | `/inventory-transfers` | | [List stock transfers](#list-stock-transfers) | GET | `/inventory-transfers` | | [Get a stock transfer](#get-a-stock-transfer) | GET | `/inventory-transfers/{id}` | | [Update a draft transfer](#update-a-draft-transfer) | PUT | `/inventory-transfers/{id}` | | [Mark a transfer as shipped](#mark-a-transfer-as-shipped) | POST | `/inventory-transfers/{id}/ship` | | [Receive a transfer](#receive-a-transfer) | POST | `/inventory-transfers/{id}/receive` | | [Cancel a transfer](#cancel-a-transfer) | POST | `/inventory-transfers/{id}/cancel` | | [Delete a draft transfer](#delete-a-draft-transfer) | DELETE | `/inventory-transfers/{id}` | | [Create a supplier](#create-a-supplier) | POST | `/suppliers` | | [List suppliers](#list-suppliers) | GET | `/suppliers` | | [Update a supplier](#update-a-supplier) | PUT | `/suppliers/{id}` | | [Create a purchase order](#create-a-purchase-order) | POST | `/purchase-orders` | | [List purchase orders](#list-purchase-orders) | GET | `/purchase-orders` | | [Get a purchase order](#get-a-purchase-order) | GET | `/purchase-orders/{id}` | | [Update a draft purchase order](#update-a-draft-purchase-order) | PUT | `/purchase-orders/{id}` | | [Mark a purchase order as ordered](#mark-a-purchase-order-as-ordered) | POST | `/purchase-orders/{id}/order` | | [Receive a purchase order](#receive-a-purchase-order) | POST | `/purchase-orders/{id}/receive` | | [Close a purchase order](#close-a-purchase-order) | POST | `/purchase-orders/{id}/close` | | [Download a purchase order as PDF](#download-a-purchase-order-as-pdf) | GET | `/purchase-orders/{id}/pdf` | | [Delete a draft purchase order](#delete-a-draft-purchase-order) | DELETE | `/purchase-orders/{id}` | | [Delete a supplier](#delete-a-supplier) | DELETE | `/suppliers/{id}` | ## List inventory items with stock GET `/inventory` · Scope: `read_inventory` | Parameter | In | Description | | --- | --- | --- | | `low_stock` | query | For example `true`. | | `limit` | query | For example `20`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/inventory?low_stock=true&limit=20" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory?low_stock=true&limit=20", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/inventory?low_stock=true&limit=20", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/inventory?low_stock=true&limit=20", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/inventory?low_stock=true&limit=20"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "available": 0, "barcode": "", "committed": 0, "damaged": 0, "incoming": 0, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "inventory_policy": "deny", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000018", "low_stock_threshold": 5, "on_hand": 0, "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "product_title": "Embroidered linen abaya", "quality_control": 0, "reserved": 0, "safety_stock": 0, "sku": "ABY-LIN-S", "tracked": true, "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "variant_title": "S" }, { "available": 0, "barcode": "", "committed": 0, "damaged": 0, "incoming": 0, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "inventory_policy": "deny", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000018", "low_stock_threshold": 5, "on_hand": 0, "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "product_title": "Embroidered linen abaya", "quality_control": 0, "reserved": 0, "safety_stock": 0, "sku": "ABY-LIN-M", "tracked": true, "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M" } ], "page_info": {"has_next_page": false} } ```
## Get stock levels of items GET `/inventory/levels` · Scope: `read_inventory` | Parameter | In | Description | | --- | --- | --- | | `item_ids` | query | An ID, as in the example. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/inventory/levels?item_ids=0193a1b2-c3d4-7e5f-8a6b-000000000017" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory/levels?item_ids=0193a1b2-c3d4-7e5f-8a6b-000000000017", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/inventory/levels?item_ids=0193a1b2-c3d4-7e5f-8a6b-000000000017", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/inventory/levels?item_ids=0193a1b2-c3d4-7e5f-8a6b-000000000017", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/inventory/levels?item_ids=0193a1b2-c3d4-7e5f-8a6b-000000000017"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": { "01a14f9e-ff97-7e10-b684-5d874da1452f": [ { "available": 0, "committed": 0, "damaged": 0, "incoming": 0, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "location_name": "West Bay shop", "on_hand": 0, "quality_control": 0, "reserved": 0, "safety_stock": 0 }, { "available": 0, "committed": 0, "damaged": 0, "incoming": 0, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "location_name": "Al Wakrah warehouse", "on_hand": 0, "quality_control": 0, "reserved": 0, "safety_stock": 0 } ] } } ```
## Adjust stock POST `/inventory/adjust` · Scope: `write_inventory` · Needs an `Idempotency-Key` header delta adds or removes units; set replaces the quantity. States: available, damaged, safety_stock, quality_control. Reasons: correction, received, damaged, shrinkage, return_restock, promotion, cycle_count, other. ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/inventory/adjust" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "changes": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "set": 12, "reason": "received" }, { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "delta": 5, "reason": "received", "note": "Supplier delivery INV-2210" } ] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory/adjust", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "changes": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "set": 12, "reason": "received" }, { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "delta": 5, "reason": "received", "note": "Supplier delivery INV-2210" } ] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/inventory/adjust", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "changes": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "set": 12, "reason": "received", }, { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "delta": 5, "reason": "received", "note": "Supplier delivery INV-2210", }, ], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'changes' => [ [ 'inventory_item_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000017', 'location_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000023', 'state' => 'available', 'set' => 12, 'reason' => 'received', ], [ 'inventory_item_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000020', 'location_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000023', 'state' => 'available', 'delta' => 5, 'reason' => 'received', 'note' => 'Supplier delivery INV-2210', ], ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "changes": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "set": 12, "reason": "received" }, { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "delta": 5, "reason": "received", "note": "Supplier delivery INV-2210" } ] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/inventory/adjust", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/inventory/adjust"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "changes": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "set": 12, "reason": "received" }, { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "state": "available", "delta": 5, "reason": "received", "note": "Supplier delivery INV-2210" } ] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "levels": [ { "available": 12, "committed": 0, "damaged": 0, "incoming": 0, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "on_hand": 12, "quality_control": 0, "reserved": 0, "safety_stock": 0 }, { "available": 5, "committed": 0, "damaged": 0, "incoming": 0, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "on_hand": 5, "quality_control": 0, "reserved": 0, "safety_stock": 0 } ] } ```
## Move stock between states POST `/inventory/move` · Scope: `write_inventory` · Needs an `Idempotency-Key` header ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/inventory/move" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "from_state": "available", "to_state": "damaged", "qty": 1, "note": "Torn hem" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory/move", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "from_state": "available", "to_state": "damaged", "qty": 1, "note": "Torn hem" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/inventory/move", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "from_state": "available", "to_state": "damaged", "qty": 1, "note": "Torn hem", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'inventory_item_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000017', 'location_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000023', 'from_state' => 'available', 'to_state' => 'damaged', 'qty' => 1, 'note' => 'Torn hem', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "from_state": "available", "to_state": "damaged", "qty": 1, "note": "Torn hem" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/inventory/move", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/inventory/move"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "from_state": "available", "to_state": "damaged", "qty": 1, "note": "Torn hem" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "levels": [ { "available": 11, "committed": 0, "damaged": 1, "incoming": 0, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "on_hand": 12, "quality_control": 0, "reserved": 0, "safety_stock": 0 } ] } ```
## Update an inventory item PATCH `/inventory/items/{id}` · Scope: `write_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"tracked": true, "low_stock_threshold": 3}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"tracked": true, "low_stock_threshold": 3}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"tracked": True, "low_stock_threshold": 3}, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['tracked' => true, 'low_stock_threshold' => 3], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"tracked": true, "low_stock_threshold": 3}` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"tracked": true, "low_stock_threshold": 3} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## List an item's stock changes GET `/inventory/items/{id}/history` · Scope: `read_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `limit` | query | For example `20`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017/history?limit=20" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017/history?limit=20", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017/history?limit=20", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017/history?limit=20", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/inventory/items/0193a1b2-c3d4-7e5f-8a6b-000000000017/history?limit=20"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "actor": "Docs", "created_at": "2026-10-18T09:30:00Z", "delta": 1, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000025", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "location_name": "West Bay shop", "note": "Torn hem", "quantity_after": 1, "reason": "movement", "reference_id": "", "reference_type": "", "state": "damaged" }, { "actor": "Docs", "created_at": "2026-10-18T09:30:00Z", "delta": -1, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000026", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "location_name": "West Bay shop", "note": "Torn hem", "quantity_after": 11, "reason": "movement", "reference_id": "", "reference_type": "", "state": "available" } ], "page_info": {"has_next_page": false} } ```
## Create a stock transfer POST `/inventory-transfers` · Scope: `write_inventory` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/inventory-transfers" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 2 } ] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory-transfers", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 2 } ] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/inventory-transfers", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 2, }, ], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'origin_location_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000023', 'destination_location_id' => '0193a1b2-c810-7698-8039-998bb6c1a849', 'reference' => 'TR-1001', 'lines' => [ [ 'inventory_item_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000017', 'qty' => 2, ], ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 2 } ] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/inventory-transfers", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/inventory-transfers"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 2 } ] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "created_at": "2026-10-18T09:30:00Z", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "destination_name": "Al Wakrah warehouse", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000022", "lines": [ { "barcode": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000024", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "product_title": "Embroidered linen abaya", "qty": 2, "received_qty": 0, "rejected_qty": 0, "sku": "ABY-LIN-S", "variant_title": "S" } ], "name": "#T1001", "notes": "", "number": 1001, "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "origin_name": "West Bay shop", "received_qty": 0, "reference": "TR-1001", "shipped_at": null, "status": "draft", "total_qty": 2, "version": 1 } ```
## List stock transfers GET `/inventory-transfers` · Scope: `read_inventory` | Parameter | In | Description | | --- | --- | --- | | `status` | query | For example `draft`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/inventory-transfers?status=draft" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory-transfers?status=draft", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/inventory-transfers?status=draft", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/inventory-transfers?status=draft", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/inventory-transfers?status=draft"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "created_at": "2026-10-18T09:30:00Z", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "destination_name": "Al Wakrah warehouse", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000022", "name": "#T1001", "notes": "", "number": 1001, "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "origin_name": "West Bay shop", "received_qty": 0, "reference": "TR-1001", "shipped_at": null, "status": "draft", "total_qty": 2, "version": 1 } ], "has_more": false } ```
## Get a stock transfer GET `/inventory-transfers/{id}` · Scope: `read_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "destination_name": "Al Wakrah warehouse", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000022", "lines": [ { "barcode": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000024", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "product_title": "Embroidered linen abaya", "qty": 2, "received_qty": 0, "rejected_qty": 0, "sku": "ABY-LIN-S", "variant_title": "S" } ], "name": "#T1001", "notes": "", "number": 1001, "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "origin_name": "West Bay shop", "received_qty": 0, "reference": "TR-1001", "shipped_at": null, "status": "draft", "total_qty": 2, "version": 1 } ```
## Update a draft transfer PUT `/inventory-transfers/{id}` · Scope: `write_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "notes": "Eid stock for the warehouse", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 3 } ], "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "notes": "Eid stock for the warehouse", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 3 } ], "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "notes": "Eid stock for the warehouse", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 3, }, ], "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'origin_location_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000023', 'destination_location_id' => '0193a1b2-c810-7698-8039-998bb6c1a849', 'reference' => 'TR-1001', 'notes' => 'Eid stock for the warehouse', 'lines' => [ [ 'inventory_item_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000017', 'qty' => 3, ], ], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "notes": "Eid stock for the warehouse", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 3 } ], "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_location_id": "0193a1b2-c810-7698-8039-998bb6c1a849", "reference": "TR-1001", "notes": "Eid stock for the warehouse", "lines": [ { "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "qty": 3 } ], "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "destination_name": "Al Wakrah warehouse", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000022", "lines": [ { "barcode": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000054", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "product_title": "Embroidered linen abaya", "qty": 3, "received_qty": 0, "rejected_qty": 0, "sku": "ABY-LIN-S", "variant_title": "S" } ], "name": "#T1001", "notes": "Eid stock for the warehouse", "number": 1001, "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "origin_name": "West Bay shop", "received_qty": 0, "reference": "TR-1001", "shipped_at": null, "status": "draft", "total_qty": 3, "version": 2 } ```
## Mark a transfer as shipped POST `/inventory-transfers/{id}/ship` · Scope: `write_inventory` · Needs an `Idempotency-Key` header | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/ship" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/ship", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/ship", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "github.com/google/uuid" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/ship", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/ship"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "destination_name": "Al Wakrah warehouse", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000022", "lines": [ { "barcode": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000054", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "product_title": "Embroidered linen abaya", "qty": 3, "received_qty": 0, "rejected_qty": 0, "sku": "ABY-LIN-S", "variant_title": "S" } ], "name": "#T1001", "notes": "Eid stock for the warehouse", "number": 1001, "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "origin_name": "West Bay shop", "received_qty": 0, "reference": "TR-1001", "shipped_at": "2026-10-18T09:30:00Z", "status": "in_transit", "total_qty": 3, "version": 3 } ```
## Receive a transfer POST `/inventory-transfers/{id}/receive` · Scope: `write_inventory` · Needs an `Idempotency-Key` header | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/receive" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000024", "accepted": 3, "rejected": 0 } ] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/receive", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000024", "accepted": 3, "rejected": 0 } ] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/receive", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000024", "accepted": 3, "rejected": 0, }, ], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'lines' => [ [ 'line_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000024', 'accepted' => 3, 'rejected' => 0, ], ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000024", "accepted": 3, "rejected": 0 } ] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/receive", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/receive"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000024", "accepted": 3, "rejected": 0 } ] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "destination_name": "Al Wakrah warehouse", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000022", "lines": [ { "barcode": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000054", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "product_title": "Embroidered linen abaya", "qty": 3, "received_qty": 3, "rejected_qty": 0, "sku": "ABY-LIN-S", "variant_title": "S" } ], "name": "#T1001", "notes": "Eid stock for the warehouse", "number": 1001, "origin_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "origin_name": "West Bay shop", "received_qty": 3, "reference": "TR-1001", "shipped_at": "2026-10-18T09:30:00Z", "status": "received", "total_qty": 3, "version": 4 } ```
## Cancel a transfer POST `/inventory-transfers/{id}/cancel` · Scope: `write_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/cancel" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/cancel", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/cancel", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/cancel", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022/cancel"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Delete a draft transfer DELETE `/inventory-transfers/{id}` · Scope: `write_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/inventory-transfers/0193a1b2-c3d4-7e5f-8a6b-000000000022"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Create a supplier POST `/suppliers` · Scope: `write_inventory` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/suppliers" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Al Noor Textiles", "contact": { "name": "Ahmed Saleh", "email": "orders@alnoor.example", "phone": "+97455001122" }, "address": { "address1": "Industrial Area Street 41", "city": "Doha", "country": "QA" }, "currency": "QAR" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/suppliers", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "name": "Al Noor Textiles", "contact": { "name": "Ahmed Saleh", "email": "orders@alnoor.example", "phone": "+97455001122" }, "address": { "address1": "Industrial Area Street 41", "city": "Doha", "country": "QA" }, "currency": "QAR" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/suppliers", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "name": "Al Noor Textiles", "contact": { "name": "Ahmed Saleh", "email": "orders@alnoor.example", "phone": "+97455001122", }, "address": { "address1": "Industrial Area Street 41", "city": "Doha", "country": "QA", }, "currency": "QAR", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'name' => 'Al Noor Textiles', 'contact' => [ 'name' => 'Ahmed Saleh', 'email' => 'orders@alnoor.example', 'phone' => '+97455001122', ], 'address' => [ 'address1' => 'Industrial Area Street 41', 'city' => 'Doha', 'country' => 'QA', ], 'currency' => 'QAR', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "name": "Al Noor Textiles", "contact": { "name": "Ahmed Saleh", "email": "orders@alnoor.example", "phone": "+97455001122" }, "address": { "address1": "Industrial Area Street 41", "city": "Doha", "country": "QA" }, "currency": "QAR" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/suppliers", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/suppliers"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "name": "Al Noor Textiles", "contact": { "name": "Ahmed Saleh", "email": "orders@alnoor.example", "phone": "+97455001122" }, "address": { "address1": "Industrial Area Street 41", "city": "Doha", "country": "QA" }, "currency": "QAR" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "address": { "address1": "Industrial Area Street 41", "address2": "", "city": "Doha", "country": "QA", "postal_code": "", "region": "" }, "contact": { "email": "orders@alnoor.example", "name": "Ahmed Saleh", "phone": "+97455001122" }, "currency": "QAR", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "name": "Al Noor Textiles", "notes": "", "version": 1 } ```
## List suppliers GET `/suppliers` · Scope: `read_inventory` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/suppliers" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/suppliers", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/suppliers", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/suppliers", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/suppliers"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "address": { "address1": "Industrial Area Street 41", "address2": "", "city": "Doha", "country": "QA", "postal_code": "", "region": "" }, "contact": { "email": "orders@alnoor.example", "name": "Ahmed Saleh", "phone": "+97455001122" }, "currency": "QAR", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "name": "Al Noor Textiles", "notes": "", "version": 1 } ] } ```
## Update a supplier PUT `/suppliers/{id}` · Scope: `write_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Al Noor Textiles", "contact": {"name": "Ahmed Saleh", "email": "orders@alnoor.example"}, "currency": "QAR", "notes": "Net 30", "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "name": "Al Noor Textiles", "contact": {"name": "Ahmed Saleh", "email": "orders@alnoor.example"}, "currency": "QAR", "notes": "Net 30", "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "name": "Al Noor Textiles", "contact": {"name": "Ahmed Saleh", "email": "orders@alnoor.example"}, "currency": "QAR", "notes": "Net 30", "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'name' => 'Al Noor Textiles', 'contact' => ['name' => 'Ahmed Saleh', 'email' => 'orders@alnoor.example'], 'currency' => 'QAR', 'notes' => 'Net 30', 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "name": "Al Noor Textiles", "contact": {"name": "Ahmed Saleh", "email": "orders@alnoor.example"}, "currency": "QAR", "notes": "Net 30", "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "name": "Al Noor Textiles", "contact": {"name": "Ahmed Saleh", "email": "orders@alnoor.example"}, "currency": "QAR", "notes": "Net 30", "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "address": { "address1": "", "address2": "", "city": "", "country": "", "postal_code": "", "region": "" }, "contact": {"email": "orders@alnoor.example", "name": "Ahmed Saleh", "phone": ""}, "currency": "QAR", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "name": "Al Noor Textiles", "notes": "Net 30", "version": 2 } ```
## Create a purchase order POST `/purchase-orders` · Scope: `write_inventory` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/purchase-orders" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 20, "cost": "180.00" } ] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 20, "cost": "180.00" } ] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/purchase-orders", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 20, "cost": "180.00", }, ], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'supplier_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000040', 'destination_location_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000023', 'currency' => 'QAR', 'payment_terms' => 'net_30', 'reference' => 'PO-2210', 'lines' => [ [ 'inventory_item_id' => '0193a1b2-515c-7600-8567-54a045bc4ee8', 'qty' => 20, 'cost' => '180.00', ], ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 20, "cost": "180.00" } ] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/purchase-orders", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/purchase-orders"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 20, "cost": "180.00" } ] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_name": "West Bay shop", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000039", "lines": [ { "barcode": "", "cost": "180.00", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000041", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000042", "product_title": "Embroidered linen abaya", "qty": 20, "received_qty": 0, "rejected_qty": 0, "sku": "ABY-LIN-L", "variant_title": "L" } ], "name": "#PO1001", "notes": "", "number": 1001, "ordered_at": null, "payment_terms": "net_30", "received_qty": 0, "reference": "PO-2210", "shipping_cost": "0.00", "status": "draft", "subtotal": "3600.00", "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "supplier_name": "Al Noor Textiles", "total": "3600.00", "total_qty": 20, "version": 1 } ```
## List purchase orders GET `/purchase-orders` · Scope: `read_inventory` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/purchase-orders" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/purchase-orders", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/purchase-orders", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/purchase-orders"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_name": "West Bay shop", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000039", "name": "#PO1001", "notes": "", "number": 1001, "ordered_at": null, "payment_terms": "", "received_qty": 0, "reference": "PO-2210", "shipping_cost": "0.00", "status": "draft", "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "supplier_name": "Al Noor Textiles", "total_qty": 20, "version": 1 } ], "has_more": false } ```
## Get a purchase order GET `/purchase-orders/{id}` · Scope: `read_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_name": "West Bay shop", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000039", "lines": [ { "barcode": "", "cost": "180.00", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000041", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000042", "product_title": "Embroidered linen abaya", "qty": 20, "received_qty": 0, "rejected_qty": 0, "sku": "ABY-LIN-L", "variant_title": "L" } ], "name": "#PO1001", "notes": "", "number": 1001, "ordered_at": null, "payment_terms": "net_30", "received_qty": 0, "reference": "PO-2210", "shipping_cost": "0.00", "status": "draft", "subtotal": "3600.00", "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "supplier_name": "Al Noor Textiles", "total": "3600.00", "total_qty": 20, "version": 1 } ```
## Update a draft purchase order PUT `/purchase-orders/{id}` · Scope: `write_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 24, "cost": "180.00" } ], "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 24, "cost": "180.00" } ], "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 24, "cost": "180.00", }, ], "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'supplier_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000040', 'destination_location_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000023', 'currency' => 'QAR', 'payment_terms' => 'net_30', 'reference' => 'PO-2210', 'lines' => [ [ 'inventory_item_id' => '0193a1b2-515c-7600-8567-54a045bc4ee8', 'qty' => 24, 'cost' => '180.00', ], ], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 24, "cost": "180.00" } ], "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "currency": "QAR", "payment_terms": "net_30", "reference": "PO-2210", "lines": [ { "inventory_item_id": "0193a1b2-515c-7600-8567-54a045bc4ee8", "qty": 24, "cost": "180.00" } ], "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_name": "West Bay shop", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000039", "lines": [ { "barcode": "", "cost": "180.00", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000063", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000042", "product_title": "Embroidered linen abaya", "qty": 24, "received_qty": 0, "rejected_qty": 0, "sku": "ABY-LIN-L", "variant_title": "L" } ], "name": "#PO1001", "notes": "", "number": 1001, "ordered_at": null, "payment_terms": "net_30", "received_qty": 0, "reference": "PO-2210", "shipping_cost": "0.00", "status": "draft", "subtotal": "4320.00", "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "supplier_name": "Al Noor Textiles", "total": "4320.00", "total_qty": 24, "version": 2 } ```
## Mark a purchase order as ordered POST `/purchase-orders/{id}/order` · Scope: `write_inventory` · Needs an `Idempotency-Key` header | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/order" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/order", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/order", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "github.com/google/uuid" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/order", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/order"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_name": "West Bay shop", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000039", "lines": [ { "barcode": "", "cost": "180.00", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000063", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000042", "product_title": "Embroidered linen abaya", "qty": 24, "received_qty": 0, "rejected_qty": 0, "sku": "ABY-LIN-L", "variant_title": "L" } ], "name": "#PO1001", "notes": "", "number": 1001, "ordered_at": "2026-10-18T09:30:00Z", "payment_terms": "net_30", "received_qty": 0, "reference": "PO-2210", "shipping_cost": "0.00", "status": "ordered", "subtotal": "4320.00", "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "supplier_name": "Al Noor Textiles", "total": "4320.00", "total_qty": 24, "version": 3 } ```
## Receive a purchase order POST `/purchase-orders/{id}/receive` · Scope: `write_inventory` · Needs an `Idempotency-Key` header | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/receive" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000041", "accepted": 24, "rejected": 0 } ], "update_cost": true }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/receive", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000041", "accepted": 24, "rejected": 0 } ], "update_cost": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/receive", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000041", "accepted": 24, "rejected": 0, }, ], "update_cost": True, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'lines' => [ [ 'line_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000041', 'accepted' => 24, 'rejected' => 0, ], ], 'update_cost' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000041", "accepted": 24, "rejected": 0 } ], "update_cost": true }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/receive", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/receive"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000041", "accepted": 24, "rejected": 0 } ], "update_cost": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "destination_location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "destination_name": "West Bay shop", "expected_at": null, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000039", "lines": [ { "barcode": "", "cost": "180.00", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000063", "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000042", "product_title": "Embroidered linen abaya", "qty": 24, "received_qty": 24, "rejected_qty": 0, "sku": "ABY-LIN-L", "variant_title": "L" } ], "name": "#PO1001", "notes": "", "number": 1001, "ordered_at": "2026-10-18T09:30:00Z", "payment_terms": "net_30", "received_qty": 24, "reference": "PO-2210", "shipping_cost": "0.00", "status": "received", "subtotal": "4320.00", "supplier_id": "0193a1b2-c3d4-7e5f-8a6b-000000000040", "supplier_name": "Al Noor Textiles", "total": "4320.00", "total_qty": 24, "version": 4 } ```
## Close a purchase order POST `/purchase-orders/{id}/close` · Scope: `write_inventory` Closes an order that won't be received in full; fully received orders close themselves. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/close" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/close", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/close", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/close", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/close"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Download a purchase order as PDF GET `/purchase-orders/{id}/pdf` · Scope: `read_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/pdf" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -o PO-2210.pdf ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/pdf", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); await writeFile("PO-2210.pdf", Buffer.from(await res.arrayBuffer())); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/pdf", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() with open("PO-2210.pdf", "wb") as f: f.write(res.content) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } file_put_contents('PO-2210.pdf', $response); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/pdf", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } out, err := os.Create("PO-2210.pdf") if err != nil { panic(err) } defer out.Close() io.Copy(out, res.Body) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039/pdf"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); await File.WriteAllBytesAsync("PO-2210.pdf", await res.Content.ReadAsByteArrayAsync()); ``` ## Delete a draft purchase order DELETE `/purchase-orders/{id}` · Scope: `write_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/purchase-orders/0193a1b2-c3d4-7e5f-8a6b-000000000039"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Delete a supplier DELETE `/suppliers/{id}` · Scope: `write_inventory` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/suppliers/0193a1b2-c3d4-7e5f-8a6b-000000000040"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Locations URL: https://sooquna.com/docs/api/admin/locations > Admin API 2026-10: Warehouses, shops and pickup points. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Warehouses, shops and pickup points. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Create a location](#create-a-location) | POST | `/locations` | | [List locations](#list-locations) | GET | `/locations` | | [Get a location](#get-a-location) | GET | `/locations/{id}` | | [Update a location](#update-a-location) | PATCH | `/locations/{id}` | | [Deactivate a location](#deactivate-a-location) | POST | `/locations/{id}/deactivate` | | [Activate a location](#activate-a-location) | POST | `/locations/{id}/activate` | | [Delete a location](#delete-a-location) | DELETE | `/locations/{id}` | ## Create a location POST `/locations` · Scope: `write_locations` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/locations" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "West Bay shop", "address": { "address1": "Diplomatic Street, Tower 2", "city": "Doha", "country_code": "QA", "phone": "+97444001100" }, "fulfils_online_orders": true, "pickup_enabled": true, "pickup_instructions": "Ask at the counter.", "pickup_ready_time": "1h" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/locations", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "name": "West Bay shop", "address": { "address1": "Diplomatic Street, Tower 2", "city": "Doha", "country_code": "QA", "phone": "+97444001100" }, "fulfils_online_orders": true, "pickup_enabled": true, "pickup_instructions": "Ask at the counter.", "pickup_ready_time": "1h" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/locations", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "name": "West Bay shop", "address": { "address1": "Diplomatic Street, Tower 2", "city": "Doha", "country_code": "QA", "phone": "+97444001100", }, "fulfils_online_orders": True, "pickup_enabled": True, "pickup_instructions": "Ask at the counter.", "pickup_ready_time": "1h", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'name' => 'West Bay shop', 'address' => [ 'address1' => 'Diplomatic Street, Tower 2', 'city' => 'Doha', 'country_code' => 'QA', 'phone' => '+97444001100', ], 'fulfils_online_orders' => true, 'pickup_enabled' => true, 'pickup_instructions' => 'Ask at the counter.', 'pickup_ready_time' => '1h', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "name": "West Bay shop", "address": { "address1": "Diplomatic Street, Tower 2", "city": "Doha", "country_code": "QA", "phone": "+97444001100" }, "fulfils_online_orders": true, "pickup_enabled": true, "pickup_instructions": "Ask at the counter.", "pickup_ready_time": "1h" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/locations", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/locations"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "name": "West Bay shop", "address": { "address1": "Diplomatic Street, Tower 2", "city": "Doha", "country_code": "QA", "phone": "+97444001100" }, "fulfils_online_orders": true, "pickup_enabled": true, "pickup_instructions": "Ask at the counter.", "pickup_ready_time": "1h" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "address": { "address1": "Diplomatic Street, Tower 2", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "", "last_name": "", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" }, "fulfils_online_orders": true, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "is_active": true, "name": "West Bay shop", "on_hand": 0, "phone": "", "pickup_enabled": true, "pickup_instructions": "Ask at the counter.", "pickup_ready_time": "1h", "position": 1, "stocked_items": 0, "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## List locations GET `/locations` · Scope: `read_locations` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/locations" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/locations", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/locations", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/locations", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/locations"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "address": { "address1": "Diplomatic Street, Tower 2", "address2": "", "city": "Doha", "company": "", "country_code": "QA", "extra": {}, "first_name": "", "last_name": "", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" }, "fulfils_online_orders": true, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "is_active": true, "name": "West Bay shop", "on_hand": 0, "phone": "", "pickup_enabled": true, "pickup_instructions": "Ask at the counter.", "pickup_ready_time": "1h", "position": 1, "stocked_items": 0, "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ] } ```
## Get a location GET `/locations/{id}` · Scope: `read_locations` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "address": { "address1": "Street 220, Building 14", "address2": "", "city": "Al Wakrah", "company": "", "country_code": "QA", "extra": {}, "first_name": "", "last_name": "", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" }, "fulfils_online_orders": true, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "is_active": true, "name": "Al Wakrah warehouse", "on_hand": 0, "phone": "", "pickup_enabled": true, "pickup_instructions": "Collect from the side gate, 9am–9pm.", "pickup_ready_time": "2h", "position": 2, "stocked_items": 0, "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## Update a location PATCH `/locations/{id}` · Scope: `write_locations` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Al Wakrah warehouse", "pickup_enabled": false, "version": 1}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"name": "Al Wakrah warehouse", "pickup_enabled": false, "version": 1}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "name": "Al Wakrah warehouse", "pickup_enabled": False, "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'name' => 'Al Wakrah warehouse', 'pickup_enabled' => false, 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"name": "Al Wakrah warehouse", "pickup_enabled": false, "version": 1}` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"name": "Al Wakrah warehouse", "pickup_enabled": false, "version": 1} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "address": { "address1": "", "address2": "", "city": "", "company": "", "country_code": "QA", "extra": {}, "first_name": "", "last_name": "", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" }, "fulfils_online_orders": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "is_active": true, "name": "Al Wakrah warehouse", "on_hand": 0, "phone": "", "pickup_enabled": false, "pickup_instructions": "", "pickup_ready_time": "1h", "position": 2, "stocked_items": 0, "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Deactivate a location POST `/locations/{id}/deactivate` · Scope: `write_locations` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/deactivate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/deactivate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/deactivate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/deactivate", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/deactivate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "address": { "address1": "", "address2": "", "city": "", "company": "", "country_code": "QA", "extra": {}, "first_name": "", "last_name": "", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" }, "fulfils_online_orders": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "is_active": false, "name": "Al Wakrah warehouse", "on_hand": 0, "phone": "", "pickup_enabled": false, "pickup_instructions": "", "pickup_ready_time": "1h", "position": 2, "stocked_items": 0, "updated_at": "2026-10-18T09:30:00Z", "version": 3 } ```
## Activate a location POST `/locations/{id}/activate` · Scope: `write_locations` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/activate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/activate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/activate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/activate", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849/activate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "address": { "address1": "", "address2": "", "city": "", "company": "", "country_code": "QA", "extra": {}, "first_name": "", "last_name": "", "latitude": null, "longitude": null, "phone": "", "province_code": "", "zip": "" }, "fulfils_online_orders": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "is_active": true, "name": "Al Wakrah warehouse", "on_hand": 0, "phone": "", "pickup_enabled": false, "pickup_instructions": "", "pickup_ready_time": "1h", "position": 2, "stocked_items": 0, "updated_at": "2026-10-18T09:30:00Z", "version": 4 } ```
## Delete a location DELETE `/locations/{id}` · Scope: `write_locations` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/locations/0193a1b2-c810-7698-8039-998bb6c1a849"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Metaobjects URL: https://sooquna.com/docs/api/admin/metaobjects > Admin API 2026-10: Metafields, their definitions, and metaobjects. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Metafields, their definitions, and metaobjects. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Create a custom field definition](#create-a-custom-field-definition) | POST | `/metafield-definitions` | | [List custom field definitions](#list-custom-field-definitions) | GET | `/metafield-definitions` | | [Update a custom field definition](#update-a-custom-field-definition) | PATCH | `/metafield-definitions/{id}` | | [Set custom field values](#set-custom-field-values) | PUT | `/metafields` | | [List a resource's custom field values](#list-a-resource-s-custom-field-values) | GET | `/metafields` | | [Delete a custom field definition](#delete-a-custom-field-definition) | DELETE | `/metafield-definitions/{id}` | | [Create a custom content type](#create-a-custom-content-type) | POST | `/metaobject-definitions` | | [List custom content types](#list-custom-content-types) | GET | `/metaobject-definitions` | | [Update a custom content type](#update-a-custom-content-type) | PUT | `/metaobject-definitions/{id}` | | [Create a custom content entry](#create-a-custom-content-entry) | POST | `/metaobjects` | | [List custom content entries](#list-custom-content-entries) | GET | `/metaobjects` | | [Get a custom content entry](#get-a-custom-content-entry) | GET | `/metaobjects/{id}` | | [Update a custom content entry](#update-a-custom-content-entry) | PUT | `/metaobjects/{id}` | | [Delete a custom content entry](#delete-a-custom-content-entry) | DELETE | `/metaobjects/{id}` | | [Delete a custom content type](#delete-a-custom-content-type) | DELETE | `/metaobject-definitions/{id}` | ## Create a custom field definition POST `/metafield-definitions` · Scope: `write_metaobjects` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/metafield-definitions" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric", "type": "single_line_text", "storefront_access": true }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metafield-definitions", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric", "type": "single_line_text", "storefront_access": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/metafield-definitions", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric", "type": "single_line_text", "storefront_access": True, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'owner_type' => 'product', 'namespace' => 'custom', 'key' => 'fabric', 'name' => 'Fabric', 'type' => 'single_line_text', 'storefront_access' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric", "type": "single_line_text", "storefront_access": true }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/metafield-definitions", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/metafield-definitions"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric", "type": "single_line_text", "storefront_access": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "description": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000031", "key": "fabric", "name": "Fabric", "namespace": "custom", "owner_type": "product", "pinned_position": null, "storefront_access": true, "type": "single_line_text", "updated_at": "2026-10-18T09:30:00Z", "validations": {}, "version": 1 } ```
## List custom field definitions GET `/metafield-definitions` · Scope: `read_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `owner_type` | query | For example `product`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/metafield-definitions?owner_type=product" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metafield-definitions?owner_type=product", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/metafield-definitions?owner_type=product", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/metafield-definitions?owner_type=product", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/metafield-definitions?owner_type=product"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "description": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000031", "key": "fabric", "name": "Fabric", "namespace": "custom", "owner_type": "product", "pinned_position": null, "storefront_access": true, "type": "single_line_text", "updated_at": "2026-10-18T09:30:00Z", "validations": {}, "version": 1 } ] } ```
## Update a custom field definition PATCH `/metafield-definitions/{id}` · Scope: `write_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric and care", "type": "single_line_text", "storefront_access": true, "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric and care", "type": "single_line_text", "storefront_access": true, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric and care", "type": "single_line_text", "storefront_access": True, "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'owner_type' => 'product', 'namespace' => 'custom', 'key' => 'fabric', 'name' => 'Fabric and care', 'type' => 'single_line_text', 'storefront_access' => true, 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric and care", "type": "single_line_text", "storefront_access": true, "version": 1 }` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "owner_type": "product", "namespace": "custom", "key": "fabric", "name": "Fabric and care", "type": "single_line_text", "storefront_access": true, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "description": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000031", "key": "fabric", "name": "Fabric and care", "namespace": "custom", "owner_type": "product", "pinned_position": null, "storefront_access": true, "type": "single_line_text", "updated_at": "2026-10-18T09:30:00Z", "validations": {}, "version": 2 } ```
## Set custom field values PUT `/metafields` · Scope: `write_metaobjects` A null value deletes the field. ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/metafields" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "owner_type": "product", "owner_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "metafields": [{"namespace": "custom", "key": "fabric", "value": "\"100% linen\""}] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metafields", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "owner_type": "product", "owner_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "metafields": [{"namespace": "custom", "key": "fabric", "value": "\"100% linen\""}] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/metafields", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "owner_type": "product", "owner_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "metafields": [ { "namespace": "custom", "key": "fabric", "value": "\"100% linen\"", }, ], }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'owner_type' => 'product', 'owner_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000005', 'metafields' => [ [ 'namespace' => 'custom', 'key' => 'fabric', 'value' => '"100% linen"', ], ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "owner_type": "product", "owner_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "metafields": [{"namespace": "custom", "key": "fabric", "value": "\"100% linen\""}] }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/metafields", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/metafields"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "owner_type": "product", "owner_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "metafields": [{"namespace": "custom", "key": "fabric", "value": "\"100% linen\""}] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000032", "key": "fabric", "namespace": "custom", "type": "single_line_text", "updated_at": "2026-10-18T09:30:00Z", "value": "\"100% linen\"" } ] } ```
## List a resource's custom field values GET `/metafields` · Scope: `read_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `owner_type` | query | For example `product`. | | `owner_id` | query | An ID, as in the example. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/metafields?owner_type=product&owner_id=0193a1b2-c3d4-7e5f-8a6b-000000000005" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metafields?owner_type=product&owner_id=0193a1b2-c3d4-7e5f-8a6b-000000000005", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/metafields?owner_type=product&owner_id=0193a1b2-c3d4-7e5f-8a6b-000000000005", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/metafields?owner_type=product&owner_id=0193a1b2-c3d4-7e5f-8a6b-000000000005", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/metafields?owner_type=product&owner_id=0193a1b2-c3d4-7e5f-8a6b-000000000005"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000032", "key": "fabric", "namespace": "custom", "type": "single_line_text", "updated_at": "2026-10-18T09:30:00Z", "value": "\"100% linen\"" } ] } ```
## Delete a custom field definition DELETE `/metafield-definitions/{id}` · Scope: `write_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/metafield-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000031"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Create a custom content type POST `/metaobject-definitions` · Scope: `write_metaobjects` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "designer", "name": "Designer", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": true }, {"key": "city", "name": "City", "type": "single_line_text"} ], "display_name_field": "name", "capabilities": {"publishable": true, "renderable": true, "translatable": true} }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobject-definitions", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "type": "designer", "name": "Designer", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": true }, {"key": "city", "name": "City", "type": "single_line_text"} ], "display_name_field": "name", "capabilities": {"publishable": true, "renderable": true, "translatable": true} }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "type": "designer", "name": "Designer", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": True, }, {"key": "city", "name": "City", "type": "single_line_text"}, ], "display_name_field": "name", "capabilities": {"publishable": True, "renderable": True, "translatable": True}, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'type' => 'designer', 'name' => 'Designer', 'fields' => [ [ 'key' => 'name', 'name' => 'Name', 'type' => 'single_line_text', 'required' => true, ], [ 'key' => 'city', 'name' => 'City', 'type' => 'single_line_text', ], ], 'display_name_field' => 'name', 'capabilities' => [ 'publishable' => true, 'renderable' => true, 'translatable' => true, ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "type": "designer", "name": "Designer", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": true }, {"key": "city", "name": "City", "type": "single_line_text"} ], "display_name_field": "name", "capabilities": {"publishable": true, "renderable": true, "translatable": true} }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "type": "designer", "name": "Designer", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": true }, {"key": "city", "name": "City", "type": "single_line_text"} ], "display_name_field": "name", "capabilities": {"publishable": true, "renderable": true, "translatable": true} } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "capabilities": {"publishable": true, "renderable": true, "translatable": true}, "description": "", "display_name_field": "name", "entries_count": 0, "fields": [ { "key": "name", "name": "Name", "required": true, "type": "single_line_text", "validations": {} }, { "key": "city", "name": "City", "required": false, "type": "single_line_text", "validations": {} } ], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000033", "name": "Designer", "storefront_access": false, "type": "designer", "version": 1 } ```
## List custom content types GET `/metaobject-definitions` · Scope: `read_metaobjects` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobject-definitions", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "capabilities": {"publishable": true, "renderable": true, "translatable": true}, "description": "", "display_name_field": "name", "entries_count": 0, "fields": [ { "key": "name", "name": "Name", "required": true, "type": "single_line_text", "validations": {} }, { "key": "city", "name": "City", "required": false, "type": "single_line_text", "validations": {} } ], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000033", "name": "Designer", "storefront_access": false, "type": "designer", "version": 1 } ] } ```
## Update a custom content type PUT `/metaobject-definitions/{id}` · Scope: `write_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "designer", "name": "Designers", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": true }, {"key": "city", "name": "City", "type": "single_line_text"} ], "display_name_field": "name", "capabilities": {"publishable": true, "renderable": true, "translatable": true}, "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "type": "designer", "name": "Designers", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": true }, {"key": "city", "name": "City", "type": "single_line_text"} ], "display_name_field": "name", "capabilities": {"publishable": true, "renderable": true, "translatable": true}, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "type": "designer", "name": "Designers", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": True, }, {"key": "city", "name": "City", "type": "single_line_text"}, ], "display_name_field": "name", "capabilities": {"publishable": True, "renderable": True, "translatable": True}, "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'type' => 'designer', 'name' => 'Designers', 'fields' => [ [ 'key' => 'name', 'name' => 'Name', 'type' => 'single_line_text', 'required' => true, ], [ 'key' => 'city', 'name' => 'City', 'type' => 'single_line_text', ], ], 'display_name_field' => 'name', 'capabilities' => [ 'publishable' => true, 'renderable' => true, 'translatable' => true, ], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "type": "designer", "name": "Designers", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": true }, {"key": "city", "name": "City", "type": "single_line_text"} ], "display_name_field": "name", "capabilities": {"publishable": true, "renderable": true, "translatable": true}, "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "type": "designer", "name": "Designers", "fields": [ { "key": "name", "name": "Name", "type": "single_line_text", "required": true }, {"key": "city", "name": "City", "type": "single_line_text"} ], "display_name_field": "name", "capabilities": {"publishable": true, "renderable": true, "translatable": true}, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "capabilities": {"publishable": true, "renderable": true, "translatable": true}, "description": "", "display_name_field": "name", "entries_count": 0, "fields": [ { "key": "name", "name": "Name", "required": true, "type": "single_line_text", "validations": {} }, { "key": "city", "name": "City", "required": false, "type": "single_line_text", "validations": {} } ], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000033", "name": "Designers", "storefront_access": false, "type": "designer", "version": 2 } ```
## Create a custom content entry POST `/metaobjects` · Scope: `write_metaobjects` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/metaobjects" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "designer", "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Doha\""} }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobjects", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "type": "designer", "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Doha\""} }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/metaobjects", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "type": "designer", "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Doha\""}, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'type' => 'designer', 'handle' => 'layla-ahmad', 'status' => 'active', 'fields' => ['name' => '"Layla Ahmad"', 'city' => '"Doha"'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "type": "designer", "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Doha\""} }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/metaobjects", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/metaobjects"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "type": "designer", "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Doha\""} } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "display_name": "\"Layla Ahmad\"", "fields": {"city": "\"Doha\"", "name": "\"Layla Ahmad\""}, "handle": "layla-ahmad", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000034", "status": "active", "type": "designer", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## List custom content entries GET `/metaobjects` · Scope: `read_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `type` | query | For example `designer`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/metaobjects?type=designer" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobjects?type=designer", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/metaobjects?type=designer", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/metaobjects?type=designer", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/metaobjects?type=designer"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "display_name": "\"Layla Ahmad\"", "fields": {"city": "\"Doha\"", "name": "\"Layla Ahmad\""}, "handle": "layla-ahmad", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000034", "status": "active", "type": "designer", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ], "page_info": {"has_next_page": false} } ```
## Get a custom content entry GET `/metaobjects/{id}` · Scope: `read_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "display_name": "\"Layla Ahmad\"", "fields": {"city": "\"Doha\"", "name": "\"Layla Ahmad\""}, "handle": "layla-ahmad", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000034", "status": "active", "type": "designer", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## Update a custom content entry PUT `/metaobjects/{id}` · Scope: `write_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Lusail\""}, "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Lusail\""}, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Lusail\""}, "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'handle' => 'layla-ahmad', 'status' => 'active', 'fields' => ['name' => '"Layla Ahmad"', 'city' => '"Lusail"'], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Lusail\""}, "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "handle": "layla-ahmad", "status": "active", "fields": {"name": "\"Layla Ahmad\"", "city": "\"Lusail\""}, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "display_name": "\"Layla Ahmad\"", "fields": {"city": "\"Lusail\"", "name": "\"Layla Ahmad\""}, "handle": "layla-ahmad", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000034", "status": "active", "type": "designer", "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Delete a custom content entry DELETE `/metaobjects/{id}` · Scope: `write_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/metaobjects/0193a1b2-c3d4-7e5f-8a6b-000000000034"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Delete a custom content type DELETE `/metaobject-definitions/{id}` · Scope: `write_metaobjects` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/metaobject-definitions/0193a1b2-c3d4-7e5f-8a6b-000000000033"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
--- # Orders URL: https://sooquna.com/docs/api/admin/orders > Admin API 2026-10: Orders, transactions, refunds and abandoned checkouts (the last 60 days without read_all_orders). {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Orders, transactions, refunds and abandoned checkouts (the last 60 days without read_all_orders). Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [List orders](#list-orders) | GET | `/orders` | | [Get an order](#get-an-order) | GET | `/orders/{id}` | | [Update an order](#update-an-order) | PATCH | `/orders/{id}` | | [Record payment of an order](#record-payment-of-an-order) | POST | `/orders/{id}/mark-paid` | | [Calculate a refund](#calculate-a-refund) | POST | `/orders/{id}/refunds/calculate` | | [Refund an order](#refund-an-order) | POST | `/orders/{id}/refunds` | | [Cancel an order](#cancel-an-order) | POST | `/orders/{id}/cancel` | | [Archive an order](#archive-an-order) | POST | `/orders/{id}/close` | | [Unarchive an order](#unarchive-an-order) | POST | `/orders/{id}/reopen` | | [Confirm a cash-on-delivery order](#confirm-a-cash-on-delivery-order) | POST | `/orders/{id}/cod-confirm` | | [List an order's tax invoices](#list-an-order-s-tax-invoices) | GET | `/orders/{id}/invoices` | | [Issue a tax invoice for an order](#issue-a-tax-invoice-for-an-order) | POST | `/orders/{id}/invoices` | | [List abandoned checkouts](#list-abandoned-checkouts) | GET | `/abandoned-checkouts` | | [Get an abandoned checkout](#get-an-abandoned-checkout) | GET | `/abandoned-checkouts/{id}` | | [List tax invoices](#list-tax-invoices) | GET | `/invoices` | | [Get a tax invoice](#get-a-tax-invoice) | GET | `/invoices/{id}` | | [Download a tax invoice as PDF](#download-a-tax-invoice-as-pdf) | GET | `/invoices/{id}/pdf` | ## List orders GET `/orders` · Scope: `read_orders` | Parameter | In | Description | | --- | --- | --- | | `financial_status` | query | For example `pending`. | | `fulfillment_status` | query | For example `unfulfilled`. | | `limit` | query | For example `20`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/orders?financial_status=pending&fulfillment_status=unfulfilled&limit=20" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders?financial_status=pending&fulfillment_status=unfulfilled&limit=20", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/orders?financial_status=pending&fulfillment_status=unfulfilled&limit=20", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/orders?financial_status=pending&fulfillment_status=unfulfilled&limit=20", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/orders?financial_status=pending&fulfillment_status=unfulfilled&limit=20"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "cancelled_at": null, "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "email": "noora@example.com", "financial_status": "pending", "fulfillment_status": "unfulfilled", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "name": "#1001", "number": 1001, "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "sample": false, "source": "draft", "state": "open", "tags": [], "total": "420.00", "total_outstanding": "420.00" } ], "page_info": {"has_next_page": false} } ```
## Get an order GET `/orders/{id}` · Scope: `read_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": null, "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "pending", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "open" } ], "fulfillment_status": "unfulfilled", "fulfillments": [], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 0, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 0, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "0.00", "note": "", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "open", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": [], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "420.00", "total_received": "0.00", "total_refunded": "0.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [], "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## Update an order PATCH `/orders/{id}` · Scope: `write_orders` Change the note, tags, contact details, addresses or attributes; leave out what doesn't change. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "note": "Call before delivery", "tags": ["phone", "priority"], "version": 2 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "note": "Call before delivery", "tags": ["phone", "priority"], "version": 2 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "note": "Call before delivery", "tags": ["phone", "priority"], "version": 2, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'note' => 'Call before delivery', 'tags' => ['phone', 'priority'], 'version' => 2, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "note": "Call before delivery", "tags": ["phone", "priority"], "version": 2 }` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "note": "Call before delivery", "tags": ["phone", "priority"], "version": 2 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": null, "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "pending", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "open" } ], "fulfillment_status": "unfulfilled", "fulfillments": [], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 0, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 0, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "0.00", "note": "Call before delivery", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "open", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": ["phone", "priority"], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "420.00", "total_received": "0.00", "total_refunded": "0.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [], "updated_at": "2026-10-18T09:30:00Z", "version": 3 } ```
## Record payment of an order POST `/orders/{id}/mark-paid` · Scope: `write_orders` · Needs an `Idempotency-Key` header | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/mark-paid" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/mark-paid", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/mark-paid", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "github.com/google/uuid" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/mark-paid", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/mark-paid"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": null, "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "paid", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "open" } ], "fulfillment_status": "unfulfilled", "fulfillments": [], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 0, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 0, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "420.00", "note": "Call before delivery", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "open", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": ["phone", "priority"], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "0.00", "total_received": "420.00", "total_refunded": "0.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [ { "actor": "Docs", "amount": "420.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000051", "kind": "sale", "method": "manual", "provider": "manual", "status": "success", "test": false } ], "updated_at": "2026-10-18T09:30:00Z", "version": 4 } ```
## Calculate a refund POST `/orders/{id}/refunds/calculate` · Scope: `write_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds/calculate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "restock": true }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds/calculate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "restock": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds/calculate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, }, ], "restock": True, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'lines' => [ [ 'line_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000037', 'quantity' => 1, ], ], 'restock' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "restock": true }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds/calculate", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds/calculate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "restock": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "available": "420.00", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "subtotal": "405.00", "tax": "0.00" } ], "shipping": "0.00", "shipping_refundable": "15.00", "subtotal": "405.00", "suggested": "405.00", "tax": "0.00" } ```
## Refund an order POST `/orders/{id}/refunds` · Scope: `write_orders` · Needs an `Idempotency-Key` header Refund lines (with restock), shipping, or an amount. Send an idempotency_key so a retried request isn't refunded twice. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "restock": true, "notify_customer": true, "note": "Wrong size", "idempotency_key": "refund-1001-1" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "restock": true, "notify_customer": true, "note": "Wrong size", "idempotency_key": "refund-1001-1" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, }, ], "restock": True, "notify_customer": True, "note": "Wrong size", "idempotency_key": "refund-1001-1", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'lines' => [ [ 'line_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000037', 'quantity' => 1, ], ], 'restock' => true, 'notify_customer' => true, 'note' => 'Wrong size', 'idempotency_key' => 'refund-1001-1', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "restock": true, "notify_customer": true, "note": "Wrong size", "idempotency_key": "refund-1001-1" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/refunds"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "lines": [{"line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1}], "restock": true, "notify_customer": true, "note": "Wrong size", "idempotency_key": "refund-1001-1" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": null, "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "partially_refunded", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 0 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "closed" } ], "fulfillment_status": "fulfilled", "fulfillments": [ { "created_at": "2026-10-18T09:30:00Z", "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000050", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "name": "#1001-F1", "shipment_status": "in_transit", "status": "success", "tracking_company": "Aramex", "tracking_number": "47012233442", "tracking_url": "https://www.aramex.com/track/results?ShipmentNumber=47012233442" } ], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 1, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 1, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "15.00", "note": "Call before delivery", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [ { "amount": "405.00", "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000055", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "quantity": 1, "restock_type": "return", "subtotal": "405.00", "tax": "0.00" } ], "note": "Wrong size", "restock": true, "shipping": "0.00" } ], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "open", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": ["phone", "priority"], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "0.00", "total_received": "420.00", "total_refunded": "405.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [ { "actor": "Docs", "amount": "420.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000051", "kind": "sale", "method": "manual", "provider": "manual", "status": "success", "test": false }, { "actor": "Docs", "amount": "405.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000056", "kind": "refund", "method": "manual", "provider": "manual", "status": "success", "test": false } ], "updated_at": "2026-10-18T09:30:00Z", "version": 6 } ```
## Cancel an order POST `/orders/{id}/cancel` · Scope: `write_orders` · Needs an `Idempotency-Key` header Reasons: customer, inventory, fraud, declined, staff, other. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cancel" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "reason": "customer", "refund": true, "restock": true, "notify_customer": true }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cancel", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "reason": "customer", "refund": true, "restock": true, "notify_customer": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cancel", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Idempotency-Key": str(uuid.uuid4()), }, json={ "reason": "customer", "refund": True, "restock": True, "notify_customer": True, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'reason' => 'customer', 'refund' => true, 'restock' => true, 'notify_customer' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" "github.com/google/uuid" ) func main() { body := `{ "reason": "customer", "refund": true, "restock": true, "notify_customer": true }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cancel", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Idempotency-Key", uuid.NewString()) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cancel"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString()); req.Content = new StringContent(""" { "reason": "customer", "refund": true, "restock": true, "notify_customer": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Archive an order POST `/orders/{id}/close` · Scope: `write_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/close" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/close", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/close", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/close", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/close"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": "2026-10-18T09:30:00Z", "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "partially_refunded", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 0 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "closed" } ], "fulfillment_status": "fulfilled", "fulfillments": [ { "created_at": "2026-10-18T09:30:00Z", "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000050", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "name": "#1001-F1", "shipment_status": "in_transit", "status": "success", "tracking_company": "Aramex", "tracking_number": "47012233442", "tracking_url": "https://www.aramex.com/track/results?ShipmentNumber=47012233442" } ], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 1, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 1, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "15.00", "note": "Call before delivery", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [ { "amount": "405.00", "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000055", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "quantity": 1, "restock_type": "return", "subtotal": "405.00", "tax": "0.00" } ], "note": "Wrong size", "restock": true, "shipping": "0.00" } ], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "archived", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": ["phone", "priority"], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "0.00", "total_received": "420.00", "total_refunded": "405.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [ { "actor": "Docs", "amount": "420.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000051", "kind": "sale", "method": "manual", "provider": "manual", "status": "success", "test": false }, { "actor": "Docs", "amount": "405.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000056", "kind": "refund", "method": "manual", "provider": "manual", "status": "success", "test": false } ], "updated_at": "2026-10-18T09:30:00Z", "version": 7 } ```
## Unarchive an order POST `/orders/{id}/reopen` · Scope: `write_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/reopen" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/reopen", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/reopen", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/reopen", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/reopen"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "attributes": {}, "billing_address": null, "buyer_accepts_marketing": false, "cancel_reason": "", "cancelled_at": null, "checkout_id": null, "closed_at": null, "cod_status": "", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "customer": { "email": "noora@example.com", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000007", "name": "Noora Al-Kuwari", "orders_count": 1, "phone": "+97455123456" }, "delivery_method": "shipping", "delivery_title": "Doha delivery", "discount_applications": [], "discount_codes": [], "draft_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000013", "email": "noora@example.com", "financial_status": "partially_refunded", "fulfillment_orders": [ { "delivery_method": "shipping", "hold_reason": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1, "remaining": 0 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "status": "closed" } ], "fulfillment_status": "fulfilled", "fulfillments": [ { "created_at": "2026-10-18T09:30:00Z", "fulfillment_order_id": "0193a1b2-c3d4-7e5f-8a6b-000000000036", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000050", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "quantity": 1 } ], "location": { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "name": "West Bay shop" }, "name": "#1001-F1", "shipment_status": "in_transit", "status": "success", "tracking_company": "Aramex", "tracking_number": "47012233442", "tracking_url": "https://www.aramex.com/track/results?ShipmentNumber=47012233442" } ], "gift": false, "gift_message": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000035", "item_count": 1, "lines": [ { "discount_allocations": [{"amount": 4500, "class": "order", "title": "Loyal customer"}], "fulfilled_quantity": 1, "gift_card": false, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "image": "", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "original_price": "520.00", "price": "450.00", "product_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "properties": {}, "quantity": 1, "refunded_quantity": 1, "requires_shipping": true, "sku": "ABY-LIN-M", "tax": "0.00", "tax_lines": [], "taxable": true, "title": "Embroidered linen abaya", "total": "405.00", "total_discount": "45.00", "variant_id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "variant_title": "M", "vendor": "Layla", "weight_grams": 0 } ], "locale": "en", "name": "#1001", "net_payment": "15.00", "note": "Call before delivery", "number": 1001, "order_discount": "45.00", "payment_fee": "0.00", "payment_method": "manual", "phone": "+97455123456", "processed_at": "2026-10-18T09:30:00Z", "refunds": [ { "amount": "405.00", "created_at": "2026-10-18T09:30:00Z", "created_by": "Docs", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000055", "lines": [ { "line_id": "0193a1b2-c3d4-7e5f-8a6b-000000000037", "location_id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "quantity": 1, "restock_type": "return", "subtotal": "405.00", "tax": "0.00" } ], "note": "Wrong size", "restock": true, "shipping": "0.00" } ], "sample": false, "shipping_address": null, "shipping_line": { "final": 1500, "kind": "shipping", "price": 1500, "title": "Doha delivery" }, "source": "draft", "state": "open", "status_url": "https://shop.sooquna.test/orders/01a14f9f314a7de682d35010a325f162", "subtotal": "450.00", "tags": ["phone", "priority"], "tax_lines": [], "taxes_included": true, "tip": "0.00", "token": "01a14f9f314a7de682d35010a325f162", "total": "420.00", "total_discounts": "45.00", "total_outstanding": "0.00", "total_received": "420.00", "total_refunded": "405.00", "total_shipping": "15.00", "total_tax": "0.00", "transactions": [ { "actor": "Docs", "amount": "420.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000051", "kind": "sale", "method": "manual", "provider": "manual", "status": "success", "test": false }, { "actor": "Docs", "amount": "405.00", "created_at": "2026-10-18T09:30:00Z", "error_code": "", "gateway_ref": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000056", "kind": "refund", "method": "manual", "provider": "manual", "status": "success", "test": false } ], "updated_at": "2026-10-18T09:30:00Z", "version": 8 } ```
## Confirm a cash-on-delivery order POST `/orders/{id}/cod-confirm` · Scope: `write_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cod-confirm" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cod-confirm", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cod-confirm", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cod-confirm", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/cod-confirm"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List an order's tax invoices GET `/orders/{id}/invoices` · Scope: `read_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
## Issue a tax invoice for an order POST `/orders/{id}/invoices` · Scope: `write_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/invoices"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List abandoned checkouts GET `/abandoned-checkouts` · Scope: `read_orders` | Parameter | In | Description | | --- | --- | --- | | `limit` | query | For example `20`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts?limit=20" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts?limit=20", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts?limit=20", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts?limit=20", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts?limit=20"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": [], "page_info": {"end_cursor": "", "has_next_page": false}} ```
## Get an abandoned checkout GET `/abandoned-checkouts/{id}` · Scope: `read_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts/0193a1b2-6e4e-7021-831d-c062f3224a2f" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts/0193a1b2-6e4e-7021-831d-c062f3224a2f", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts/0193a1b2-6e4e-7021-831d-c062f3224a2f", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts/0193a1b2-6e4e-7021-831d-c062f3224a2f", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/abandoned-checkouts/0193a1b2-6e4e-7021-831d-c062f3224a2f"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List tax invoices GET `/invoices` · Scope: `read_orders` | Parameter | In | Description | | --- | --- | --- | | `from` | query | For example `2026-10-01`. | | `to` | query | For example `2026-10-31`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/invoices?from=2026-10-01&to=2026-10-31" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/invoices?from=2026-10-01&to=2026-10-31", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/invoices?from=2026-10-01&to=2026-10-31", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/invoices?from=2026-10-01&to=2026-10-31", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/invoices?from=2026-10-01&to=2026-10-31"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
## Get a tax invoice GET `/invoices/{id}` · Scope: `read_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-fcce-7039-8c02-ad9a810b3006" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-fcce-7039-8c02-ad9a810b3006", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-fcce-7039-8c02-ad9a810b3006", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-fcce-7039-8c02-ad9a810b3006", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-fcce-7039-8c02-ad9a810b3006"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Download a tax invoice as PDF GET `/invoices/{id}/pdf` · Scope: `read_orders` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-a106-72b4-8b5d-6a45297a2d2b/pdf" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -o invoice.pdf ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-a106-72b4-8b5d-6a45297a2d2b/pdf", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); await writeFile("invoice.pdf", Buffer.from(await res.arrayBuffer())); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-a106-72b4-8b5d-6a45297a2d2b/pdf", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() with open("invoice.pdf", "wb") as f: f.write(res.content) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } file_put_contents('invoice.pdf', $response); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-a106-72b4-8b5d-6a45297a2d2b/pdf", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } out, err := os.Create("invoice.pdf") if err != nil { panic(err) } defer out.Close() io.Copy(out, res.Body) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/invoices/0193a1b2-a106-72b4-8b5d-6a45297a2d2b/pdf"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); await File.WriteAllBytesAsync("invoice.pdf", await res.Content.ReadAsByteArrayAsync()); ``` --- # Products URL: https://sooquna.com/docs/api/admin/products > Admin API 2026-10: Products, variants, collections and the product taxonomy. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Products, variants, collections and the product taxonomy. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Create a product](#create-a-product) | POST | `/products` | | [List products](#list-products) | GET | `/products` | | [Get a product](#get-a-product) | GET | `/products/{id}` | | [List a product's variants](#list-a-product-s-variants) | GET | `/products/{id}/variants` | | [Update a product](#update-a-product) | PUT | `/products/{id}` | | [Duplicate a product](#duplicate-a-product) | POST | `/products/{id}/duplicate` | | [Change many products at once](#change-many-products-at-once) | POST | `/products/bulk` | | [Delete a product](#delete-a-product) | DELETE | `/products/{id}` | | [Add an image to a product](#add-an-image-to-a-product) | POST | `/products/{id}/media` | | [Reorder a product's media](#reorder-a-product-s-media) | PUT | `/products/{id}/media/order` | | [Update an image's alt text](#update-an-image-s-alt-text) | PATCH | `/products/{id}/media/{media_id}` | | [Remove an image from a product](#remove-an-image-from-a-product) | DELETE | `/products/{id}/media/{media_id}` | | [Create a collection](#create-a-collection) | POST | `/collections` | | [List collections](#list-collections) | GET | `/collections` | | [Get a collection](#get-a-collection) | GET | `/collections/{id}` | | [Update a collection](#update-a-collection) | PUT | `/collections/{id}` | | [List a collection's products](#list-a-collection-s-products) | GET | `/collections/{id}/products` | | [Add products to a manual collection](#add-products-to-a-manual-collection) | POST | `/collections/{id}/products` | | [Reorder a manual collection's products](#reorder-a-manual-collection-s-products) | PUT | `/collections/{id}/products/order` | | [Remove products from a manual collection](#remove-products-from-a-manual-collection) | POST | `/collections/{id}/products/remove` | | [Delete a collection](#delete-a-collection) | DELETE | `/collections/{id}` | | [Search the product category taxonomy](#search-the-product-category-taxonomy) | GET | `/taxonomy` | | [Get a product category](#get-a-product-category) | GET | `/taxonomy/{id}` | ## Create a product POST `/products` · Scope: `write_products` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/products" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Embroidered linen abaya", "body_html": "

Soft linen, hand-embroidered in Doha.

", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}] } ], "variants": [ { "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S" }, { "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M" }, {"options": ["L"], "price": "450.00", "sku": "ABY-LIN-L"} ] }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "title": "Embroidered linen abaya", "body_html": "

Soft linen, hand-embroidered in Doha.

", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}] } ], "variants": [ { "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S" }, { "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M" }, {"options": ["L"], "price": "450.00", "sku": "ABY-LIN-L"} ] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/products", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "title": "Embroidered linen abaya", "body_html": "

Soft linen, hand-embroidered in Doha.

", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}], }, ], "variants": [ { "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S", }, { "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M", }, {"options": ["L"], "price": "450.00", "sku": "ABY-LIN-L"}, ], }, ) res.raise_for_status() print(res.json()) ```
```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'title' => 'Embroidered linen abaya', 'body_html' => '

Soft linen, hand-embroidered in Doha.

', 'status' => 'active', 'vendor' => 'Layla', 'product_type' => 'Abayas', 'tags' => ['linen', 'summer'], 'options' => [ [ 'name' => 'Size', 'values' => [['value' => 'S'], ['value' => 'M'], ['value' => 'L']], ], ], 'variants' => [ [ 'options' => ['S'], 'price' => '450.00', 'compare_at_price' => '520.00', 'sku' => 'ABY-LIN-S', ], [ 'options' => ['M'], 'price' => '450.00', 'compare_at_price' => '520.00', 'sku' => 'ABY-LIN-M', ], [ 'options' => ['L'], 'price' => '450.00', 'sku' => 'ABY-LIN-L', ], ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "title": "Embroidered linen abaya", "body_html": "

Soft linen, hand-embroidered in Doha.

", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}] } ], "variants": [ { "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S" }, { "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M" }, {"options": ["L"], "price": "450.00", "sku": "ABY-LIN-L"} ] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/products", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/products"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "title": "Embroidered linen abaya", "body_html": "

Soft linen, hand-embroidered in Doha.

", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}] } ], "variants": [ { "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S" }, { "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M" }, {"options": ["L"], "price": "450.00", "sku": "ABY-LIN-L"} ] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "body_html": "

Soft linen, hand-embroidered in Doha.

", "category_id": null, "channels": ["online_store"], "collections": [], "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "gift_card": false, "handle": "embroidered-linen-abaya", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "media": [], "options": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000038", "name": "Size", "position": 1, "values": [{"value": "S"}, {"value": "M"}] } ], "product_type": "Abayas", "publish_at": null, "published": true, "published_at": "2026-10-18T09:30:00Z", "seo_description": "", "seo_title": "", "status": "active", "tags": ["linen", "summer"], "template_suffix": "", "title": "Embroidered linen abaya", "updated_at": "2026-10-18T09:30:00Z", "variants": [ { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "inventory_policy": "deny", "inventory_tracked": true, "options": ["S"], "position": 1, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-S", "tax_code": "", "taxable": true, "title": "S", "version": 1, "weight": 0, "weight_grams": 0, "weight_unit": "kg" }, { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "inventory_policy": "deny", "inventory_tracked": true, "options": ["M"], "position": 2, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-M", "tax_code": "", "taxable": true, "title": "M", "version": 1, "weight": 0, "weight_grams": 0, "weight_unit": "kg" } ], "vendor": "Layla", "version": 1 } ```
## List products GET `/products` · Scope: `read_products` | Parameter | In | Description | | --- | --- | --- | | `status` | query | For example `active`. | | `limit` | query | For example `10`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/products?status=active&limit=10" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products?status=active&limit=10", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/products?status=active&limit=10", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/products?status=active&limit=10", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/products?status=active&limit=10"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "category": null, "created_at": "2026-10-18T09:30:00Z", "handle": "embroidered-linen-abaya", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "price_max": "450.00", "price_min": "450.00", "product_type": "Abayas", "published": true, "status": "active", "tags": ["linen", "summer"], "title": "Embroidered linen abaya", "total_inventory": 0, "tracked_variants": 3, "updated_at": "2026-10-18T09:30:00Z", "variants_count": 3, "vendor": "Layla" } ], "page_info": {"has_next_page": false} } ```
## Get a product GET `/products/{id}` · Scope: `read_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "body_html": "

Soft linen, hand-embroidered in Doha.

", "category_id": null, "channels": ["online_store"], "collections": [], "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "gift_card": false, "handle": "embroidered-linen-abaya", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "media": [], "options": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000038", "name": "Size", "position": 1, "values": [{"value": "S"}, {"value": "M"}] } ], "product_type": "Abayas", "publish_at": null, "published": true, "published_at": "2026-10-18T09:30:00Z", "seo_description": "", "seo_title": "", "status": "active", "tags": ["linen", "summer"], "template_suffix": "", "title": "Embroidered linen abaya", "updated_at": "2026-10-18T09:30:00Z", "variants": [ { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "inventory_policy": "deny", "inventory_tracked": true, "options": ["S"], "position": 1, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-S", "tax_code": "", "taxable": true, "title": "S", "version": 1, "weight": 0, "weight_grams": 0, "weight_unit": "kg" }, { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "inventory_policy": "deny", "inventory_tracked": true, "options": ["M"], "position": 2, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-M", "tax_code": "", "taxable": true, "title": "M", "version": 1, "weight": 0, "weight_grams": 0, "weight_unit": "kg" } ], "vendor": "Layla", "version": 1 } ```
## List a product's variants GET `/products/{id}/variants` · Scope: `read_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/variants" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/variants", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/variants", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/variants", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/variants"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "inventory_policy": "deny", "inventory_tracked": true, "options": ["S"], "position": 1, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-S", "tax_code": "", "taxable": true, "title": "S", "version": 1, "weight": 0, "weight_grams": 0, "weight_unit": "kg" }, { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "inventory_policy": "deny", "inventory_tracked": true, "options": ["M"], "position": 2, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-M", "tax_code": "", "taxable": true, "title": "M", "version": 1, "weight": 0, "weight_grams": 0, "weight_unit": "kg" } ] } ```
## Update a product PUT `/products/{id}` · Scope: `write_products` Send the whole product with the version you read: variants left out are deleted, and a stale version gets 409. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Embroidered linen abaya", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer", "eid"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}] } ], "variants": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S" }, { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M" }, { "id": "0193a1b2-e240-7ff9-88bf-e99d692cae3c", "options": ["L"], "price": "450.00", "sku": "ABY-LIN-L" } ], "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "title": "Embroidered linen abaya", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer", "eid"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}] } ], "variants": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S" }, { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M" }, { "id": "0193a1b2-e240-7ff9-88bf-e99d692cae3c", "options": ["L"], "price": "450.00", "sku": "ABY-LIN-L" } ], "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "title": "Embroidered linen abaya", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer", "eid"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}], }, ], "variants": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S", }, { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M", }, { "id": "0193a1b2-e240-7ff9-88bf-e99d692cae3c", "options": ["L"], "price": "450.00", "sku": "ABY-LIN-L", }, ], "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'title' => 'Embroidered linen abaya', 'status' => 'active', 'vendor' => 'Layla', 'product_type' => 'Abayas', 'tags' => ['linen', 'summer', 'eid'], 'options' => [ [ 'name' => 'Size', 'values' => [['value' => 'S'], ['value' => 'M'], ['value' => 'L']], ], ], 'variants' => [ [ 'id' => '0193a1b2-c3d4-7e5f-8a6b-000000000019', 'options' => ['S'], 'price' => '450.00', 'compare_at_price' => '520.00', 'sku' => 'ABY-LIN-S', ], [ 'id' => '0193a1b2-c3d4-7e5f-8a6b-000000000014', 'options' => ['M'], 'price' => '450.00', 'compare_at_price' => '520.00', 'sku' => 'ABY-LIN-M', ], [ 'id' => '0193a1b2-e240-7ff9-88bf-e99d692cae3c', 'options' => ['L'], 'price' => '450.00', 'sku' => 'ABY-LIN-L', ], ], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "title": "Embroidered linen abaya", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer", "eid"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}] } ], "variants": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S" }, { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M" }, { "id": "0193a1b2-e240-7ff9-88bf-e99d692cae3c", "options": ["L"], "price": "450.00", "sku": "ABY-LIN-L" } ], "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "title": "Embroidered linen abaya", "status": "active", "vendor": "Layla", "product_type": "Abayas", "tags": ["linen", "summer", "eid"], "options": [ { "name": "Size", "values": [{"value": "S"}, {"value": "M"}, {"value": "L"}] } ], "variants": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "options": ["S"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-S" }, { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "options": ["M"], "price": "450.00", "compare_at_price": "520.00", "sku": "ABY-LIN-M" }, { "id": "0193a1b2-e240-7ff9-88bf-e99d692cae3c", "options": ["L"], "price": "450.00", "sku": "ABY-LIN-L" } ], "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "body_html": "", "category_id": null, "channels": ["online_store"], "collections": [], "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "gift_card": false, "handle": "embroidered-linen-abaya", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "media": [], "options": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000065", "name": "Size", "position": 1, "values": [{"value": "S"}, {"value": "M"}] } ], "product_type": "Abayas", "publish_at": null, "published": true, "published_at": "2026-10-18T09:30:00Z", "seo_description": "", "seo_title": "", "status": "active", "tags": ["eid", "linen"], "template_suffix": "", "title": "Embroidered linen abaya", "updated_at": "2026-10-18T09:30:00Z", "variants": [ { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000019", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000017", "inventory_policy": "deny", "inventory_tracked": true, "options": ["S"], "position": 1, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-S", "tax_code": "", "taxable": true, "title": "S", "version": 2, "weight": 0, "weight_grams": 0, "weight_unit": "kg" }, { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000014", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000020", "inventory_policy": "deny", "inventory_tracked": true, "options": ["M"], "position": 2, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-M", "tax_code": "", "taxable": true, "title": "M", "version": 2, "weight": 0, "weight_grams": 0, "weight_unit": "kg" } ], "vendor": "Layla", "version": 2 } ```
## Duplicate a product POST `/products/{id}/duplicate` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/duplicate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Embroidered linen abaya (black)", "include_media": true, "status": "draft" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/duplicate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "title": "Embroidered linen abaya (black)", "include_media": true, "status": "draft" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/duplicate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "title": "Embroidered linen abaya (black)", "include_media": True, "status": "draft", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'title' => 'Embroidered linen abaya (black)', 'include_media' => true, 'status' => 'draft', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "title": "Embroidered linen abaya (black)", "include_media": true, "status": "draft" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/duplicate", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/duplicate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "title": "Embroidered linen abaya (black)", "include_media": true, "status": "draft" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "body_html": "", "category_id": null, "channels": [], "collections": [], "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "gift_card": false, "handle": "embroidered-linen-abaya-black", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000057", "media": [], "options": [ { "id": "0193a1b2-c3d4-7e5f-8a6b-000000000058", "name": "Size", "position": 1, "values": [{"value": "S"}, {"value": "M"}] } ], "product_type": "Abayas", "publish_at": null, "published": false, "published_at": null, "seo_description": "", "seo_title": "", "status": "draft", "tags": ["eid", "linen"], "template_suffix": "", "title": "Embroidered linen abaya (black)", "updated_at": "2026-10-18T09:30:00Z", "variants": [ { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000059", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000060", "inventory_policy": "deny", "inventory_tracked": true, "options": ["S"], "position": 1, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-S", "tax_code": "", "taxable": true, "title": "S", "version": 1, "weight": 0, "weight_grams": 0, "weight_unit": "kg" }, { "barcode": "", "compare_at_price": "520.00", "country_of_origin": null, "hs_code": "", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000061", "image_media_id": null, "inventory_item_id": "0193a1b2-c3d4-7e5f-8a6b-000000000062", "inventory_policy": "deny", "inventory_tracked": true, "options": ["M"], "position": 2, "price": "450.00", "requires_shipping": true, "sku": "ABY-LIN-M", "tax_code": "", "taxable": true, "title": "M", "version": 1, "weight": 0, "weight_grams": 0, "weight_unit": "kg" } ], "vendor": "Layla", "version": 1 } ```
## Change many products at once POST `/products/bulk` · Scope: `write_products` Actions: add_tags, remove_tags, set_status, publish, unpublish, add_to_collections, remove_from_collections, delete. ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/products/bulk" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "add_tags", "ids": [ "0193a1b2-c3d4-7e5f-8a6b-000000000005", "0193a1b2-c3d4-7e5f-8a6b-000000000057" ], "tags": ["eid-edit"] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/bulk", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "action": "add_tags", "ids": [ "0193a1b2-c3d4-7e5f-8a6b-000000000005", "0193a1b2-c3d4-7e5f-8a6b-000000000057" ], "tags": ["eid-edit"] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/products/bulk", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "action": "add_tags", "ids": [ "0193a1b2-c3d4-7e5f-8a6b-000000000005", "0193a1b2-c3d4-7e5f-8a6b-000000000057", ], "tags": ["eid-edit"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'action' => 'add_tags', 'ids' => [ '0193a1b2-c3d4-7e5f-8a6b-000000000005', '0193a1b2-c3d4-7e5f-8a6b-000000000057', ], 'tags' => ['eid-edit'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "action": "add_tags", "ids": [ "0193a1b2-c3d4-7e5f-8a6b-000000000005", "0193a1b2-c3d4-7e5f-8a6b-000000000057" ], "tags": ["eid-edit"] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/products/bulk", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/products/bulk"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "action": "add_tags", "ids": [ "0193a1b2-c3d4-7e5f-8a6b-000000000005", "0193a1b2-c3d4-7e5f-8a6b-000000000057" ], "tags": ["eid-edit"] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"updated": 2} ```
## Delete a product DELETE `/products/{id}` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000057" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000057", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000057", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000057", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000057"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Add an image to a product POST `/products/{id}/media` · Scope: `write_products` Pass an uploaded file's asset_id (see Files) or an external_url to import. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "external_url": "https://cdn.example.com/abaya-front.jpg", "alt": "Embroidered linen abaya", "front": null }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "external_url": "https://cdn.example.com/abaya-front.jpg", "alt": "Embroidered linen abaya", "front": null }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "external_url": "https://cdn.example.com/abaya-front.jpg", "alt": "Embroidered linen abaya", "front": None, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'external_url' => 'https://cdn.example.com/abaya-front.jpg', 'alt' => 'Embroidered linen abaya', 'front' => null, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "external_url": "https://cdn.example.com/abaya-front.jpg", "alt": "Embroidered linen abaya", "front": null }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "external_url": "https://cdn.example.com/abaya-front.jpg", "alt": "Embroidered linen abaya", "front": null } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Reorder a product's media PUT `/products/{id}/media/order` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/order" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "ids": [ "0193a1b2-0000-7000-8000-00000000a001", "0193a1b2-0000-7000-8000-00000000a002" ] }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/order", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "ids": [ "0193a1b2-0000-7000-8000-00000000a001", "0193a1b2-0000-7000-8000-00000000a002" ] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/order", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "ids": [ "0193a1b2-0000-7000-8000-00000000a001", "0193a1b2-0000-7000-8000-00000000a002", ], }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'ids' => [ '0193a1b2-0000-7000-8000-00000000a001', '0193a1b2-0000-7000-8000-00000000a002', ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "ids": [ "0193a1b2-0000-7000-8000-00000000a001", "0193a1b2-0000-7000-8000-00000000a002" ] }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/order", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/order"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "ids": [ "0193a1b2-0000-7000-8000-00000000a001", "0193a1b2-0000-7000-8000-00000000a002" ] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Update an image's alt text PATCH `/products/{id}/media/{media_id}` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `media_id` | path | The media ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"alt": "Embroidered linen abaya", "back": null}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"alt": "Embroidered linen abaya", "back": null}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"alt": "Embroidered linen abaya", "back": None}, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['alt' => 'Embroidered linen abaya', 'back' => null], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"alt": "Embroidered linen abaya", "back": null}` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"alt": "Embroidered linen abaya", "back": null} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Remove an image from a product DELETE `/products/{id}/media/{media_id}` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `media_id` | path | The media ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/products/0193a1b2-c3d4-7e5f-8a6b-000000000005/media/0193a1b2-3af9-7339-89df-609243f7e660"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Create a collection POST `/collections` · Scope: `write_products` kind manual takes product_ids; kind smart takes rules (column, relation, condition). ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/collections" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "kind": "manual", "title": "Eid edit", "body_html": "

Pieces for Eid gatherings.

", "published": true, "product_ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"] }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "kind": "manual", "title": "Eid edit", "body_html": "

Pieces for Eid gatherings.

", "published": true, "product_ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"] }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/collections", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "kind": "manual", "title": "Eid edit", "body_html": "

Pieces for Eid gatherings.

", "published": True, "product_ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"], }, ) res.raise_for_status() print(res.json()) ```
```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'kind' => 'manual', 'title' => 'Eid edit', 'body_html' => '

Pieces for Eid gatherings.

', 'published' => true, 'product_ids' => ['0193a1b2-c3d4-7e5f-8a6b-000000000005'], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "kind": "manual", "title": "Eid edit", "body_html": "

Pieces for Eid gatherings.

", "published": true, "product_ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"] }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/collections", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/collections"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "kind": "manual", "title": "Eid edit", "body_html": "

Pieces for Eid gatherings.

", "published": true, "product_ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"] } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "body_html": "

Pieces for Eid gatherings.

", "disjunctive": false, "handle": "eid-edit", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000004", "image_asset_id": null, "kind": "manual", "products_count": 1, "published": true, "published_at": "2026-10-18T09:30:00Z", "rules": [], "seo_description": "", "seo_title": "", "sort_order": "manual", "template_suffix": "", "title": "Eid edit", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## List collections GET `/collections` · Scope: `read_products` | Parameter | In | Description | | --- | --- | --- | | `limit` | query | For example `10`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/collections?limit=10" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections?limit=10", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/collections?limit=10", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/collections?limit=10", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/collections?limit=10"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "body_html": "

Pieces for Eid gatherings.

", "disjunctive": false, "handle": "eid-edit", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000004", "image_asset_id": null, "kind": "manual", "products_count": 1, "published": true, "published_at": "2026-10-18T09:30:00Z", "rules": [], "seo_description": "", "seo_title": "", "sort_order": "manual", "template_suffix": "", "title": "Eid edit", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ], "page_info": {"has_next_page": false} } ```
## Get a collection GET `/collections/{id}` · Scope: `read_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "body_html": "

Pieces for Eid gatherings.

", "disjunctive": false, "handle": "eid-edit", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000004", "image_asset_id": null, "kind": "manual", "products_count": 1, "published": true, "published_at": "2026-10-18T09:30:00Z", "rules": [], "seo_description": "", "seo_title": "", "sort_order": "manual", "template_suffix": "", "title": "Eid edit", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## Update a collection PUT `/collections/{id}` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "kind": "manual", "title": "Eid edit", "sort_order": "price_asc", "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "kind": "manual", "title": "Eid edit", "sort_order": "price_asc", "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "kind": "manual", "title": "Eid edit", "sort_order": "price_asc", "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'kind' => 'manual', 'title' => 'Eid edit', 'sort_order' => 'price_asc', 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "kind": "manual", "title": "Eid edit", "sort_order": "price_asc", "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "kind": "manual", "title": "Eid edit", "sort_order": "price_asc", "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "body_html": "", "disjunctive": false, "handle": "eid-edit", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000004", "image_asset_id": null, "kind": "manual", "products_count": 1, "published": true, "published_at": "2026-10-18T09:30:00Z", "rules": [], "seo_description": "", "seo_title": "", "sort_order": "price_asc", "template_suffix": "", "title": "Eid edit", "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
## List a collection's products GET `/collections/{id}/products` · Scope: `read_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `limit` | query | For example `24`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products?limit=24" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products?limit=24", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products?limit=24", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products?limit=24", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products?limit=24"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "handle": "embroidered-linen-abaya", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "position": 1, "status": "active", "title": "Embroidered linen abaya" } ], "has_more": false } ```
## Add products to a manual collection POST `/collections/{id}/products` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['ids' => ['0193a1b2-c3d4-7e5f-8a6b-000000000005']], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Reorder a manual collection's products PUT `/collections/{id}/products/order` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/order" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/order", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/order", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['ids' => ['0193a1b2-c3d4-7e5f-8a6b-000000000005']], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/order", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/order"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Remove products from a manual collection POST `/collections/{id}/products/remove` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/remove" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/remove", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/remove", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['ids' => ['0193a1b2-c3d4-7e5f-8a6b-000000000005']], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/remove", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004/products/remove"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"]} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Delete a collection DELETE `/collections/{id}` · Scope: `write_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/collections/0193a1b2-c3d4-7e5f-8a6b-000000000004"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 204 ```json {} ```
## Search the product category taxonomy GET `/taxonomy` · Scope: `read_products` | Parameter | In | Description | | --- | --- | --- | | `q` | query | For example `abaya`. | | `locale` | query | For example `en`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/taxonomy?q=abaya&locale=en" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/taxonomy?q=abaya&locale=en", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/taxonomy?q=abaya&locale=en", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/taxonomy?q=abaya&locale=en", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/taxonomy?q=abaya&locale=en"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
## Get a product category GET `/taxonomy/{id}` · Scope: `read_products` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `locale` | query | For example `ar`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/taxonomy/0193a1b2-4af1-78d7-87af-bf6bbb10bd5a?locale=ar" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/taxonomy/0193a1b2-4af1-78d7-87af-bf6bbb10bd5a?locale=ar", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/taxonomy/0193a1b2-4af1-78d7-87af-bf6bbb10bd5a?locale=ar", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/taxonomy/0193a1b2-4af1-78d7-87af-bf6bbb10bd5a?locale=ar", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/taxonomy/0193a1b2-4af1-78d7-87af-bf6bbb10bd5a?locale=ar"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Reports URL: https://sooquna.com/docs/api/admin/reports > Admin API 2026-10: Analytics reports. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Analytics reports. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [List available reports](#list-available-reports) | GET | `/analytics/reports` | | [Run a report](#run-a-report) | GET | `/analytics/reports/{key}` | ## List available reports GET `/analytics/reports` · Scope: `read_reports` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/analytics/reports" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/analytics/reports", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/analytics/reports", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/analytics/reports", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/analytics/reports"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "category": "sales", "chart": "line", "columns": [ {"key": "period", "type": "date"}, {"key": "orders", "type": "int"} ], "group_by": ["day", "week"], "key": "sales_over_time" }, { "category": "sales", "chart": "bar", "columns": [ {"key": "product", "type": "text"}, {"key": "orders", "type": "int"} ], "key": "sales_by_product" } ] } ```
## Run a report GET `/analytics/reports/{key}` · Scope: `read_reports` | Parameter | In | Description | | --- | --- | --- | | `key` | path | The key ID. | | `group_by` | query | For example `day`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/analytics/reports/sales_over_time?group_by=day" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/analytics/reports/sales_over_time?group_by=day", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/analytics/reports/sales_over_time?group_by=day", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/analytics/reports/sales_over_time?group_by=day", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/analytics/reports/sales_over_time?group_by=day"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "currency": "QAR", "group_by": "day", "range": {"from": "2026-10-18T09:30:00Z", "to": "2026-10-18T09:30:00Z"}, "report": { "category": "sales", "chart": "line", "columns": [ {"key": "period", "type": "date"}, {"key": "orders", "type": "int"} ], "group_by": ["day", "week"], "key": "sales_over_time" }, "rows": [["2026-09-19", 0], ["2026-09-20", 0]], "totals": [null, 0] } ```
--- # Returns URL: https://sooquna.com/docs/api/admin/returns > Admin API 2026-10: Return requests. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Return requests. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [List an order's returns](#list-an-order-s-returns) | GET | `/orders/{id}/returns` | | [List returns](#list-returns) | GET | `/returns` | | [Get a return](#get-a-return) | GET | `/returns/{id}` | | [Approve, decline or close a return](#approve-decline-or-close-a-return) | POST | `/returns/{id}` | ## List an order's returns GET `/orders/{id}/returns` · Scope: `read_returns` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/returns" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/returns", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/returns", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/returns", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/orders/0193a1b2-c3d4-7e5f-8a6b-000000000035/returns"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
## List returns GET `/returns` · Scope: `read_returns` | Parameter | In | Description | | --- | --- | --- | | `status` | query | For example `requested`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/returns?status=requested" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/returns?status=requested", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/returns?status=requested", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/returns?status=requested", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/returns?status=requested"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
## Get a return GET `/returns/{id}` · Scope: `read_returns` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Approve, decline or close a return POST `/returns/{id}` · Scope: `write_returns` Actions: approve (with instructions), decline (with reason), receive, close. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "approve", "instructions": "Drop the parcel at any Aramex point within 7 days.", "notify_customer": true, "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "action": "approve", "instructions": "Drop the parcel at any Aramex point within 7 days.", "notify_customer": true, "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "action": "approve", "instructions": "Drop the parcel at any Aramex point within 7 days.", "notify_customer": True, "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'action' => 'approve', 'instructions' => 'Drop the parcel at any Aramex point within 7 days.', 'notify_customer' => true, 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "action": "approve", "instructions": "Drop the parcel at any Aramex point within 7 days.", "notify_customer": true, "version": 1 }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/returns/0193a1b2-a3f8-7a9d-860a-6961e749501c"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "action": "approve", "instructions": "Drop the parcel at any Aramex point within 7 days.", "notify_customer": true, "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Shipping URL: https://sooquna.com/docs/api/admin/shipping > Admin API 2026-10: Shipping profiles, zones, rates, local delivery and pickup. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Shipping profiles, zones, rates, local delivery and pickup. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [List shipping profiles](#list-shipping-profiles) | GET | `/shipping/profiles` | | [Get a shipping profile](#get-a-shipping-profile) | GET | `/shipping/profiles/{id}` | | [List a shipping profile's products](#list-a-shipping-profile-s-products) | GET | `/shipping/profiles/{id}/products` | | [List local delivery settings](#list-local-delivery-settings) | GET | `/shipping/local-delivery` | | [Get a local delivery setting](#get-a-local-delivery-setting) | GET | `/shipping/local-delivery/{id}` | | [List delivery slots](#list-delivery-slots) | GET | `/shipping/local-delivery/{id}/slots` | | [List pickup locations](#list-pickup-locations) | GET | `/shipping/pickup` | | [List package sizes](#list-package-sizes) | GET | `/shipping/packages` | ## List shipping profiles GET `/shipping/profiles` · Scope: `read_shipping` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shipping/profiles" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipping/profiles", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shipping/profiles", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shipping/profiles", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shipping/profiles"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
## Get a shipping profile GET `/shipping/profiles/{id}` · Scope: `read_shipping` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-5054-7ddb-83e9-13198abd3357" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-5054-7ddb-83e9-13198abd3357", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-5054-7ddb-83e9-13198abd3357", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-5054-7ddb-83e9-13198abd3357", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-5054-7ddb-83e9-13198abd3357"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List a shipping profile's products GET `/shipping/profiles/{id}/products` · Scope: `read_shipping` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `limit` | query | For example `20`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-596b-74f1-8fed-60b5d8fc7174/products?limit=20" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-596b-74f1-8fed-60b5d8fc7174/products?limit=20", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-596b-74f1-8fed-60b5d8fc7174/products?limit=20", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-596b-74f1-8fed-60b5d8fc7174/products?limit=20", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shipping/profiles/0193a1b2-596b-74f1-8fed-60b5d8fc7174/products?limit=20"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List local delivery settings GET `/shipping/local-delivery` · Scope: `read_shipping` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "areas_count": 0, "enabled": false, "location": { "address": ["Diplomatic Street, Tower 2", "Doha"], "country": "QA", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "is_active": true, "latitude": null, "longitude": null, "name": "West Bay shop" } }, { "areas_count": 0, "enabled": false, "location": { "address": ["QA"], "country": "QA", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "is_active": true, "latitude": null, "longitude": null, "name": "Al Wakrah warehouse" } } ] } ```
## Get a local delivery setting GET `/shipping/local-delivery/{id}` · Scope: `read_shipping` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-c5e1-71ad-841f-44c23f74ba59" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-c5e1-71ad-841f-44c23f74ba59", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-c5e1-71ad-841f-44c23f74ba59", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-c5e1-71ad-841f-44c23f74ba59", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-c5e1-71ad-841f-44c23f74ba59"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List delivery slots GET `/shipping/local-delivery/{id}/slots` · Scope: `read_shipping` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-a42a-7f53-8ceb-2814823b20ea/slots" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-a42a-7f53-8ceb-2814823b20ea/slots", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-a42a-7f53-8ceb-2814823b20ea/slots", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-a42a-7f53-8ceb-2814823b20ea/slots", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shipping/local-delivery/0193a1b2-a42a-7f53-8ceb-2814823b20ea/slots"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List pickup locations GET `/shipping/pickup` · Scope: `read_shipping` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shipping/pickup" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipping/pickup", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shipping/pickup", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shipping/pickup", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shipping/pickup"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "enabled": true, "instructions": "Ask at the counter.", "location": { "address": ["Diplomatic Street, Tower 2", "Doha"], "country": "QA", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000023", "is_active": true, "latitude": null, "longitude": null, "name": "West Bay shop" }, "ready_time": "1h" }, { "enabled": false, "instructions": "", "location": { "address": ["QA"], "country": "QA", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000021", "is_active": true, "latitude": null, "longitude": null, "name": "Al Wakrah warehouse" }, "ready_time": "1h" } ] } ```
## List package sizes GET `/shipping/packages` · Scope: `read_shipping` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shipping/packages" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shipping/packages", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shipping/packages", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shipping/packages", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shipping/packages"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json {"data": []} ```
--- # Shop URL: https://sooquna.com/docs/api/admin/shop > Admin API 2026-10: Shop {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Endpoints for shop. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Get the store's settings](#get-the-store-s-settings) | GET | `/shop` | ## Get the store's settings GET `/shop` · Any token ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/shop" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/shop", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/shop", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/shop", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/shop"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "country": "QA", "created_at": "2026-10-18T09:30:00Z", "currency": "QAR", "domain": "shop.sooquna.test", "email": "", "enabled_locales": ["en"], "handle": "shop", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000045", "name": "Shop", "phone": "", "plan": "grow", "primary_locale": "en", "status": "active", "timezone": "UTC", "weight_unit": "kg" } ```
--- # Themes URL: https://sooquna.com/docs/api/admin/themes > Admin API 2026-10: Themes and theme files. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Themes and theme files. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Add a theme from the library](#add-a-theme-from-the-library) | POST | `/themes` | | [List themes](#list-themes) | GET | `/themes` | | [Upload a theme (.zip)](#upload-a-theme-zip) | POST | `/themes/upload` | | [Get a theme](#get-a-theme) | GET | `/themes/{id}` | | [Rename a theme](#rename-a-theme) | PATCH | `/themes/{id}` | | [Duplicate a theme](#duplicate-a-theme) | POST | `/themes/{id}/duplicate` | | [Publish a theme](#publish-a-theme) | POST | `/themes/{id}/publish` | | [Delete a theme](#delete-a-theme) | DELETE | `/themes/{id}` | | [Download a theme as a .zip](#download-a-theme-as-a-zip) | GET | `/themes/{id}/download` | | [List a theme's files](#list-a-theme-s-files) | GET | `/themes/{id}/files` | | [Read a theme file](#read-a-theme-file) | GET | `/themes/{id}/file` | | [Write a theme file](#write-a-theme-file) | PUT | `/themes/{id}/file` | | [Open a file in the code editor](#open-a-file-in-the-code-editor) | GET | `/themes/{id}/code/file` | | [Save a file with conflict detection](#save-a-file-with-conflict-detection) | PUT | `/themes/{id}/code/file` | | [Delete a theme file](#delete-a-theme-file) | DELETE | `/themes/{id}/code/file` | | [Rename a theme file](#rename-a-theme-file) | POST | `/themes/{id}/code/rename` | | [List a file's saved versions](#list-a-file-s-saved-versions) | GET | `/themes/{id}/code/versions` | | [Read a saved version of a file](#read-a-saved-version-of-a-file) | GET | `/themes/{id}/code/versions/{vid}` | | [Restore a saved version of a file](#restore-a-saved-version-of-a-file) | POST | `/themes/{id}/code/versions/{vid}/restore` | | [List what uses a file](#list-what-uses-a-file) | GET | `/themes/{id}/references` | | [Run the theme check](#run-the-theme-check) | POST | `/themes/{id}/check` | | [Check unsaved content of a file](#check-unsaved-content-of-a-file) | POST | `/themes/{id}/check/file` | | [Upload a theme asset](#upload-a-theme-asset) | POST | `/themes/{id}/assets` | | [List restore points](#list-restore-points) | GET | `/themes/{id}/snapshots` | | [Create a restore point](#create-a-restore-point) | POST | `/themes/{id}/snapshots` | | [Restore the theme to a restore point](#restore-the-theme-to-a-restore-point) | POST | `/themes/{id}/snapshots/{sid}/restore` | | [Add an alternate template](#add-an-alternate-template) | POST | `/themes/{id}/templates` | ## Add a theme from the library POST `/themes` · Scope: `write_themes` ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"library_key": "sahil"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"library_key": "sahil"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"library_key": "sahil"}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['library_key' => 'sahil'], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"library_key": "sahil"}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"library_key": "sahil"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 201 ```json { "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000046", "latest_version": "1.1.0", "library_key": "sahil", "library_version": "1.1.0", "name": "Sahil", "role": "unpublished", "source": "library", "update_available": false, "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## List themes GET `/themes` · Scope: `read_themes` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000046", "latest_version": "1.1.0", "library_key": "sahil", "library_version": "1.1.0", "name": "Sahil", "role": "unpublished", "source": "library", "update_available": false, "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ] } ```
## Upload a theme (.zip) POST `/themes/upload` · Scope: `write_themes` Send the .zip as the body with Content-Type: application/zip. ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/upload" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/zip" \ --data-binary @sahil-eid.zip ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/upload", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/zip", }, body: await readFile("sahil-eid.zip"), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/upload", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Content-Type": "application/zip", }, data=open("sahil-eid.zip", "rb"), ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/zip', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => file_get_contents('sahil-eid.zip'), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { f, err := os.Open("sahil-eid.zip") if err != nil { panic(err) } defer f.Close() req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/upload", f) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/zip") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/upload"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new ByteArrayContent(await File.ReadAllBytesAsync("sahil-eid.zip")); req.Content.Headers.ContentType = new("application/zip"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Get a theme GET `/themes/{id}` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "created_at": "2026-10-18T09:30:00Z", "id": "0193a1b2-c3d4-7e5f-8a6b-000000000046", "latest_version": "1.1.0", "library_key": "sahil", "library_version": "1.1.0", "name": "Sahil", "role": "unpublished", "source": "library", "update_available": false, "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
## Rename a theme PATCH `/themes/{id}` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PATCH "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Sahil (Eid)"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165", { method: "PATCH", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"name": "Sahil (Eid)"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.patch( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"name": "Sahil (Eid)"}, ) res.raise_for_status() print(res.json()) ``` ```php 'PATCH', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['name' => 'Sahil (Eid)'], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"name": "Sahil (Eid)"}` req, err := http.NewRequest("PATCH", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Patch, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"name": "Sahil (Eid)"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Duplicate a theme POST `/themes/{id}/duplicate` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-0753-74ce-894f-8a6cfd2e290d/duplicate" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-0753-74ce-894f-8a6cfd2e290d/duplicate", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-0753-74ce-894f-8a6cfd2e290d/duplicate", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-0753-74ce-894f-8a6cfd2e290d/duplicate", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-0753-74ce-894f-8a6cfd2e290d/duplicate"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Publish a theme POST `/themes/{id}/publish` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-a154-7e3e-8469-fb60de553c57/publish" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-a154-7e3e-8469-fb60de553c57/publish", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-a154-7e3e-8469-fb60de553c57/publish", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-a154-7e3e-8469-fb60de553c57/publish", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-a154-7e3e-8469-fb60de553c57/publish"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Delete a theme DELETE `/themes/{id}` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-f0c3-73c2-8be6-b02e03b23165"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Download a theme as a .zip GET `/themes/{id}/download` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-31fa-74d9-8a75-bfa9d5956a52/download" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -o sahil.zip ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-31fa-74d9-8a75-bfa9d5956a52/download", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); await writeFile("sahil.zip", Buffer.from(await res.arrayBuffer())); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-31fa-74d9-8a75-bfa9d5956a52/download", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() with open("sahil.zip", "wb") as f: f.write(res.content) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } file_put_contents('sahil.zip', $response); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-31fa-74d9-8a75-bfa9d5956a52/download", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } out, err := os.Create("sahil.zip") if err != nil { panic(err) } defer out.Close() io.Copy(out, res.Body) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-31fa-74d9-8a75-bfa9d5956a52/download"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); await File.WriteAllBytesAsync("sahil.zip", await res.Content.ReadAsByteArrayAsync()); ``` ## List a theme's files GET `/themes/{id}/files` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/files" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/files", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/files", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/files", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/files"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "modified": false, "path": "assets/back-in-stock.js", "sha": "07e1262d2e58cfd08fed9525b25e911db869ebc3f5a2db854d86b6da7f5601fd", "size": 2415, "updated_at": "2026-10-18T09:30:00Z" }, { "modified": false, "path": "assets/base.css", "sha": "9b083fbe7035e7b32638a76653a84152e7a88fdfb7fe7e22061550a27a9981db", "size": 50265, "updated_at": "2026-10-18T09:30:00Z" } ] } ```
## Read a theme file GET `/themes/{id}/file` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `path` | query | For example `templates/index.json`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/file?path=templates%2Findex.json" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/file?path=templates%2Findex.json", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/file?path=templates%2Findex.json", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/file?path=templates%2Findex.json", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/file?path=templates%2Findex.json"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Write a theme file PUT `/themes/{id}/file` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-475c-7384-8181-3e210a78239d/file" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "path": "snippets/eid-banner.liquid", "content": "

{{ '\''eid.banner'\'' | t }}

" }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-475c-7384-8181-3e210a78239d/file", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "path": "snippets/eid-banner.liquid", "content": "

{{ 'eid.banner' | t }}

" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-475c-7384-8181-3e210a78239d/file", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "path": "snippets/eid-banner.liquid", "content": "

{{ 'eid.banner' | t }}

", }, ) res.raise_for_status() print(res.json()) ```
```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'path' => 'snippets/eid-banner.liquid', 'content' => '

{{ \'eid.banner\' | t }}

', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "path": "snippets/eid-banner.liquid", "content": "

{{ 'eid.banner' | t }}

" }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-475c-7384-8181-3e210a78239d/file", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-475c-7384-8181-3e210a78239d/file"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "path": "snippets/eid-banner.liquid", "content": "

{{ 'eid.banner' | t }}

" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
## Open a file in the code editor GET `/themes/{id}/code/file` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `path` | query | For example `sections/header.liquid`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=sections%2Fheader.liquid" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=sections%2Fheader.liquid", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=sections%2Fheader.liquid", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=sections%2Fheader.liquid", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=sections%2Fheader.liquid"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Save a file with conflict detection PUT `/themes/{id}/code/file` · Scope: `write_themes` Pass the base_sha you read; a newer save by someone else gets 409 with their content. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "path": "snippets/eid-banner.liquid", "content": "

{{ '\''eid.banner'\'' | t }}

", "create": true }' ```
```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "path": "snippets/eid-banner.liquid", "content": "

{{ 'eid.banner' | t }}

", "create": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "path": "snippets/eid-banner.liquid", "content": "

{{ 'eid.banner' | t }}

", "create": True, }, ) res.raise_for_status() print(res.json()) ```
```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'path' => 'snippets/eid-banner.liquid', 'content' => '

{{ \'eid.banner\' | t }}

', 'create' => true, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "path": "snippets/eid-banner.liquid", "content": "

{{ 'eid.banner' | t }}

", "create": true }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "path": "snippets/eid-banner.liquid", "content": "

{{ 'eid.banner' | t }}

", "create": true } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
## Delete a theme file DELETE `/themes/{id}/code/file` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `path` | query | For example `snippets/eid-banner.liquid`. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=snippets%2Feid-banner.liquid" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=snippets%2Feid-banner.liquid", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=snippets%2Feid-banner.liquid", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=snippets%2Feid-banner.liquid", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-b6c1-7e31-8320-3f947513bbf5/code/file?path=snippets%2Feid-banner.liquid"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Rename a theme file POST `/themes/{id}/code/rename` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-fbe3-7f5b-852a-2375f6d83ee9/code/rename" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "path": "snippets/eid-banner.liquid", "new_path": "snippets/eid-strip.liquid" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-fbe3-7f5b-852a-2375f6d83ee9/code/rename", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "path": "snippets/eid-banner.liquid", "new_path": "snippets/eid-strip.liquid" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-fbe3-7f5b-852a-2375f6d83ee9/code/rename", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "path": "snippets/eid-banner.liquid", "new_path": "snippets/eid-strip.liquid", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'path' => 'snippets/eid-banner.liquid', 'new_path' => 'snippets/eid-strip.liquid', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "path": "snippets/eid-banner.liquid", "new_path": "snippets/eid-strip.liquid" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-fbe3-7f5b-852a-2375f6d83ee9/code/rename", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-fbe3-7f5b-852a-2375f6d83ee9/code/rename"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "path": "snippets/eid-banner.liquid", "new_path": "snippets/eid-strip.liquid" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List a file's saved versions GET `/themes/{id}/code/versions` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `path` | query | For example `sections/header.liquid`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-393e-7637-8f04-ca12cb4555cb/code/versions?path=sections%2Fheader.liquid" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-393e-7637-8f04-ca12cb4555cb/code/versions?path=sections%2Fheader.liquid", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-393e-7637-8f04-ca12cb4555cb/code/versions?path=sections%2Fheader.liquid", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-393e-7637-8f04-ca12cb4555cb/code/versions?path=sections%2Fheader.liquid", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-393e-7637-8f04-ca12cb4555cb/code/versions?path=sections%2Fheader.liquid"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Read a saved version of a file GET `/themes/{id}/code/versions/{vid}` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `vid` | path | The vid ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-037f-7e2a-8fcd-53d495e53d24/code/versions/0193a1b2-bef5-7711-8060-c0f60de80743" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-037f-7e2a-8fcd-53d495e53d24/code/versions/0193a1b2-bef5-7711-8060-c0f60de80743", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-037f-7e2a-8fcd-53d495e53d24/code/versions/0193a1b2-bef5-7711-8060-c0f60de80743", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-037f-7e2a-8fcd-53d495e53d24/code/versions/0193a1b2-bef5-7711-8060-c0f60de80743", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-037f-7e2a-8fcd-53d495e53d24/code/versions/0193a1b2-bef5-7711-8060-c0f60de80743"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Restore a saved version of a file POST `/themes/{id}/code/versions/{vid}/restore` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `vid` | path | The vid ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-73b7-7430-8bcd-96c8863373e8/code/versions/0193a1b2-ae62-7575-8ba3-32f821888101/restore" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"path": "sections/header.liquid"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-73b7-7430-8bcd-96c8863373e8/code/versions/0193a1b2-ae62-7575-8ba3-32f821888101/restore", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"path": "sections/header.liquid"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-73b7-7430-8bcd-96c8863373e8/code/versions/0193a1b2-ae62-7575-8ba3-32f821888101/restore", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"path": "sections/header.liquid"}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['path' => 'sections/header.liquid'], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"path": "sections/header.liquid"}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-73b7-7430-8bcd-96c8863373e8/code/versions/0193a1b2-ae62-7575-8ba3-32f821888101/restore", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-73b7-7430-8bcd-96c8863373e8/code/versions/0193a1b2-ae62-7575-8ba3-32f821888101/restore"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"path": "sections/header.liquid"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List what uses a file GET `/themes/{id}/references` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `target` | query | For example `snippets/product-card.liquid`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/references?target=snippets%2Fproduct-card.liquid" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/references?target=snippets%2Fproduct-card.liquid", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/references?target=snippets%2Fproduct-card.liquid", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/references?target=snippets%2Fproduct-card.liquid", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/references?target=snippets%2Fproduct-card.liquid"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
Response 200 ```json { "data": [ { "line": 10, "path": "sections/featured-collection.liquid", "text": "
  • {% render 'product-card', product: product, sizes: '(min-width: 990px) 25vw, 50vw' %}
  • " }, { "line": 25, "path": "sections/main-collection.liquid", "text": "
  • {% render 'product-card', product: product, sizes: '(min-width: 990px) 25vw, 50vw', eager: eager %}
  • " } ] } ```
    ## Run the theme check POST `/themes/{id}/check` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/check" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/check", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/check", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/check", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/check"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "problems": [ { "line": 40, "message": " without width and height causes layout shift", "path": "layout/theme.liquid", "severity": "warning" } ] } ```
    ## Check unsaved content of a file POST `/themes/{id}/check/file` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-9296-7481-870c-298744417c48/check/file" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"path": "snippets/eid-banner.liquid", "content": "{% if %}"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-9296-7481-870c-298744417c48/check/file", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"path": "snippets/eid-banner.liquid", "content": "{% if %}"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-9296-7481-870c-298744417c48/check/file", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"path": "snippets/eid-banner.liquid", "content": "{% if %}"}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['path' => 'snippets/eid-banner.liquid', 'content' => '{% if %}'], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"path": "snippets/eid-banner.liquid", "content": "{% if %}"}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-9296-7481-870c-298744417c48/check/file", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-9296-7481-870c-298744417c48/check/file"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"path": "snippets/eid-banner.liquid", "content": "{% if %}"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Upload a theme asset POST `/themes/{id}/assets` · Scope: `write_themes` Send the file as the body; name it with ?name=. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `name` | query | For example `logo.svg`. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-d586-7e30-865b-b5d523c2ea11/assets?name=logo.svg" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: image/svg+xml" \ --data-binary @logo.svg ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-d586-7e30-865b-b5d523c2ea11/assets?name=logo.svg", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "image/svg+xml", }, body: await readFile("logo.svg"), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-d586-7e30-865b-b5d523c2ea11/assets?name=logo.svg", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], "Content-Type": "image/svg+xml", }, data=open("logo.svg", "rb"), ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: image/svg+xml', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => file_get_contents('logo.svg'), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { f, err := os.Open("logo.svg") if err != nil { panic(err) } defer f.Close() req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-d586-7e30-865b-b5d523c2ea11/assets?name=logo.svg", f) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "image/svg+xml") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-d586-7e30-865b-b5d523c2ea11/assets?name=logo.svg"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new ByteArrayContent(await File.ReadAllBytesAsync("logo.svg")); req.Content.Headers.ContentType = new("image/svg+xml"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List restore points GET `/themes/{id}/snapshots` · Scope: `read_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/snapshots" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/snapshots", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/snapshots", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/snapshots", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c3d4-7e5f-8a6b-000000000046/snapshots"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json {"data": []} ```
    ## Create a restore point POST `/themes/{id}/snapshots` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-e506-7f8e-88e5-d91e7fbd9ecb/snapshots" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Before Ramadan banner"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-e506-7f8e-88e5-d91e7fbd9ecb/snapshots", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"name": "Before Ramadan banner"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-e506-7f8e-88e5-d91e7fbd9ecb/snapshots", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"name": "Before Ramadan banner"}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['name' => 'Before Ramadan banner'], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"name": "Before Ramadan banner"}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-e506-7f8e-88e5-d91e7fbd9ecb/snapshots", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-e506-7f8e-88e5-d91e7fbd9ecb/snapshots"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"name": "Before Ramadan banner"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Restore the theme to a restore point POST `/themes/{id}/snapshots/{sid}/restore` · Scope: `write_themes` | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `sid` | path | The sid ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-3713-7414-8ee8-0537214a9614/snapshots/0193a1b2-07ea-7a69-8f04-e63849649165/restore" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-3713-7414-8ee8-0537214a9614/snapshots/0193a1b2-07ea-7a69-8f04-e63849649165/restore", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-3713-7414-8ee8-0537214a9614/snapshots/0193a1b2-07ea-7a69-8f04-e63849649165/restore", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-3713-7414-8ee8-0537214a9614/snapshots/0193a1b2-07ea-7a69-8f04-e63849649165/restore", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-3713-7414-8ee8-0537214a9614/snapshots/0193a1b2-07ea-7a69-8f04-e63849649165/restore"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Add an alternate template POST `/themes/{id}/templates` · Scope: `write_themes` Copies the default template of the type (or from) to <type>.<suffix>.json. | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c29b-7faf-8b58-bd82cdfa2e75/templates" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"type": "product", "suffix": "gift"}' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c29b-7faf-8b58-bd82cdfa2e75/templates", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({"type": "product", "suffix": "gift"}), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c29b-7faf-8b58-bd82cdfa2e75/templates", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={"type": "product", "suffix": "gift"}, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode(['type' => 'product', 'suffix' => 'gift'], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{"type": "product", "suffix": "gift"}` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c29b-7faf-8b58-bd82cdfa2e75/templates", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/themes/0193a1b2-c29b-7faf-8b58-bd82cdfa2e75/templates"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" {"type": "product", "suffix": "gift"} """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` --- # Translations URL: https://sooquna.com/docs/api/admin/translations > Admin API 2026-10: Languages and translated content. {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Languages and translated content. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [List the store's published languages](#list-the-store-s-published-languages) | GET | `/locales` | | [Get a resource's translations](#get-a-resource-s-translations) | GET | `/translations` | | [List resources and their translation status](#list-resources-and-their-translation-status) | GET | `/translations/resources` | | [Save translations](#save-translations) | PUT | `/translations` | ## List the store's published languages GET `/locales` · Scope: `read_translations` ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/locales" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/locales", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/locales", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/locales", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/locales"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "available": [ {"code": "ur", "dir": "rtl", "endonym": "اردو", "name": "Urdu"}, {"code": "fa", "dir": "rtl", "endonym": "فارسی", "name": "Persian"} ], "limit": 5, "locales": [ { "code": "en", "dir": "ltr", "endonym": "English", "name": "English", "primary": true, "published": true }, { "code": "ar", "dir": "rtl", "endonym": "العربية", "name": "Arabic", "primary": false, "published": true } ], "settings": { "arabic_digits": false, "hijri_dates": false, "money_formats": {}, "translate_handles": false } } ```
    ## Get a resource's translations GET `/translations` · Scope: `read_translations` | Parameter | In | Description | | --- | --- | --- | | `resource_type` | query | For example `product`. | | `resource_id` | query | An ID, as in the example. | | `locale` | query | For example `ar`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/translations?resource_type=product&resource_id=0193a1b2-c3d4-7e5f-8a6b-000000000005&locale=ar" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/translations?resource_type=product&resource_id=0193a1b2-c3d4-7e5f-8a6b-000000000005&locale=ar", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/translations?resource_type=product&resource_id=0193a1b2-c3d4-7e5f-8a6b-000000000005&locale=ar", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/translations?resource_type=product&resource_id=0193a1b2-c3d4-7e5f-8a6b-000000000005&locale=ar", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/translations?resource_type=product&resource_id=0193a1b2-c3d4-7e5f-8a6b-000000000005&locale=ar"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "fields": [ { "key": "title", "kind": "text", "outdated": false, "source": "Embroidered linen abaya", "value": "" }, { "key": "handle", "kind": "handle", "outdated": false, "source": "embroidered-linen-abaya", "value": "" } ], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "locale": "ar", "type": "product" } ```
    ## List resources and their translation status GET `/translations/resources` · Scope: `read_translations` | Parameter | In | Description | | --- | --- | --- | | `type` | query | For example `product`. | | `locale` | query | For example `ar`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/translations/resources?type=product&locale=ar" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/translations/resources?type=product&locale=ar", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/translations/resources?type=product&locale=ar", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/translations/resources?type=product&locale=ar", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/translations/resources?type=product&locale=ar"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "data": [ { "fields": 6, "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "outdated": 0, "title": "Embroidered linen abaya", "translated": 0, "type": "product" } ], "types": ["product", "collection"] } ```
    ## Save translations PUT `/translations` · Scope: `write_translations` ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/translations" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "resource_type": "product", "resource_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "locale": "ar", "values": { "title": "عباية كتان مطرزة", "body_html": "

    كتان ناعم مطرز يدوياً في الدوحة.

    " } }' ```
    ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/translations", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "resource_type": "product", "resource_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "locale": "ar", "values": { "title": "عباية كتان مطرزة", "body_html": "

    كتان ناعم مطرز يدوياً في الدوحة.

    " } }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```
    ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/translations", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "resource_type": "product", "resource_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "locale": "ar", "values": { "title": "عباية كتان مطرزة", "body_html": "

    كتان ناعم مطرز يدوياً في الدوحة.

    ", }, }, ) res.raise_for_status() print(res.json()) ```
    ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'resource_type' => 'product', 'resource_id' => '0193a1b2-c3d4-7e5f-8a6b-000000000005', 'locale' => 'ar', 'values' => [ 'title' => 'عباية كتان مطرزة', 'body_html' => '

    كتان ناعم مطرز يدوياً في الدوحة.

    ', ], ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ```
    ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "resource_type": "product", "resource_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "locale": "ar", "values": { "title": "عباية كتان مطرزة", "body_html": "

    كتان ناعم مطرز يدوياً في الدوحة.

    " } }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/translations", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ```
    ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/translations"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "resource_type": "product", "resource_id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "locale": "ar", "values": { "title": "عباية كتان مطرزة", "body_html": "

    كتان ناعم مطرز يدوياً في الدوحة.

    " } } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "fields": [ { "key": "title", "kind": "text", "outdated": false, "source": "Embroidered linen abaya", "value": "عباية كتان مطرزة" }, { "key": "body_html", "kind": "html", "outdated": false, "source": "", "value": "

    كتان ناعم مطرز يدوياً في الدوحة.

    " } ], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "locale": "ar", "type": "product" } ```
    --- # Webhooks URL: https://sooquna.com/docs/api/admin/webhooks > Admin API 2026-10: Webhooks {/* Generated by web/marketing/scripts/docs-api.mjs from api/. Edit those files, not this one. */} Endpoints for webhooks. Every example sets `SOOQUNA_TOKEN` from the environment; see [authentication](/docs/api#admin-api). Responses are from a test store, cut to two items per list. | Endpoint | Method | Path | | --- | --- | --- | | [Subscribe to a webhook topic](#subscribe-to-a-webhook-topic) | POST | `/webhooks` | | [List webhook subscriptions](#list-webhook-subscriptions) | GET | `/webhooks` | | [Get a webhook subscription](#get-a-webhook-subscription) | GET | `/webhooks/{id}` | | [Update a webhook subscription](#update-a-webhook-subscription) | PUT | `/webhooks/{id}` | | [Send a test delivery](#send-a-test-delivery) | POST | `/webhooks/{id}/test` | | [List recent deliveries](#list-recent-deliveries) | GET | `/webhooks/{id}/deliveries` | | [Resend a delivery](#resend-a-delivery) | POST | `/webhooks/{id}/deliveries/{webhook_id}/resend` | | [Pause a subscription](#pause-a-subscription) | POST | `/webhooks/{id}/disable` | | [Resume a subscription](#resume-a-subscription) | POST | `/webhooks/{id}/enable` | | [Delete a subscription](#delete-a-subscription) | DELETE | `/webhooks/{id}` | ## Subscribe to a webhook topic POST `/webhooks` · Any token ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/webhooks" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "api_version": "2026-10" }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "api_version": "2026-10" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/webhooks", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "api_version": "2026-10", }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'topic' => 'orders/create', 'endpoint' => 'https://erp.example.com/sooquna/orders', 'api_version' => '2026-10', ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "api_version": "2026-10" }` req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/webhooks", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/webhooks"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "api_version": "2026-10" } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 201 ```json { "api_version": "2026-10", "app_id": "0193a1b2-c3d4-7e5f-8a6b-000000000047", "app_name": "Docs", "created_at": "2026-10-18T09:30:00Z", "disabled_at": null, "endpoint": "https://erp.example.com/sooquna/orders", "failure_since": null, "fields": [], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000048", "metafield_namespaces": [], "status": "active", "topic": "orders/create", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
    ## List webhook subscriptions GET `/webhooks` · Any token ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/webhooks" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/webhooks", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/webhooks", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/webhooks"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "data": [ { "api_version": "2026-10", "app_id": "0193a1b2-c3d4-7e5f-8a6b-000000000047", "app_name": "Docs", "created_at": "2026-10-18T09:30:00Z", "disabled_at": null, "endpoint": "https://erp.example.com/sooquna/orders", "failure_since": null, "fields": [], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000048", "metafield_namespaces": [], "status": "active", "topic": "orders/create", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ] } ```
    ## Get a webhook subscription GET `/webhooks/{id}` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "api_version": "2026-10", "app_id": "0193a1b2-c3d4-7e5f-8a6b-000000000047", "app_name": "Docs", "created_at": "2026-10-18T09:30:00Z", "disabled_at": null, "endpoint": "https://erp.example.com/sooquna/orders", "failure_since": null, "fields": [], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000048", "metafield_namespaces": [], "status": "active", "topic": "orders/create", "updated_at": "2026-10-18T09:30:00Z", "version": 1 } ```
    ## Update a webhook subscription PUT `/webhooks/{id}` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X PUT "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "fields": ["id", "name", "total_price", "financial_status"], "version": 1 }' ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", { method: "PUT", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, "Content-Type": "application/json", }, body: JSON.stringify({ "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "fields": ["id", "name", "total_price", "financial_status"], "version": 1 }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.put( "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, json={ "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "fields": ["id", "name", "total_price", "financial_status"], "version": 1, }, ) res.raise_for_status() print(res.json()) ``` ```php 'PUT', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode([ 'topic' => 'orders/create', 'endpoint' => 'https://erp.example.com/sooquna/orders', 'fields' => ['id', 'name', 'total_price', 'financial_status'], 'version' => 1, ], JSON_UNESCAPED_UNICODE), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "fields": ["id", "name", "total_price", "financial_status"], "version": 1 }` req, err := http.NewRequest("PUT", "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", strings.NewReader(body)) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Put, "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); req.Content = new StringContent(""" { "topic": "orders/create", "endpoint": "https://erp.example.com/sooquna/orders", "fields": ["id", "name", "total_price", "financial_status"], "version": 1 } """, Encoding.UTF8, "application/json"); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "api_version": "2026-10", "app_id": "0193a1b2-c3d4-7e5f-8a6b-000000000047", "app_name": "Docs", "created_at": "2026-10-18T09:30:00Z", "disabled_at": null, "endpoint": "https://erp.example.com/sooquna/orders", "failure_since": null, "fields": ["id", "name"], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000048", "metafield_namespaces": [], "status": "active", "topic": "orders/create", "updated_at": "2026-10-18T09:30:00Z", "version": 2 } ```
    ## Send a test delivery POST `/webhooks/{id}/test` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/test" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/test", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/test", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/test", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/test"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## List recent deliveries GET `/webhooks/{id}/deliveries` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `limit` | query | For example `20`. | ```bash curl -X GET "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries?limit=20" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries?limit=20", { method: "GET", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.get( "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries?limit=20", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'GET', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries?limit=20", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries?limit=20"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json {"data": []} ```
    ## Resend a delivery POST `/webhooks/{id}/deliveries/{webhook_id}/resend` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | | `webhook_id` | path | The webhook ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries/0193a1b2-0d08-78d5-8cf4-7748fc34dca0/resend" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries/0193a1b2-0d08-78d5-8cf4-7748fc34dca0/resend", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries/0193a1b2-0d08-78d5-8cf4-7748fc34dca0/resend", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries/0193a1b2-0d08-78d5-8cf4-7748fc34dca0/resend", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/deliveries/0193a1b2-0d08-78d5-8cf4-7748fc34dca0/resend"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ``` ## Pause a subscription POST `/webhooks/{id}/disable` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/disable" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/disable", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/disable", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/disable", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/disable"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "api_version": "2026-10", "app_id": "0193a1b2-c3d4-7e5f-8a6b-000000000047", "app_name": "Docs", "created_at": "2026-10-18T09:30:00Z", "disabled_at": "2026-10-18T09:30:00Z", "endpoint": "https://erp.example.com/sooquna/orders", "failure_since": null, "fields": ["id", "name"], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000048", "metafield_namespaces": [], "status": "disabled", "topic": "orders/create", "updated_at": "2026-10-18T09:30:00Z", "version": 3 } ```
    ## Resume a subscription POST `/webhooks/{id}/enable` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X POST "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/enable" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/enable", { method: "POST", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.post( "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/enable", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'POST', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("POST", "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/enable", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048/enable"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 200 ```json { "api_version": "2026-10", "app_id": "0193a1b2-c3d4-7e5f-8a6b-000000000047", "app_name": "Docs", "created_at": "2026-10-18T09:30:00Z", "disabled_at": null, "endpoint": "https://erp.example.com/sooquna/orders", "failure_since": null, "fields": ["id", "name"], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000048", "metafield_namespaces": [], "status": "active", "topic": "orders/create", "updated_at": "2026-10-18T09:30:00Z", "version": 4 } ```
    ## Delete a subscription DELETE `/webhooks/{id}` · Any token | Parameter | In | Description | | --- | --- | --- | | `id` | path | The resource's ID. | ```bash curl -X DELETE "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048" \ -H "X-Sooquna-Access-Token: $SOOQUNA_TOKEN" ``` ```js const res = await fetch("https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", { method: "DELETE", headers: { "X-Sooquna-Access-Token": process.env.SOOQUNA_TOKEN, }, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ``` ```python res = requests.delete( "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", headers={ "X-Sooquna-Access-Token": os.environ["SOOQUNA_TOKEN"], }, ) res.raise_for_status() print(res.json()) ``` ```php 'DELETE', CURLOPT_HTTPHEADER => [ 'X-Sooquna-Access-Token: ' . getenv('SOOQUNA_TOKEN'), ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($status >= 300) { throw new RuntimeException("$status: $response"); } $data = json_decode($response, true); print_r($data); ``` ```go package main "fmt" "io" "net/http" "os" ) func main() { req, err := http.NewRequest("DELETE", "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048", nil) if err != nil { panic(err) } req.Header.Set("X-Sooquna-Access-Token", os.Getenv("SOOQUNA_TOKEN")) res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { data, _ := io.ReadAll(res.Body) panic(fmt.Sprintf("%d: %s", res.StatusCode, data)) } data, _ := io.ReadAll(res.Body) fmt.Println(string(data)) } ``` ```csharp using System.Text; using var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Delete, "https://api.sooquna.com/admin/api/2026-10/webhooks/0193a1b2-c3d4-7e5f-8a6b-000000000048"); req.Headers.Add("X-Sooquna-Access-Token", Environment.GetEnvironmentVariable("SOOQUNA_TOKEN")); var res = await client.SendAsync(req); if (!res.IsSuccessStatusCode) throw new Exception($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}"); Console.WriteLine(await res.Content.ReadAsStringAsync()); ```
    Response 204 ```json {} ```
    --- # Assets URL: https://sooquna.com/docs/architecture/assets > CSS, JavaScript, fonts and images in assets/, and how they're served and cached. Files in `assets/` are served from the store's own domain: ```liquid {{ 'base.css' | asset_url | stylesheet_tag }} {{ shop.name }} ``` `asset_url` gives `/cdn/shop/t//assets/base.css?v=`. The hash changes when the file changes, so browsers keep each version for a year and fetch the new one at once after a save. ## What can go in assets/ CSS, JavaScript, JSON, SVG, text, images (PNG, JPEG, WebP, AVIF, GIF, ICO), fonts (WOFF2, WOFF, TTF, OTF), MP4 and WebM video, and PDF, up to 20 MB each. Text files are created in the code editor; images, fonts and media are uploaded with **Upload asset**. Uploaded SVGs are cleaned of scripts. ## Liquid in assets isn't rendered `assets/theme.css.liquid` is served as it is. CSS that depends on settings goes in a `{% style %}` tag in a snippet or section, as Sahil's `snippets/css-variables.liquid` does: ```liquid title="snippets/css-variables.liquid" {%- style -%} :root { --page-width: {{ settings.page_width }}px; --radius: {{ settings.radius }}px; } {%- endstyle -%} ``` ## Images merchants choose Logos, banners and other images merchants pick come from [`image_picker`](/docs/settings/input-settings/image_picker) settings, not from `assets/`. Pass them to [`image_url`](/docs/liquid/filters/image_url) to get resized WebP copies from the image CDN. ## Fonts Ship font files in `assets/` and declare them with `@font-face` (see [Fonts](/docs/settings/fonts)). Preload the one or two files the first screen needs: ```liquid ``` --- # Blocks URL: https://sooquna.com/docs/architecture/blocks > Local blocks, theme blocks, nesting, static blocks and passing data to blocks. Blocks are the parts of a section merchants add and reorder: slides of a slideshow, columns of a multicolumn section, the title, price and buy buttons of a product page. ## Local blocks Defined in the section's schema and drawn by the section's own loop: ```liquid {% for block in section.blocks %}
    {%- case block.type -%} {%- when 'image' -%}{{ block.settings.image | image_url: width: 800 | image_tag }} {%- when 'text' -%}{{ block.settings.text }} {%- endcase -%}
    {% endfor %} {% schema %} { "name": "Multicolumn", "blocks": [ { "type": "image", "name": "Image", "settings": [{ "type": "image_picker", "id": "image", "label": "Image" }] }, { "type": "text", "name": "Text", "settings": [{ "type": "richtext", "id": "text", "label": "Text" }] } ] } {% endschema %} ``` Always output `{{ block.shopify_attributes }}` on the block's outer element: the visual editor needs it to select the block. ## Theme blocks A theme block is a file in `blocks/` with its own schema. Many sections can use it, and blocks can hold other blocks. ```liquid title="blocks/heading.liquid"

    {{ block.settings.text }}

    {% schema %} { "name": "Heading", "settings": [ { "type": "inline_richtext", "id": "text", "label": "Text", "default": "Heading" }, { "type": "select", "id": "size", "label": "Size", "default": "md", "options": [{ "value": "sm", "label": "Small" }, { "value": "md", "label": "Medium" }, { "value": "lg", "label": "Large" }] } ], "presets": [{ "name": "Heading" }] } {% endschema %} ``` A section accepts theme blocks with `{ "type": "@theme" }` (any of them) or by name (`{ "type": "heading" }`), and renders them with: ```liquid {% content_for 'blocks' %} ``` A theme block that holds blocks does the same: `"blocks": [{ "type": "@theme" }]` in its schema and `{% content_for 'blocks' %}` in its markup. Nesting stops at 8 levels. ### Private blocks A file whose name starts with `_` (`blocks/_card-media.liquid`) is a private block: it isn't offered for `@theme`, only to sections and blocks that name it. ### Static blocks A section can place a theme block itself, where merchants can edit its settings but not move or delete it: ```liquid {% content_for 'block', type: 'heading', id: 'title' %} ``` The `id` keeps its settings in the template's JSON. ## Passing data down A product section hands its product to every block inside it, however deep: ```liquid title="sections/main-product.liquid" {% content_for 'blocks', closest.product: product %} ``` ```liquid title="blocks/product-price.liquid" {%- assign product = closest.product | default: product -%}
    {{ product.price | money }}
    ``` So one price block works on the product page, in a featured product section and in quick view. See [`closest`](/docs/liquid/objects/closest). ## Blocks tied to store features Like sections, a block can set `"capability": "wishlist"` in its schema to render only while that [store feature](/docs/storefront/store-features) is on, and to be hidden from the editor while it's off. --- # Config URL: https://sooquna.com/docs/architecture/config > Theme settings (settings_schema.json), their values (settings_data.json) and style presets. ## settings_schema.json The theme settings merchants see under **Theme settings** in the visual editor, in groups. The theme's name and version live in [`theme.json`](/docs/architecture/directory-structure#themejson). ```json title="config/settings_schema.json" [ { "name": "Colors", "settings": [ { "type": "header", "content": "Scheme 1" }, { "type": "color", "id": "scheme_1_background", "label": "Background", "default": "#FBF8F3" }, { "type": "color", "id": "scheme_1_text", "label": "Text", "default": "#1C1917" } ] }, { "name": "Cart", "settings": [ { "type": "select", "id": "cart_type", "label": "Cart type", "default": "drawer", "options": [{ "value": "drawer", "label": "Drawer" }, { "value": "page", "label": "Page" }] } ] } ] ``` Read the values anywhere as `settings.`: `{{ settings.cart_type }}`. Setting IDs are unique across the whole file. A group can set `"capability"` to show only while a [store feature](/docs/storefront/store-features) is on. ## settings_data.json The current values, written by the visual editor, and named presets: ```json title="config/settings_data.json" { "current": "Default", "presets": { "Default": { "scheme_1_background": "#FBF8F3", "cart_type": "drawer" }, "Night": { "scheme_1_background": "#121212", "scheme_1_text": "#F5F5F4" } } } ``` `current` is a preset name, or an object of values once the merchant changes something. Presets are the theme's styles: merchants choose one in **Theme settings** and start from it. A setting without a value takes its `default` from the schema. The theme check refuses a `current` that names a preset that doesn't exist, and values that don't fit their setting (a number out of range, an unknown select option). --- # Custom pages URL: https://sooquna.com/docs/architecture/custom-pages > Standalone Liquid pages at /custom/, attached to store pages and linked from menus. A custom page is a Liquid file in `custom_pages/` that draws a whole page: a size guide, a Ramadan landing page, a store locator. It's a Sooquna addition to the Shopify theme structure. The [tutorial](/docs/getting-started/custom-page) builds one step by step. ```liquid title="custom_pages/size-guide.liquid"

    {{ custom_page.title }}

    {{ custom_page.settings.intro }} …
    {% schema %} { "name": "Size guide", "layout": "theme", "seo": { "title": "Size guide", "description": "How to find your size." }, "settings": [{ "type": "richtext", "id": "intro", "label": "Introduction", "default": "

    Measurements in centimetres.

    " }] } {% endschema %} ``` ## Naming and URL The file name is the URL: `custom_pages/size-guide.liquid` is at `/custom/size-guide` (and `/ar/custom/size-guide` in Arabic). Names use lowercase letters, digits and `-`. Custom pages are listed in the sitemap. ## Schema | Key | Meaning | | --- | --- | | `name` | The name in admin pickers, and the page title if `seo.title` isn't set. | | `layout` | `"theme"` (default) to draw inside `layout/theme.liquid`; `"none"` for a page without the layout. | | `seo` | `title` and `description` of `/custom/`. | | `settings` | Settings read as `custom_page.settings`. They take their defaults; to let merchants change text, attach the page to a store page and use `page.content`. | ## In the page | Variable | Value | | --- | --- | | [`custom_page`](/docs/liquid/objects/custom_page) | `name`, `title`, `url` and `settings`. | | `page` | The store page, when one uses this file (below). Not set at `/custom/`. | Everything else works as in a template: global objects, `{% render %}`, `{% section 'name' %}` to place a section, `{% stylesheet %}`. ## Attaching to a store page In **Storefront › Pages**, a page's **Theme template** can be **Custom page: **. Then `/pages/` draws the custom page, with `page` set and `custom_page.title` taken from the page. The merchant gets a translatable title and handle, SEO fields and visibility dates; you keep the layout in code. ## Links The admin link pickers (menus, buttons, the [`url`](/docs/settings/input-settings/url) setting) offer **Custom pages** next to products and collections. Links are stored by name and resolve to the right URL at render time, with the language prefix. A [`custom_page`](/docs/settings/input-settings/custom_page) setting lets a section pick one. ## Renaming and deleting Before you rename or delete a custom page, the code editor lists the store pages that use it. Links to a deleted custom page render `#`, and pages that used it fall back to their normal template. --- # Directory structure URL: https://sooquna.com/docs/architecture/directory-structure > The folders of a Sooquna theme, what each file name may be, and the theme's limits. ```text theme/ ├── layout/ theme.liquid (required), password.liquid ├── templates/ index.json (required), product.json, product..json, … │ ├── customers/ (accepted for Shopify themes; account pages are drawn by Sooquna) │ └── metaobject/ .json: pages for metaobject entries ├── sections/ *.liquid sections, and *.json section groups ├── blocks/ *.liquid theme blocks (_name.liquid for private blocks) ├── snippets/ *.liquid partials for {% render %} ├── custom_pages/ *.liquid standalone pages at /custom/ ├── assets/ CSS, JS, fonts, images, SVG ├── config/ settings_schema.json (required), settings_data.json ├── locales/ en.default.json, ar.json, *.schema.json └── theme.json name, version, author, supported locales ``` ## File names | Folder | Allowed names | | --- | --- | | `layout/`, `snippets/` | lowercase letters, digits, `-` and `_`, ending in `.liquid` | | `templates/` | `.json` or `.liquid`, optionally `..json`; also `robots.txt.liquid` | | `sections/` | `.liquid`, or `.json` for a section group | | `blocks/` | `.liquid`; a leading `_` hides the block from merchants' block lists | | `custom_pages/` | lowercase letters, digits and `-`, ending in `.liquid` (the name is the URL) | | `assets/` | any of letters, digits, `.`, `-` and `_`; CSS, JS, JSON, SVG, text, Liquid, images, fonts and media | | `locales/` | a language code (`ar`, `en`), optionally `.default` and `.schema`: `en.default.schema.json` | ## Required files - `layout/theme.liquid` - `templates/index.json` (or `templates/index.liquid`) - `config/settings_schema.json` Every other template is optional. Without `page`, `blog` or `article` templates, Sooquna draws those pages plainly inside your layout; other missing templates show an error in previews, so add one for each page type your store uses. ## theme.json ```json title="theme.json" { "name": "Sahil", "version": "1.1.0", "author": "Sooquna", "support_url": "https://sooquna.com/docs/themes/sahil", "supported_locales": ["en", "ar"], "rtl": true } ``` ## Limits | Limit | Value | | --- | --- | | Files per theme | 2,000 | | Text file size | 5 MB | | Asset size | 20 MB | | Sections per template | 256 | | Blocks per section | 50 (lower it with `max_blocks`) | | Block nesting | 8 levels | | Themes per store | 20 | --- # Layouts URL: https://sooquna.com/docs/architecture/layouts > The page frame every template is drawn inside, and what a layout must output. A layout is the HTML around every page: ``, ``, the header and footer. Templates use `layout/theme.liquid` unless they choose another. ```liquid title="layout/theme.liquid" {{ page_title }}{% unless page_title == shop.name %} – {{ shop.name }}{% endunless %} {%- if page_description != blank %}{% endif %} {{ 'base.css' | asset_url | stylesheet_tag }} {{ content_for_header }} {% sections 'header-group' %}
    {{ content_for_layout }}
    {% sections 'footer-group' %} ``` ## Required output | Object | Where | What it adds | | --- | --- | --- | | [`content_for_header`](/docs/liquid/objects/content_for_header) | inside `` | `hreflang` links, robots meta on previews, analytics and pixels (after consent), the visual editor bridge | | [`content_for_layout`](/docs/liquid/objects/content_for_layout) | inside `` | the template's sections | Set `dir` from [`request.locale.direction`](/docs/liquid/objects/request) so the page flips for Arabic. See [RTL and Arabic typography](/docs/best-practices/rtl-arabic). ## Choosing a layout - A JSON template: `"layout": "landing"` uses `layout/landing.liquid`; `"layout": false` renders without one. - A Liquid template: `{% layout 'landing' %}` or `{% layout none %}`. - A custom page: `"layout"` in its schema (`"theme"` by default, `"none"` for a bare page). - The password page uses `layout/password.liquid` when the theme has it. --- # Locales URL: https://sooquna.com/docs/architecture/locales > Storefront text and editor labels in every language, with plural forms for Arabic. ## Storefront text `locales/.json` holds the text the theme prints. One file is the default (`en.default.json`); keys missing from another language fall back to it. ```json title="locales/en.default.json" { "products": { "add_to_cart": "Add to cart", "low_stock": "Only {{ count }} left", "reviews_html": "{{ rating }} out of 5" }, "cart": { "count": { "one": "{{ count }} item", "other": "{{ count }} items" } } } ``` ```liquid {{ 'products.add_to_cart' | t }} {{ 'products.low_stock' | t: count: variant.inventory_quantity }} {{ 'cart.count' | t: count: cart.item_count }} ``` - **Variables** are passed as `name: value` and written `{{ name }}` in the text. Their values are escaped. - **HTML**: only keys ending in `_html` may contain markup; other values are escaped. - **Plurals**: give an object of plural forms and pass `count`. English uses `one` and `other`; Arabic uses `zero`, `one`, `two`, `few`, `many` and `other`, picked by the CLDR rules: ```json title="locales/ar.json" { "cart": { "count": { "zero": "لا منتجات", "one": "منتج واحد", "two": "منتجان", "few": "{{ count }} منتجات", "many": "{{ count }} منتجاً", "other": "{{ count }} منتج" } } } ``` A missing key shows `translation missing: ar.cart.count` in the page, so it's easy to spot in previews. ## Editor labels Schema names and labels can be translated keys: `"label": "t:settings.cart_type"`. They're read from `locales/.schema.json`, shown in the merchant's admin language. ## Merchants' own wording Merchants can change any storefront text, per language, in **Storefront › Translate › Theme texts**, without editing files. Their wording wins over the locale files and survives theme updates. ## Sample content in other languages `locales/.content.json` translates the sample text a theme ships in its templates and section groups (headings, announcement text). When a merchant adds that language, the translations are offered as a starting point. Keys are paths to settings; values are `[source, translation]`: ```json title="locales/ar.content.json" { "sections/footer-group.json/sections/footer/blocks/shop/settings/heading": ["Shop", "تسوّق"] } ``` --- # Sections URL: https://sooquna.com/docs/architecture/sections > Section files, their schema, presets, section groups and where sections are allowed. A section is a part of a page merchants can add, remove, reorder and configure: a banner, a product grid, a newsletter sign-up. It's a Liquid file in `sections/` with a `{% schema %}`. ```liquid title="sections/rich-text.liquid"
    {%- if section.settings.heading != blank -%}

    {{ section.settings.heading }}

    {%- endif -%} {{ section.settings.text }}
    {% schema %} { "name": "t:sections.rich_text.name", "tag": "section", "class": "section-rich-text", "settings": [ { "type": "text", "id": "heading", "label": "Heading", "default": "Talk about your brand" }, { "type": "richtext", "id": "text", "label": "Text" } ], "presets": [{ "name": "Rich text" }] } {% endschema %} ``` ## Schema keys | Key | Meaning | | --- | --- | | `name` | The name in the editor (a `t:` key for translated names). | | `tag` | The wrapper element: `section`, `div` (default), `article`, `aside`, `header` or `footer`. | | `class` | Extra classes on the wrapper, after `shopify-section`. | | `limit` | How many times the section can be on one page. | | `settings` | Inputs; see [Input setting types](/docs/settings/input-settings). | | `blocks` | Block types the section accepts: local blocks with their own settings, theme blocks by name, or `{ "type": "@theme" }` for any theme block. | | `max_blocks` | At most this many blocks (50 by default and at most). | | `presets` | Entries in **Add section**: a name, starting settings and blocks. Without a preset the section can't be added from the editor. | | `enabled_on`, `disabled_on` | Where the section may be added; see below. | | `capability` | A [store feature](/docs/storefront/store-features); the section renders only while it's on. Sooquna only. | ## The wrapper Every section is wrapped in its `tag`: ```html
    …
    ``` The ID is stable, so CSS and JavaScript can target it, and the [section rendering API](/docs/storefront/section-rendering) uses it to re-render one section. ## Section groups A section group is a JSON file in `sections/` that holds sections shared by every page: the header and the footer. A layout renders it with `{% sections 'header-group' %}`. ```json title="sections/header-group.json" { "type": "header", "name": "Header group", "sections": { "announcement": { "type": "announcement-bar", "settings": { "color_scheme": "brand" } }, "header": { "type": "header", "settings": { "menu": "main-menu", "sticky": true } } }, "order": ["announcement", "header"] } ``` `type` is `header`, `footer` or `overlay` (popups, drawers). Section IDs in a group look like `sections--header-group__header`. ## Where sections can go ```json "enabled_on": { "templates": ["product", "collection"] }, "disabled_on": { "groups": ["header", "footer"] } ``` - `templates`: template types (`product`, `index`…) or `"*"`. - `groups`: section group types (`header`, `footer`, `overlay`) or `"*"`. - With `enabled_on`, the section goes only where it lists. With `disabled_on`, everywhere except where it lists. ## Rendering a section from code `{% section 'newsletter' %}` renders a section file in place, with its default settings. Use it in layouts and custom pages for sections the merchant shouldn't move. ## Assets of a section `{% stylesheet %}` and `{% javascript %}` hold CSS and JavaScript for the section. They're output once per page, however many times the section is used. CSS that uses settings goes in `{% style %}`, which the editor updates as the merchant changes values. --- # Snippets and render URL: https://sooquna.com/docs/architecture/snippets > Reusable Liquid partials, rendered with their own variables. A snippet is a Liquid file in `snippets/` you render from anywhere: a product card, an icon, a price. ```liquid {% render 'product-card', product: product, sizes: '(min-width: 990px) 25vw, 50vw' %} ``` ## Isolated scope A snippet sees **only** the variables you pass and the global objects (`shop`, `settings`, `cart`, `request`…). Variables assigned outside aren't visible inside, and variables assigned inside don't leak out. This keeps snippets predictable: a snippet works the same wherever it's rendered. ```liquid {% assign badge = 'New' %} {% render 'card', product: product %} {%- comment -%} card can't see badge {%- endcomment -%} {% render 'card', product: product, badge: badge %} ``` ## Rendering for each item ```liquid {% render 'product-card' for collection.products as product %} ``` Inside, `product` is each item and `forloop` works as in a `for` loop. ```liquid {% render 'price' with product.selected_or_first_available_variant as variant %} ``` ## include isn't supported Shopify's deprecated `{% include %}` shares the caller's variables, which makes snippets fragile. Sooquna doesn't support it: replace it with `render` and pass what the snippet needs. The theme check flags any `include`. ## Document a snippet Describe parameters in a `{% doc %}` block at the top. It isn't rendered. ```liquid title="snippets/price.liquid" {% doc %} Shows a price with the compare-at price struck through. @param {variant} variant - The variant to price {% enddoc %} ``` ## Limits Snippets can render snippets, up to 10 levels deep. --- # Templates URL: https://sooquna.com/docs/architecture/templates > JSON and Liquid templates, alternate templates, and which template each page uses. A template draws one type of page. The [rendering overview](/docs/getting-started/how-rendering-works#1-the-request-picks-a-store-a-theme-and-a-template) lists which URL uses which template. ## JSON templates JSON templates are the default. They list sections, and the visual editor edits them: when a merchant adds, removes or reorders a section, this file changes. ```json title="templates/collection.json" { "layout": "theme", "wrapper": "div.collection-page", "sections": { "banner": { "type": "collection-banner", "settings": { "show_description": true } }, "grid": { "type": "main-collection", "blocks": { "f": { "type": "filters" } }, "block_order": ["f"], "settings": { "per_page": 24 } } }, "order": ["banner", "grid"] } ``` | Key | Meaning | | --- | --- | | `sections` | Section entries by ID: `type` is the file in `sections/`, then `settings`, `blocks`, `block_order`. | | `order` | The order the sections render in. Every ID in `order` must exist in `sections`. | | `layout` | Optional: another layout name, or `false` for none. | | `wrapper` | Optional: an element around all sections, such as `div.collection-page` or `main#content[data-x=y]`. | A section entry can set `"disabled": true` to keep it in the file without rendering it. ## Liquid templates `templates/page.faq.liquid` is rendered as Liquid, with no sections the merchant can arrange. Use Liquid templates for pages that are mostly code (a `robots.txt.liquid`, an FAQ built from metaobjects); use JSON everywhere else. ## Alternate templates `templates/..json` is an alternate. In admin the merchant picks it per product, collection, page or blog post (the **Theme template** field). Common ones: - `product.quick-view.json` for quick-view popups, loaded with `?view=quick-view`. - `page.contact.json` for a contact page with the contact form. - `product.gift-card.json` for gift card products. ## Templates in Sahil `404`, `article`, `blog`, `cart`, `collection`, `index`, `list-collections`, `page`, `page.contact`, `password`, `product`, `product.quick-view`, `search` and `wishlist`, all JSON. ## Special templates | Template | Notes | | --- | --- | | `templates/robots.txt.liquid` | Replaces the default `robots.txt`. `{{ robots.default }}` holds the default rules. | | `templates/metaobject/.json` | Pages for metaobject entries; see [Metaobject pages](/docs/storefront/metaobject-pages). | | `templates/customers/*` | Accepted so Shopify themes upload, but not used: customer account pages are drawn by Sooquna in the theme's colours. See [Customer accounts](/docs/storefront/customer-accounts). | --- # Accessibility URL: https://sooquna.com/docs/best-practices/accessibility > A WCAG 2.2 AA checklist for Sooquna themes. Themes should meet WCAG 2.2 AA in both languages. Check each template with a keyboard, a screen reader (VoiceOver or TalkBack) and an automated checker. ## Checklist **Structure** - One `

    ` per page; headings in order. - Landmarks: `
    `, `