Skip to content

API integration

The API integration allows vendors without a supported e-commerce platform to connect with a Garnet marketplace via a REST API. Vendors can push products, update prices and stock, submit tracking information, and receive orders via webhook.

Integration scope

  • ✅ Product synchronization (push from vendor)
  • ✅ Price and stock updates
  • ✅ Order synchronization (webhook to vendor)
  • ✅ Tracking synchronization (push from vendor)

Authentication

All API requests must include a Bearer token in the Authorization header. The API key is provided when the marketplace admin creates the integration in Garnet > Settings > Integrations > API.

Authorization: Bearer your_api_key

Base URL: https://api.garnetmarketplace.com

Quick start

Here is a full example: create a pineapple product, then update its stock.

Step 1 — Create the product:

Full curl command
bash
curl -X POST https://api.garnetmarketplace.com/products \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "pineapple-001",
    "title": "Fresh Pineapple",
    "descriptionHtml": "<p>Sweet and juicy tropical pineapple, hand-picked at peak ripeness.</p>",
    "productType": "Fruits",
    "tags": ["tropical", "fresh", "fruit"],
    "variants": [
      {
        "sku": "PINE-SINGLE",
        "price": 4.99,
        "inventoryQuantity": 120,
        "weight": { "value": 900, "unit": "GRAMS" }
      }
    ],
    "images": [
      { "src": "https://images.unsplash.com/photo-1550258987-190a2d41a8ba?w=800", "alt": "Fresh pineapple" }
    ]
  }'

Response:

json
{ "productId": "gid://shopify/Product/123456789" }

Step 2 — Update stock and price:

Full curl command
bash
curl -X PATCH https://api.garnetmarketplace.com/products \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '[
    { "sku": "PINE-SINGLE", "price": 3.99, "stock": 85 }
  ]'

Response:

json
{ "updated": 1, "unknownSkus": [] }

Endpoints

POST /products

Create or update a product in the marketplace. If a product with the same externalId already exists, it will be updated. On first creation, the product is created as DRAFT. The marketplace admin can then approve and publish it.

Request body:

FieldTypeRequiredDescription
externalIdstringyesUnique product identifier in the vendor's system
titlestringyesProduct title
descriptionHtmlstringnoProduct description in HTML
vendorstringnoBrand name (defaults to the vendor name)
productTypestringnoProduct type (e.g. "Bags")
tagsstring[]noProduct tags
productOptionsobject[]noProduct options (see below)
variantsobject[]yesAt least one variant (see below)
imagesobject[]noProduct images (see below)
metafieldsobject[]noCustom metafields (see below)

Product option:

FieldTypeRequiredDescription
namestringyesOption name (e.g. "Size")
valuesstring[]yesOption values (e.g. ["S", "M", "L"])

Variant:

FieldTypeRequiredDescription
skustringyesSKU identifier
barcodestringnoBarcode (EAN, UPC, etc.)
pricenumberyesSale price
compareAtPricenumbernoOriginal price before discount
inventoryQuantityintegernoAvailable stock quantity
trackedbooleannoWhether inventory is tracked (default: true)
requiresShippingbooleannoWhether shipping is required (default: true)
weightobjectno{ value: number, unit: "GRAMS" | "KILOGRAMS" | "OUNCES" | "POUNDS" }
optionValuesobject[]no[{ optionName: "Size", name: "M" }] — must match productOptions
externalVariantIdstringnoUnique variant identifier in the vendor's system

Image:

FieldTypeRequiredDescription
srcstringyesPublic URL of the image
altstringnoAlt text for accessibility
externalIdstringnoUnique image ID to avoid re-uploading on updates

Metafield:

FieldTypeRequiredDescription
keystringyesMetafield key (e.g. "material")
valuestringyesMetafield value (e.g. "leather")

Example request:

bash
curl -X POST https://api.garnetmarketplace.com/products \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "vendor-product-123",
    "title": "Premium Leather Bag",
    "descriptionHtml": "<p>A beautiful leather bag</p>",
    "productType": "Bags",
    "tags": ["leather", "premium"],
    "productOptions": [
      { "name": "Size", "values": ["S", "M", "L"] }
    ],
    "variants": [
      {
        "sku": "BAG-001-S",
        "price": 129.99,
        "inventoryQuantity": 50,
        "optionValues": [{ "optionName": "Size", "name": "S" }]
      },
      {
        "sku": "BAG-001-M",
        "price": 129.99,
        "inventoryQuantity": 30,
        "optionValues": [{ "optionName": "Size", "name": "M" }]
      }
    ],
    "images": [
      { "src": "https://example.com/bag-front.jpg", "alt": "Front view" }
    ],
    "metafields": [
      { "key": "material", "value": "leather" },
      { "key": "country_of_origin", "value": "Italy" }
    ]
  }'

Response:

json
{ "productId": "gid://shopify/Product/123456789" }

PATCH /products

Bulk update price and stock for existing products by SKU. Maximum 250 items per request. Only updates variants that match existing SKUs in the marketplace.

Request body: Array of objects:

FieldTypeRequiredDescription
skustringyesSKU identifier
pricenumberyesNew price
stockintegeryesNew stock quantity

Example request:

bash
curl -X PATCH https://api.garnetmarketplace.com/products \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '[
    { "sku": "BAG-001-S", "price": 119.99, "stock": 45 },
    { "sku": "BAG-001-M", "price": 119.99, "stock": 28 }
  ]'

Response:

json
{ "updated": 1, "unknownSkus": [] }

POST /tracking

Submit a tracking number for an order. This will fulfill the order on the marketplace and notify the customer.

Request body:

FieldTypeRequiredDescription
orderIdintegeryesNumeric Shopify order ID (received in the order webhook)
trackingNumberstringyesTracking number
trackingCompanystringnoCarrier name (e.g. "UPS")
trackingUrlstringnoTracking URL

Example request:

bash
curl -X POST https://api.garnetmarketplace.com/tracking \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": 5538456789012,
    "trackingNumber": "1Z999AA10123456784",
    "trackingCompany": "UPS",
    "trackingUrl": "https://www.ups.com/track?tracknum=1Z999AA10123456784"
  }'

Response:

json
{ "fulfilled": true }

Receiving orders (webhook)

When a customer places an order on the marketplace, Garnet sends a POST request to the vendor's registered webhook URL. The payload follows the exact same format as the Shopify Order resource.

WARNING

The order webhook URL must be configured separately by the Garnet team. Contact us to set it up.

Order sample
json
{
    "id": 6902490759457,
    "admin_graphql_api_id": "gid://shopify/Order/6902490759457",
    "app_id": 1354745,
    "browser_ip": "24.132.136.18",
    "buyer_accepts_marketing": false,
    "cancel_reason": null,
    "cancelled_at": null,
    "cart_token": null,
    "checkout_id": 40647032832289,
    "checkout_token": "e11a0a03bf6395931c8df943a2efe8cc",
    "client_details": {
      "accept_language": null,
      "browser_height": null,
      "browser_ip": "24.132.136.18",
      "browser_width": null,
      "session_hash": null,
      "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:146.0) Gecko/20100101 Firefox/146.0"
    },
    "closed_at": null,
    "company": null,
    "confirmation_number": "C0VW5VQUF",
    "confirmed": true,
    "contact_email": null,
    "created_at": "2025-12-17T02:42:56-05:00",
    "currency": "USD",
    "current_subtotal_price": "107.80",
    "current_subtotal_price_set": {
      "shop_money": {
        "amount": "107.80",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "107.80",
        "currency_code": "USD"
      }
    },
    "current_total_additional_fees_set": null,
    "current_total_discounts": "2.20",
    "current_total_discounts_set": {
      "shop_money": {
        "amount": "2.20",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "2.20",
        "currency_code": "USD"
      }
    },
    "current_total_duties_set": null,
    "current_total_price": "121.43",
    "current_total_price_set": {
      "shop_money": {
        "amount": "121.43",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "121.43",
        "currency_code": "USD"
      }
    },
    "current_total_tax": "8.63",
    "current_total_tax_set": {
      "shop_money": {
        "amount": "8.63",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "8.63",
        "currency_code": "USD"
      }
    },
    "customer_locale": "en",
    "device_id": null,
    "discount_codes": [
      {
        "code": "78ZSKTG699J3",
        "amount": "4.40",
        "type": "percentage"
      }
    ],
    "duties_included": false,
    "email": "",
    "estimated_taxes": false,
    "financial_status": "partially_refunded",
    "fulfillment_status": null,
    "landing_site": null,
    "landing_site_ref": null,
    "location_id": 83306807585,
    "merchant_business_entity_id": "MTc2MTk4MDUyMTI5",
    "merchant_of_record_app_id": null,
    "name": "#1239",
    "note": null,
    "note_attributes": [],
    "number": 239,
    "order_number": 1239,
    "order_status_url": "https://ananature.com/76198052129/orders/c747e5e61ded045655e363f0e67314d0/authenticate?key=74674d94ab8a0517b3fbb1e5388260e6",
    "original_total_additional_fees_set": null,
    "original_total_duties_set": null,
    "payment_gateway_names": [
      "manual"
    ],
    "phone": null,
    "po_number": null,
    "presentment_currency": "USD",
    "processed_at": "2025-12-17T02:42:55-05:00",
    "reference": null,
    "referring_site": null,
    "source_identifier": null,
    "source_name": "shopify_draft_order",
    "source_url": null,
    "subtotal_price": "215.60",
    "subtotal_price_set": {
      "shop_money": {
        "amount": "215.60",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "215.60",
        "currency_code": "USD"
      }
    },
    "tags": "",
    "tax_exempt": false,
    "tax_lines": [
      {
        "price": "17.25",
        "rate": 0.08,
        "title": "Tax",
        "price_set": {
          "shop_money": {
            "amount": "17.25",
            "currency_code": "USD"
          },
          "presentment_money": {
            "amount": "17.25",
            "currency_code": "USD"
          }
        },
        "channel_liable": false
      }
    ],
    "taxes_included": false,
    "test": false,
    "token": "c747e5e61ded045655e363f0e67314d0",
    "total_cash_rounding_payment_adjustment_set": {
      "shop_money": {
        "amount": "0.00",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "0.00",
        "currency_code": "USD"
      }
    },
    "total_cash_rounding_refund_adjustment_set": {
      "shop_money": {
        "amount": "0.00",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "0.00",
        "currency_code": "USD"
      }
    },
    "total_discounts": "4.40",
    "total_discounts_set": {
      "shop_money": {
        "amount": "4.40",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "4.40",
        "currency_code": "USD"
      }
    },
    "total_line_items_price": "220.00",
    "total_line_items_price_set": {
      "shop_money": {
        "amount": "220.00",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "220.00",
        "currency_code": "USD"
      }
    },
    "total_outstanding": "0.00",
    "total_price": "242.85",
    "total_price_set": {
      "shop_money": {
        "amount": "242.85",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "242.85",
        "currency_code": "USD"
      }
    },
    "total_shipping_price_set": {
      "shop_money": {
        "amount": "10.00",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "10.00",
        "currency_code": "USD"
      }
    },
    "total_tax": "17.25",
    "total_tax_set": {
      "shop_money": {
        "amount": "17.25",
        "currency_code": "USD"
      },
      "presentment_money": {
        "amount": "17.25",
        "currency_code": "USD"
      }
    },
    "total_tip_received": "0.00",
    "total_weight": 0,
    "updated_at": "2026-01-15T11:29:09-05:00",
    "user_id": 122335035681,
    "billing_address": null,
    "customer": null,
    "discount_applications": [
      {
        "target_type": "line_item",
        "type": "discount_code",
        "value": "2.0",
        "value_type": "percentage",
        "allocation_method": "across",
        "target_selection": "all",
        "code": "78ZSKTG699J3"
      }
    ],
    "fulfillments": [],
    "line_items": [
      {
        "id": 16636086157601,
        "admin_graphql_api_id": "gid://shopify/LineItem/16636086157601",
        "attributed_staffs": [],
        "current_quantity": 1,
        "fulfillable_quantity": 1,
        "fulfillment_service": "manual",
        "fulfillment_status": null,
        "gift_card": false,
        "grams": 0,
        "name": "My Groovy 2",
        "price": "110.00",
        "price_set": {
          "shop_money": {
            "amount": "110.00",
            "currency_code": "USD"
          },
          "presentment_money": {
            "amount": "110.00",
            "currency_code": "USD"
          }
        },
        "product_exists": false,
        "product_id": null,
        "properties": [],
        "quantity": 2,
        "requires_shipping": true,
        "sku": null,
        "taxable": true,
        "title": "My Groovy 2",
        "total_discount": "0.00",
        "total_discount_set": {
          "shop_money": {
            "amount": "0.00",
            "currency_code": "USD"
          },
          "presentment_money": {
            "amount": "0.00",
            "currency_code": "USD"
          }
        },
        "variant_id": null,
        "variant_inventory_management": null,
        "variant_title": null,
        "vendor": "Pineapple Groovy",
        "tax_lines": [
          {
            "channel_liable": false,
            "price": "17.25",
            "price_set": {
              "shop_money": {
                "amount": "17.25",
                "currency_code": "USD"
              },
              "presentment_money": {
                "amount": "17.25",
                "currency_code": "USD"
              }
            },
            "rate": 0.08,
            "title": "Tax"
          }
        ],
        "duties": [],
        "discount_allocations": [
          {
            "amount": "4.40",
            "amount_set": {
              "shop_money": {
                "amount": "4.40",
                "currency_code": "USD"
              },
              "presentment_money": {
                "amount": "4.40",
                "currency_code": "USD"
              }
            },
            "discount_application_index": 0
          }
        ]
      }
    ],
    "payment_terms": null,
    "refunds": [
      {
        "id": 1225821389089,
        "admin_graphql_api_id": "gid://shopify/Refund/1225821389089",
        "created_at": "2025-12-17T06:02:16-05:00",
        "note": "",
        "order_id": 6902490759457,
        "processed_at": "2025-12-17T06:02:16-05:00",
        "restock": true,
        "total_duties_set": {
          "shop_money": {
            "amount": "0.00",
            "currency_code": "USD"
          },
          "presentment_money": {
            "amount": "0.00",
            "currency_code": "USD"
          }
        },
        "user_id": 122335035681,
        "order_adjustments": [
          {
            "id": 349704061217,
            "amount": "-5.00",
            "amount_set": {
              "shop_money": {
                "amount": "-5.00",
                "currency_code": "USD"
              },
              "presentment_money": {
                "amount": "-5.00",
                "currency_code": "USD"
              }
            },
            "kind": "shipping_refund",
            "order_id": 6902490759457,
            "reason": "Shipping refund",
            "refund_id": 1225821389089,
            "tax_amount": "0.00",
            "tax_amount_set": {
              "shop_money": {
                "amount": "0.00",
                "currency_code": "USD"
              },
              "presentment_money": {
                "amount": "0.00",
                "currency_code": "USD"
              }
            }
          },
          {
            "id": 349704093985,
            "amount": "41.42",
            "amount_set": {
              "shop_money": {
                "amount": "41.42",
                "currency_code": "USD"
              },
              "presentment_money": {
                "amount": "41.42",
                "currency_code": "USD"
              }
            },
            "kind": "refund_discrepancy",
            "order_id": 6902490759457,
            "reason": "Refund discrepancy",
            "refund_id": 1225821389089,
            "tax_amount": "0.00",
            "tax_amount_set": {
              "shop_money": {
                "amount": "0.00",
                "currency_code": "USD"
              },
              "presentment_money": {
                "amount": "0.00",
                "currency_code": "USD"
              }
            }
          }
        ],
        "transactions": [
          {
            "id": 8492102615329,
            "admin_graphql_api_id": "gid://shopify/OrderTransaction/8492102615329",
            "amount": "80.00",
            "authorization": null,
            "created_at": "2025-12-17T06:02:16-05:00",
            "currency": "USD",
            "device_id": null,
            "error_code": null,
            "gateway": "manual",
            "kind": "refund",
            "location_id": null,
            "message": "Refunded 80.00 USD from manual gateway",
            "order_id": 6902490759457,
            "parent_id": 8491800002849,
            "payment_id": "#1239.1",
            "processed_at": "2025-12-17T06:02:16-05:00",
            "receipt": {},
            "source_name": "1830279",
            "status": "success",
            "test": false,
            "user_id": 122335035681
          }
        ],
        "refund_line_items": [
          {
            "id": 638025335073,
            "line_item_id": 16636086157601,
            "location_id": 83306807585,
            "quantity": 1,
            "restock_type": "cancel",
            "subtotal": 107.8,
            "subtotal_set": {
              "shop_money": {
                "amount": "107.80",
                "currency_code": "USD"
              },
              "presentment_money": {
                "amount": "107.80",
                "currency_code": "USD"
              }
            },
            "total_tax": 8.62,
            "total_tax_set": {
              "shop_money": {
                "amount": "8.62",
                "currency_code": "USD"
              },
              "presentment_money": {
                "amount": "8.62",
                "currency_code": "USD"
              }
            },
            "line_item": {
              "id": 16636086157601,
              "admin_graphql_api_id": "gid://shopify/LineItem/16636086157601",
              "attributed_staffs": [],
              "current_quantity": 1,
              "fulfillable_quantity": 1,
              "fulfillment_service": "manual",
              "fulfillment_status": null,
              "gift_card": false,
              "grams": 0,
              "name": "My Groovy 2",
              "price": "110.00",
              "price_set": {
                "shop_money": {
                  "amount": "110.00",
                  "currency_code": "USD"
                },
                "presentment_money": {
                  "amount": "110.00",
                  "currency_code": "USD"
                }
              },
              "product_exists": false,
              "product_id": null,
              "properties": [],
              "quantity": 2,
              "requires_shipping": true,
              "sku": null,
              "taxable": true,
              "title": "My Groovy 2",
              "total_discount": "0.00",
              "total_discount_set": {
                "shop_money": {
                  "amount": "0.00",
                  "currency_code": "USD"
                },
                "presentment_money": {
                  "amount": "0.00",
                  "currency_code": "USD"
                }
              },
              "variant_id": null,
              "variant_inventory_management": null,
              "variant_title": null,
              "vendor": "Pineapple Groovy",
              "tax_lines": [
                {
                  "channel_liable": false,
                  "price": "17.25",
                  "price_set": {
                    "shop_money": {
                      "amount": "17.25",
                      "currency_code": "USD"
                    },
                    "presentment_money": {
                      "amount": "17.25",
                      "currency_code": "USD"
                    }
                  },
                  "rate": 0.08,
                  "title": "Tax"
                }
              ],
              "duties": [],
              "discount_allocations": [
                {
                  "amount": "4.40",
                  "amount_set": {
                    "shop_money": {
                      "amount": "4.40",
                      "currency_code": "USD"
                    },
                    "presentment_money": {
                      "amount": "4.40",
                      "currency_code": "USD"
                    }
                  },
                  "discount_application_index": 0
                }
              ]
            }
          }
        ],
        "duties": []
      }
    ],
    "shipping_address": null,
    "shipping_lines": [
      {
        "id": 5304825053473,
        "carrier_identifier": null,
        "code": "custom",
        "discounted_price": "10.00",
        "discounted_price_set": {
          "shop_money": {
            "amount": "10.00",
            "currency_code": "USD"
          },
          "presentment_money": {
            "amount": "10.00",
            "currency_code": "USD"
          }
        },
        "is_removed": false,
        "phone": null,
        "price": "10.00",
        "price_set": {
          "shop_money": {
            "amount": "10.00",
            "currency_code": "USD"
          },
          "presentment_money": {
            "amount": "10.00",
            "currency_code": "USD"
          }
        },
        "requested_fulfillment_service_id": null,
        "source": "shopify",
        "title": "Standard shipping",
        "tax_lines": [],
        "discount_allocations": []
      }
    ]
  }

Error responses

All endpoints return JSON errors in the following format:

json
{ "error": "Error message describing what went wrong" }
StatusDescription
400Invalid request (validation error)
401Invalid or missing API key
404Resource not found
500Server error