# 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.
GET `/access_scopes` · Any token
POST `/bulk-operations` · Any token
Exports a resource as JSONL to a signed download URL.
GET `/bulk-operations` · Any token
GET `/bulk-operations/{id}` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/bulk-operations/{id}/cancel` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/pages` · Scope: `write_content`
A family-run abaya house in Doha since 2009.
", "visible": true, "seo_description": "Our story." }' ```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); ```A family-run abaya house in Doha since 2009.
", "visible": True, "seo_description": "Our story.", }, ) res.raise_for_status() print(res.json()) ```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); ```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)) } ```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()); ```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 } ```GET `/pages` · Scope: `read_content`
| Parameter | In | Description |
| --- | --- | --- |
| `visibility` | query | For example `visible`. |
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 `/pages/{id}` · Scope: `read_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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 } ```PUT `/pages/{id}` · Scope: `write_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
A family-run abaya house in Doha since 2009.
", "custom_page_name": "", "visible": true, "version": 1 }' ```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); ```A family-run abaya house in Doha since 2009.
", "custom_page_name": "", "visible": True, "version": 1, }, ) res.raise_for_status() print(res.json()) ```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); ```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)) } ```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()); ```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 } ```POST `/pages/bulk` · Scope: `write_content`
POST `/blogs` · Scope: `write_content`
GET `/blogs` · Scope: `read_content`
PUT `/blogs/{id}` · Scope: `write_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/articles` · Scope: `write_content`
Five looks for Eid gatherings, from morning prayers to evening visits.
", "tags": ["eid", "style"], "visible": true }' ```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); ```Five looks for Eid gatherings, from morning prayers to evening visits.
", "tags": ["eid", "style"], "visible": True, }, ) res.raise_for_status() print(res.json()) ```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); ```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)) } ```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()); ```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 } ```GET `/articles` · Scope: `read_content`
| Parameter | In | Description |
| --- | --- | --- |
| `blog_id` | query | An ID, as in the example. |
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 `/articles/{id}` · Scope: `read_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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 } ```PUT `/articles/{id}` · Scope: `write_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
Six looks for Eid gatherings.
", "visible": true, "version": 1 }' ```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); ```Six looks for Eid gatherings.
", "visible": True, "version": 1, }, ) res.raise_for_status() print(res.json()) ```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); ```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)) } ```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()); ```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 } ```POST `/articles/bulk` · Scope: `write_content`
DELETE `/blogs/{id}` · Scope: `write_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/menus` · Scope: `write_content`
GET `/menus` · Scope: `read_content`
GET `/menus/{id}` · Scope: `read_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
DELETE `/menus/{id}` · Scope: `write_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/policies` · Scope: `read_content`
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 } ] } ```
PUT `/policies/{kind}` · Scope: `write_content`
kind: refund, privacy, terms, shipping, contact or legal.
| Parameter | In | Description |
| --- | --- | --- |
| `kind` | path | The kind ID. |
Unworn items can be returned within 14 days of delivery.
", "version": 1 }' ```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); ```Unworn items can be returned within 14 days of delivery.
", "version": 1, }, ) res.raise_for_status() print(res.json()) ```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); ```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)) } ```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()); ```POST `/redirects` · Scope: `write_content`
GET `/redirects` · Scope: `read_content`
| Parameter | In | Description |
| --- | --- | --- |
| `q` | query | For example `abayas`. |
PUT `/redirects/{id}` · Scope: `write_content`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/redirects/delete` · Scope: `write_content`
POST `/customers` · Scope: `write_customers` · Needs an `Idempotency-Key` header
GET `/customers` · Scope: `read_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `q` | query | For example `noora`. |
| `limit` | query | For example `10`. |
GET `/customers/count` · Scope: `read_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `tag` | query | For example `vip`. |
GET `/customers/tags` · Scope: `read_customers`
GET `/customers/{id}` · Scope: `read_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PATCH `/customers/{id}` · Scope: `write_customers`
Fields you leave out stay as they are.
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/customers/{id}/addresses` · Scope: `write_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PATCH `/customers/{id}/addresses/{address_id}` · Scope: `write_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `address_id` | path | The address ID. |
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. |
DELETE `/customers/{id}/addresses/{address_id}` · Scope: `write_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `address_id` | path | The address ID. |
PUT `/customers/{id}/marketing` · Scope: `write_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/customers/{id}/consents` · Scope: `read_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/customers/{id}/orders` · Scope: `read_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/customers/{id}/send-invite` · Scope: `write_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/customers/bulk` · Scope: `write_customers`
Actions: add_tags, remove_tags, delete.
POST `/segments` · Scope: `write_customers`
GET `/segments` · Scope: `read_customers`
GET `/segments/fields` · Scope: `read_customers`
GET `/segments/{id}` · Scope: `read_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/segments/{id}` · Scope: `write_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/segments/{id}` · Scope: `write_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/customers/{id}` · Scope: `write_customers`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/discounts` · Scope: `write_discounts`
method code or automatic; type order, product, shipping or bxgy; value_type percentage or fixed_amount.
GET `/discounts` · Scope: `read_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `status` | query | For example `scheduled`. |
GET `/discounts/lookup` · Scope: `read_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `code` | query | For example `EID10`. |
GET `/discounts/{id}` · Scope: `read_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/discounts/{id}` · Scope: `write_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/discounts/{id}/codes` · Scope: `write_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/discounts/{id}/codes/generate` · Scope: `write_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/discounts/{id}/codes` · Scope: `read_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `q` | query | For example `EID10`. |
DELETE `/discounts/{id}/codes/{code_id}` · Scope: `write_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `code_id` | path | The code ID. |
GET `/discounts/{id}/redemptions` · Scope: `read_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/discounts/{id}/duplicate` · Scope: `write_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/discounts/{id}/deactivate` · Scope: `write_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/discounts/{id}/activate` · Scope: `write_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/discounts/{id}` · Scope: `write_discounts`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/draft-orders/calculate` · Scope: `write_draft_orders`
POST `/draft-orders` · Scope: `write_draft_orders` · Needs an `Idempotency-Key` header
GET `/draft-orders` · Scope: `read_draft_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `status` | query | For example `open`. |
| `limit` | query | For example `10`. |
GET `/draft-orders/{id}` · Scope: `read_draft_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/draft-orders/{id}` · Scope: `write_draft_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
DELETE `/draft-orders/{id}` · Scope: `write_draft_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/files/uploads` · Scope: `write_files`
Returns a signed URL; PUT the file there, then complete the upload.
POST `/files/uploads/{id}/complete` · Scope: `write_files`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/files/imports` · Scope: `write_files`
GET `/files` · Scope: `read_files`
| Parameter | In | Description |
| --- | --- | --- |
| `kind` | query | For example `image`. |
| `limit` | query | For example `20`. |
GET `/files/{id}` · Scope: `read_files`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PATCH `/files/{id}` · Scope: `write_files`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/files/{id}/download` · Scope: `read_files`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/files/{id}/usage` · Scope: `read_files`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/files/{id}` · Scope: `write_files`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/orders/{id}/fulfillments` · Scope: `write_fulfillments` · Needs an `Idempotency-Key` header
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PATCH `/orders/{id}/fulfillments/{fulfillment_id}` · Scope: `write_fulfillments`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `fulfillment_id` | path | The fulfillment ID. |
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. |
GET `/orders/{id}/shipments` · Scope: `read_fulfillments`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
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. |
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. |
POST `/orders/{id}/shipping-labels/quotes` · Scope: `write_fulfillments`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/orders/{id}/shipping-labels` · Scope: `write_fulfillments`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/shipments/{id}/track` · Scope: `write_fulfillments`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/shipments/{id}/cancel` · Scope: `write_fulfillments`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/gift-cards` · Scope: `write_gift_cards`
GET `/gift-cards` · Scope: `read_gift_cards`
| Parameter | In | Description |
| --- | --- | --- |
| `status` | query | For example `active`. |
GET `/gift-cards/{id}` · Scope: `read_gift_cards`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/gift-cards/{id}` · Scope: `write_gift_cards`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
POST `/gift-cards/{id}/disable` · Scope: `write_gift_cards`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/gift-cards/{id}/enable` · Scope: `write_gift_cards`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/inventory` · Scope: `read_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `low_stock` | query | For example `true`. |
| `limit` | query | For example `20`. |
GET `/inventory/levels` · Scope: `read_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `item_ids` | query | An ID, as in the example. |
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.
POST `/inventory/move` · Scope: `write_inventory` · Needs an `Idempotency-Key` header
PATCH `/inventory/items/{id}` · Scope: `write_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/inventory/items/{id}/history` · Scope: `read_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `limit` | query | For example `20`. |
POST `/inventory-transfers` · Scope: `write_inventory`
GET `/inventory-transfers` · Scope: `read_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `status` | query | For example `draft`. |
GET `/inventory-transfers/{id}` · Scope: `read_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/inventory-transfers/{id}` · Scope: `write_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/inventory-transfers/{id}/ship` · Scope: `write_inventory` · Needs an `Idempotency-Key` header
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/inventory-transfers/{id}/receive` · Scope: `write_inventory` · Needs an `Idempotency-Key` header
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/inventory-transfers/{id}/cancel` · Scope: `write_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/inventory-transfers/{id}` · Scope: `write_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/suppliers` · Scope: `write_inventory`
GET `/suppliers` · Scope: `read_inventory`
PUT `/suppliers/{id}` · Scope: `write_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/purchase-orders` · Scope: `write_inventory`
GET `/purchase-orders` · Scope: `read_inventory`
GET `/purchase-orders/{id}` · Scope: `read_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/purchase-orders/{id}` · Scope: `write_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/purchase-orders/{id}/order` · Scope: `write_inventory` · Needs an `Idempotency-Key` header
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/purchase-orders/{id}/receive` · Scope: `write_inventory` · Needs an `Idempotency-Key` header
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
GET `/purchase-orders/{id}/pdf` · Scope: `read_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/purchase-orders/{id}` · Scope: `write_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/suppliers/{id}` · Scope: `write_inventory`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/locations` · Scope: `write_locations`
GET `/locations` · Scope: `read_locations`
GET `/locations/{id}` · Scope: `read_locations`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PATCH `/locations/{id}` · Scope: `write_locations`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/locations/{id}/deactivate` · Scope: `write_locations`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/locations/{id}/activate` · Scope: `write_locations`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/locations/{id}` · Scope: `write_locations`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/metafield-definitions` · Scope: `write_metaobjects`
GET `/metafield-definitions` · Scope: `read_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `owner_type` | query | For example `product`. |
PATCH `/metafield-definitions/{id}` · Scope: `write_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/metafields` · Scope: `write_metaobjects`
A null value deletes the field.
GET `/metafields` · Scope: `read_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `owner_type` | query | For example `product`. |
| `owner_id` | query | An ID, as in the example. |
DELETE `/metafield-definitions/{id}` · Scope: `write_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/metaobject-definitions` · Scope: `write_metaobjects`
GET `/metaobject-definitions` · Scope: `read_metaobjects`
PUT `/metaobject-definitions/{id}` · Scope: `write_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/metaobjects` · Scope: `write_metaobjects`
GET `/metaobjects` · Scope: `read_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `type` | query | For example `designer`. |
GET `/metaobjects/{id}` · Scope: `read_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/metaobjects/{id}` · Scope: `write_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/metaobjects/{id}` · Scope: `write_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/metaobject-definitions/{id}` · Scope: `write_metaobjects`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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`. |
GET `/orders/{id}` · Scope: `read_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
POST `/orders/{id}/mark-paid` · Scope: `write_orders` · Needs an `Idempotency-Key` header
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/orders/{id}/refunds/calculate` · Scope: `write_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
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. |
POST `/orders/{id}/close` · Scope: `write_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/orders/{id}/reopen` · Scope: `write_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/orders/{id}/cod-confirm` · Scope: `write_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/orders/{id}/invoices` · Scope: `read_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/orders/{id}/invoices` · Scope: `write_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/abandoned-checkouts` · Scope: `read_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `limit` | query | For example `20`. |
GET `/abandoned-checkouts/{id}` · Scope: `read_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/invoices` · Scope: `read_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `from` | query | For example `2026-10-01`. |
| `to` | query | For example `2026-10-31`. |
GET `/invoices/{id}` · Scope: `read_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/invoices/{id}/pdf` · Scope: `read_orders`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/products` · Scope: `write_products`
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"} ] }' ```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); ```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()) ```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); ```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)) } ```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()); ```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 } ```GET `/products` · Scope: `read_products`
| Parameter | In | Description |
| --- | --- | --- |
| `status` | query | For example `active`. |
| `limit` | query | For example `10`. |
GET `/products/{id}` · Scope: `read_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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 } ```GET `/products/{id}/variants` · Scope: `read_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
POST `/products/{id}/duplicate` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/products/bulk` · Scope: `write_products`
Actions: add_tags, remove_tags, set_status, publish, unpublish, add_to_collections, remove_from_collections, delete.
DELETE `/products/{id}` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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. |
PUT `/products/{id}/media/order` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PATCH `/products/{id}/media/{media_id}` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `media_id` | path | The media ID. |
DELETE `/products/{id}/media/{media_id}` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `media_id` | path | The media ID. |
POST `/collections` · Scope: `write_products`
kind manual takes product_ids; kind smart takes rules (column, relation, condition).
Pieces for Eid gatherings.
", "published": true, "product_ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"] }' ```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); ```Pieces for Eid gatherings.
", "published": True, "product_ids": ["0193a1b2-c3d4-7e5f-8a6b-000000000005"], }, ) res.raise_for_status() print(res.json()) ```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); ```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)) } ```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()); ```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 } ```GET `/collections` · Scope: `read_products`
| Parameter | In | Description |
| --- | --- | --- |
| `limit` | query | For example `10`. |
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 `/collections/{id}` · Scope: `read_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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 } ```PUT `/collections/{id}` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/collections/{id}/products` · Scope: `read_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `limit` | query | For example `24`. |
POST `/collections/{id}/products` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/collections/{id}/products/order` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/collections/{id}/products/remove` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/collections/{id}` · Scope: `write_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/taxonomy` · Scope: `read_products`
| Parameter | In | Description |
| --- | --- | --- |
| `q` | query | For example `abaya`. |
| `locale` | query | For example `en`. |
GET `/taxonomy/{id}` · Scope: `read_products`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `locale` | query | For example `ar`. |
GET `/analytics/reports` · Scope: `read_reports`
GET `/analytics/reports/{key}` · Scope: `read_reports`
| Parameter | In | Description |
| --- | --- | --- |
| `key` | path | The key ID. |
| `group_by` | query | For example `day`. |
GET `/orders/{id}/returns` · Scope: `read_returns`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/returns` · Scope: `read_returns`
| Parameter | In | Description |
| --- | --- | --- |
| `status` | query | For example `requested`. |
GET `/returns/{id}` · Scope: `read_returns`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/returns/{id}` · Scope: `write_returns`
Actions: approve (with instructions), decline (with reason), receive, close.
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/shipping/profiles` · Scope: `read_shipping`
GET `/shipping/profiles/{id}` · Scope: `read_shipping`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/shipping/profiles/{id}/products` · Scope: `read_shipping`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `limit` | query | For example `20`. |
GET `/shipping/local-delivery` · Scope: `read_shipping`
GET `/shipping/local-delivery/{id}` · Scope: `read_shipping`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/shipping/local-delivery/{id}/slots` · Scope: `read_shipping`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/shipping/pickup` · Scope: `read_shipping`
GET `/shipping/packages` · Scope: `read_shipping`
GET `/shop` · Any token
POST `/themes` · Scope: `write_themes`
GET `/themes` · Scope: `read_themes`
POST `/themes/upload` · Scope: `write_themes`
Send the .zip as the body with Content-Type: application/zip.
GET `/themes/{id}` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PATCH `/themes/{id}` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/themes/{id}/duplicate` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/themes/{id}/publish` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/themes/{id}` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/themes/{id}/download` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/themes/{id}/files` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/themes/{id}/file` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `path` | query | For example `templates/index.json`. |
PUT `/themes/{id}/file` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
{{ '\''eid.banner'\'' | t }}
" }' ```{{ 'eid.banner' | t }}
" }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```{{ 'eid.banner' | t }}
", }, ) res.raise_for_status() print(res.json()) ```{{ \'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); ```{{ '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)) } ```{{ '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()); ```GET `/themes/{id}/code/file` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `path` | query | For example `sections/header.liquid`. |
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. |
{{ '\''eid.banner'\'' | t }}
", "create": true }' ```{{ 'eid.banner' | t }}
", "create": true }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```{{ 'eid.banner' | t }}
", "create": True, }, ) res.raise_for_status() print(res.json()) ```{{ \'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); ```{{ '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)) } ```{{ '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 `/themes/{id}/code/file` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `path` | query | For example `snippets/eid-banner.liquid`. |
POST `/themes/{id}/code/rename` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/themes/{id}/code/versions` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `path` | query | For example `sections/header.liquid`. |
GET `/themes/{id}/code/versions/{vid}` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `vid` | path | The vid ID. |
POST `/themes/{id}/code/versions/{vid}/restore` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `vid` | path | The vid ID. |
GET `/themes/{id}/references` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `target` | query | For example `snippets/product-card.liquid`. |
POST `/themes/{id}/check` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/themes/{id}/check/file` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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`. |
GET `/themes/{id}/snapshots` · Scope: `read_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/themes/{id}/snapshots` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/themes/{id}/snapshots/{sid}/restore` · Scope: `write_themes`
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `sid` | path | The sid ID. |
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. |
GET `/locales` · Scope: `read_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`. |
GET `/translations/resources` · Scope: `read_translations`
| Parameter | In | Description |
| --- | --- | --- |
| `type` | query | For example `product`. |
| `locale` | query | For example `ar`. |
PUT `/translations` · Scope: `write_translations`
كتان ناعم مطرز يدوياً في الدوحة.
" } }' ```كتان ناعم مطرز يدوياً في الدوحة.
" } }), }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); const data = await res.json(); console.log(data); ```كتان ناعم مطرز يدوياً في الدوحة.
", }, }, ) res.raise_for_status() print(res.json()) ```كتان ناعم مطرز يدوياً في الدوحة.
', ], ], 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); ```كتان ناعم مطرز يدوياً في الدوحة.
" } }` 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)) } ```كتان ناعم مطرز يدوياً في الدوحة.
" } } """, 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()); ```كتان ناعم مطرز يدوياً في الدوحة.
" } ], "id": "0193a1b2-c3d4-7e5f-8a6b-000000000005", "locale": "ar", "type": "product" } ```POST `/webhooks` · Any token
GET `/webhooks` · Any token
GET `/webhooks/{id}` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
PUT `/webhooks/{id}` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/webhooks/{id}/test` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
GET `/webhooks/{id}/deliveries` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `limit` | query | For example `20`. |
POST `/webhooks/{id}/deliveries/{webhook_id}/resend` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
| `webhook_id` | path | The webhook ID. |
POST `/webhooks/{id}/disable` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
POST `/webhooks/{id}/enable` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
DELETE `/webhooks/{id}` · Any token
| Parameter | In | Description |
| --- | --- | --- |
| `id` | path | The resource's ID. |
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/