StabisoDocs

API reference

Shopify

Shopify: a company's online shop connected with an app of its own; every 5 minutes the shop's products come in as the company's products and its orders as sales orders, invoiced when sent and paid to the payment provider's balance; a drop shipper's suppliers get a purchase order for what they ship.

Operation Summary Scope Idempotency-Key
GET /v1/shopify Get Shopify admin
POST /v1/shopify/authorize Start connecting a Shopify shop on its consent page admin
POST /v1/shopify/connections Connect a Shopify shop admin
POST /v1/shopify/connections/consent Connect a Shopify shop with its consent page's answer admin
DELETE /v1/shopify/connections/{shopify_connection_id} Disconnect Shopify admin
GET /v1/shopify/connections/{shopify_connection_id}/orders List the shop's orders admin
GET /v1/shopify/connections/{shopify_connection_id}/payouts List the shop's payouts admin
GET /v1/shopify/connections/{shopify_connection_id}/products List the shop's products admin
GET /v1/shopify/connections/{shopify_connection_id}/suppliers List the shop's vendors admin
PUT /v1/shopify/connections/{shopify_connection_id}/suppliers Set who ships a shop vendor's goods admin
POST /v1/shopify/connections/{shopify_connection_id}/sync Read the shop now admin

GET /v1/shopify

Get Shopify

Whether a shop can be connected here, the permissions its app needs, and each company connected: the shop, its currency, how far its products were read and the last error.

Required scope admin (admin implies every scope)
Operation id get_shopify_v1_shopify_get

Example request

curl "$ERP_URL/v1/shopify" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK ShopifySetup
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "available": true,
  "scopes": [
    "string"
  ],
  "redirect_uri": "string",
  "connections": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "entity": "string",
      "shop_domain": "string",
      "shop_name": "string",
      "admin_url": "string",
      "currency": "string",
      "taxes_included": true,
      "method": "app",
      "status": "active",
      "products_read_to": "2026-09-21T09:30:00Z",
      "last_sync_at": "2026-09-21T09:30:00Z",
      "last_error": "string",
      "products": 1,
      "orders_read_to": "2026-09-21T09:30:00Z",
      "orders": 1,
      "orders_open": 1,
      "orders_with_problems": 1,
      "linked_by": {},
      "linked_at": "2026-09-21T09:30:00Z"
    }
  ]
}

POST /v1/shopify/authorize

Start connecting a Shopify shop on its consent page

The shop's consent page for the company's own app: open url; the shop sends the browser back to redirect_uri (which the app must allow) with a query string for POST /v1/shopify/connections/consent, within 15 minutes. For a shop the app's client credentials cannot reach. 409 in a test copy or when this system has no address to come back to.

Required scope admin (admin implies every scope)
Idempotency-Key not used
Operation id authorize_v1_shopify_authorize_post

Request body

application/json (required): ShopifyAuthorize

Field Type Required Description
entity string yes Code (or id) of the company.
shop_domain string yes The shop's own address. (pattern ^[a-z0-9][a-z0-9-]{0,59}\.myshopify\.com$)
client_id string yes The client id of the company's app. (min length 10; max length 200)
client_secret string yes That app's client secret: it travels sealed in state and checks the shop's answer; never shown again. (min length 10; max length 500)

Example request

curl -X POST "$ERP_URL/v1/shopify/authorize" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "client_id": "3f5e8a1b9c2d4e6f7a8b9c0d1e2f3a4b",
  "client_secret": "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",
  "entity": "CH01",
  "shop_domain": "alpine-goods.myshopify.com"
}'

Responses

Status Meaning Body
200 OK ShopifyAuthorizeOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "url": "string",
  "redirect_uri": "string"
}

POST /v1/shopify/connections

Connect a Shopify shop

Connect a company's shop with an app of the company's own: its client id and secret (an app made in Shopify's Dev Dashboard and installed on a shop of the app's own organization) or a custom app's access token; for any other shop use its consent page (POST /v1/shopify/authorize). The shop is asked for its name, currency and whether its prices include the tax (proving the app). From then on its products come in as products here every 5 minutes (the first round reads them all), and the orders placed from then on as sales orders. Connecting again replaces the secret. 409 in a test copy or when the company is connected to another shop; 422 when the shop refuses the app.

Required scope admin (admin implies every scope)
Idempotency-Key not used
Operation id connect_v1_shopify_connections_post

Request body

application/json (required): ShopifyConnectInput

Field Type Required Description
entity string yes Code (or id) of the company.
shop_domain string yes The shop's own address, <name>.myshopify.com (in the shop's admin under Settings, Domains). (pattern ^[a-z0-9][a-z0-9-]{0,59}\.myshopify\.com$)
client_id string or null The client id of the company's app, made in Shopify's Dev Dashboard and installed on the shop; with client_secret. (min length 10; max length 200)
client_secret string or null That app's client secret. Kept sealed, never shown again. (min length 10; max length 500)
access_token string or null Instead of an app's client id and secret: a custom app's Admin API access token (shpat_...). Kept sealed, never shown again. (min length 10; max length 500)

Example request

curl -X POST "$ERP_URL/v1/shopify/connections" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "client_id": "3f5e8a1b9c2d4e6f7a8b9c0d1e2f3a4b",
  "client_secret": "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",
  "entity": "CH01",
  "shop_domain": "alpine-goods.myshopify.com"
}'

Responses

Status Meaning Body
200 OK ShopifyConnection
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "entity": "string",
  "shop_domain": "string",
  "shop_name": "string",
  "admin_url": "string",
  "currency": "string",
  "taxes_included": true,
  "method": "app",
  "status": "active",
  "products_read_to": "2026-09-21T09:30:00Z",
  "last_sync_at": "2026-09-21T09:30:00Z",
  "last_error": "string",
  "products": 1,
  "orders_read_to": "2026-09-21T09:30:00Z",
  "orders": 1,
  "orders_open": 1,
  "orders_with_problems": 1,
  "linked_by": {},
  "linked_at": "2026-09-21T09:30:00Z"
}

POST /v1/shopify/connections/consent

Connect a Shopify shop with its consent page's answer

Finish connecting with the query string the shop's consent page sent the browser back with (only for whoever started it): Shopify's signature is checked with the app's secret and the code traded for the app's lasting token. 422 when the answer is not theirs, too old or not signed by Shopify, or the shop refuses the code; 409 as above.

Required scope admin (admin implies every scope)
Idempotency-Key not used
Operation id connect_consent_v1_shopify_connections_consent_post

Request body

application/json (required): ShopifyCallbackInput

Field Type Required Description
query string yes The query string the shop's consent page sent the browser back with, as it came (its signature covers every parameter). (min length 1; max length 4000)

Example request

curl -X POST "$ERP_URL/v1/shopify/connections/consent" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "code=0907a61c0c8d55e99db179b68161bc00&hmac=700e2d…&shop=alpine-goods.myshopify.com&state=eyJvcmciOiI….Xq3v…&timestamp=1793017200"
}'

Responses

Status Meaning Body
200 OK ShopifyConnection
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "entity": "string",
  "shop_domain": "string",
  "shop_name": "string",
  "admin_url": "string",
  "currency": "string",
  "taxes_included": true,
  "method": "app",
  "status": "active",
  "products_read_to": "2026-09-21T09:30:00Z",
  "last_sync_at": "2026-09-21T09:30:00Z",
  "last_error": "string",
  "products": 1,
  "orders_read_to": "2026-09-21T09:30:00Z",
  "orders": 1,
  "orders_open": 1,
  "orders_with_problems": 1,
  "linked_by": {},
  "linked_at": "2026-09-21T09:30:00Z"
}

DELETE /v1/shopify/connections/{shopify_connection_id}

Disconnect Shopify

Disconnect: nothing more is read and the secret is deleted (the app is the company's to uninstall in Shopify). The products stay, and so does which variant each is sold as, so connecting the same shop again makes no product twice.

Required scope admin (admin implies every scope)
Idempotency-Key not used
Operation id disconnect_v1_shopify_connections__shopify_connection_id__delete

Parameters

In Name Type Required Description
path shopify_connection_id string (uuid) yes Id of the connection (GET /v1/shopify).

Example request

curl -X DELETE "$ERP_URL/v1/shopify/connections/7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
204 No content
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

GET /v1/shopify/connections/{shopify_connection_id}/orders

List the shop's orders

The shop's orders taken into the books (those placed after the shop was connected), each with its sales order, the invoice of each fulfilment and whether it is paid, and what keeps it from being done, in plain words.

Required scope admin (admin implies every scope)
Operation id list_orders_v1_shopify_connections__shopify_connection_id__orders_get

Parameters

In Name Type Required Description
path shopify_connection_id string (uuid) yes Id of the connection (GET /v1/shopify).
query state "cancelled" | "done" | "open" or null Only the orders in this state: open, done or cancelled.
query problems boolean Only the orders a step of which was refused. (default false)
query limit integer At most this many, the newest first. (min 1; max 1000; default 100)

Example request

curl "$ERP_URL/v1/shopify/connections/7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a/orders" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of ShopifyOrderOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "order_id": 1,
    "name": "string",
    "placed_at": "2026-09-21T09:30:00Z",
    "customer": "string",
    "paid": true,
    "charged": "string",
    "sales_order_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "sales_order": "string",
    "state": "cancelled",
    "problem": "string",
    "invoices": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "number": null,
        "status": "string",
        "total": "string",
        "charged": "string",
        "paid": true
      }
    ],
    "purchase_orders": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "number": "string",
        "vendor": "string",
        "status": "string"
      }
    ],
    "credit_notes": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "number": null,
        "status": "string",
        "total": "string",
        "refunded": "string",
        "paid": true
      }
    ]
  }
]

GET /v1/shopify/connections/{shopify_connection_id}/payouts

List the shop's payouts

The payouts of Shopify Payments read from the shop (those of the last 30 days each round, from the day the shop was connected): what each paid out to the bank, the fees and the chargebacks Shopify kept of it, the entry that booked them against the payment provider's balance, whether its bank line was posted to that balance, and what keeps it from being booked, in plain words.

Required scope admin (admin implies every scope)
Operation id list_payouts_v1_shopify_connections__shopify_connection_id__payouts_get

Parameters

In Name Type Required Description
path shopify_connection_id string (uuid) yes Id of the connection (GET /v1/shopify).
query limit integer At most this many, the newest first. (min 1; max 1000; default 100)

Example request

curl "$ERP_URL/v1/shopify/connections/7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a/payouts" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of ShopifyPayoutOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "payout_id": 1,
    "issued_at": "2026-09-21T09:30:00Z",
    "status": "string",
    "currency": "string",
    "net": "string",
    "fees": "string",
    "adjustments": "string",
    "state": "booked",
    "journal_entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "journal_entry": "string",
    "in_bank": true,
    "problem": "string"
  }
]

GET /v1/shopify/connections/{shopify_connection_id}/products

List the shop's products

The shop's variants sold here, each with the product it is sold as, its SKU, name, price and status as last read.

Required scope admin (admin implies every scope)
Operation id list_variants_v1_shopify_connections__shopify_connection_id__products_get

Parameters

In Name Type Required Description
path shopify_connection_id string (uuid) yes Id of the connection (GET /v1/shopify).
query limit integer At most this many, by name. (min 1; max 1000; default 200)

Example request

curl "$ERP_URL/v1/shopify/connections/7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a/products" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of ShopifyVariantOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "variant_id": 1,
    "product_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "product": "string",
    "sku": "string",
    "name": "string",
    "price": "string",
    "status": "string",
    "vendor": "string",
    "cost": "string",
    "read_at": "2026-09-21T09:30:00Z"
  }
]

GET /v1/shopify/connections/{shopify_connection_id}/suppliers

List the shop's vendors

The vendors the shop's products name, by name, each with the company's vendor who ships its goods to the customers (drop shipping), or none when the company ships them itself.

Required scope admin (admin implies every scope)
Operation id list_suppliers_v1_shopify_connections__shopify_connection_id__suppliers_get

Parameters

In Name Type Required Description
path shopify_connection_id string (uuid) yes Id of the connection (GET /v1/shopify).

Example request

curl "$ERP_URL/v1/shopify/connections/7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a/suppliers" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of ShopifySupplierOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "shop_vendor": "string",
    "variants": 1,
    "without_cost": 1,
    "vendor": "string",
    "vendor_name": "string"
  }
]

PUT /v1/shopify/connections/{shopify_connection_id}/suppliers

Set who ships a shop vendor's goods

Name the company's vendor who ships the goods of one of the shop's vendors straight to the customers (drop shipping), or none (vendor null) when the company ships them itself. From the next round, an order's lines of those goods raise a purchase order of that vendor at their cost per item in the shop, sent to the customer's address; those already raised stay. 422 when the vendor is blocked or inactive.

Required scope admin (admin implies every scope)
Idempotency-Key not used
Operation id set_supplier_v1_shopify_connections__shopify_connection_id__suppliers_put

Parameters

In Name Type Required Description
path shopify_connection_id string (uuid) yes Id of the connection (GET /v1/shopify).

Request body

application/json (required): ShopifySupplierInput

Field Type Required Description
shop_vendor string yes The vendor the shop's products name. (min length 1; max length 255)
vendor string or null yes Code (or id) of the company's active vendor who ships them to the customers; null when the company ships them itself.

Example request

curl -X PUT "$ERP_URL/v1/shopify/connections/7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a/suppliers" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "shop_vendor": "Alpine Outfitters",
  "vendor": "V-00004"
}'

Responses

Status Meaning Body
200 OK ShopifySupplierOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "shop_vendor": "string",
  "variants": 1,
  "without_cost": 1,
  "vendor": "string",
  "vendor_name": "string"
}

POST /v1/shopify/connections/{shopify_connection_id}/sync

Read the shop now

A round now (they run every 5 minutes): read the products that changed, make products of the new variants and take over new names, prices and whether the shop still sells each; then read the orders that changed, make a sales order of each new one and the purchase orders of its drop-shipped goods, invoice what was sent and pay the invoices of paid orders to the payment provider's balance; then read the payouts and book the fees and chargebacks of those on their way to the bank. 409 when the shop stopped accepting the app (connect again) or in a test copy.

Required scope admin (admin implies every scope)
Idempotency-Key not used
Operation id sync_connection_v1_shopify_connections__shopify_connection_id__sync_post

Parameters

In Name Type Required Description
path shopify_connection_id string (uuid) yes Id of the connection (GET /v1/shopify).

Example request

curl -X POST "$ERP_URL/v1/shopify/connections/7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a/sync" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK ShopifySyncOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "read": 1,
  "new_products": 1,
  "updated_products": 1,
  "orders_read": 1,
  "new_orders": 1,
  "purchase_orders": 1,
  "invoiced": 1,
  "paid": 1,
  "problems": 1,
  "refunds": 1,
  "payouts": 1,
  "connection": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "entity": "string",
    "shop_domain": "string",
    "shop_name": "string",
    "admin_url": "string",
    "currency": "string",
    "taxes_included": true,
    "method": "app",
    "status": "active",
    "products_read_to": "2026-09-21T09:30:00Z",
    "last_sync_at": "2026-09-21T09:30:00Z",
    "last_error": "string",
    "products": 1,
    "orders_read_to": "2026-09-21T09:30:00Z",
    "orders": 1,
    "orders_open": 1,
    "orders_with_problems": 1,
    "linked_by": {},
    "linked_at": "2026-09-21T09:30:00Z"
  }
}

Schemas

ShopifyAuthorize

Field Type Required Description
entity string yes Code (or id) of the company.
shop_domain string yes The shop's own address. (pattern ^[a-z0-9][a-z0-9-]{0,59}\.myshopify\.com$)
client_id string yes The client id of the company's app. (min length 10; max length 200)
client_secret string yes That app's client secret: it travels sealed in state and checks the shop's answer; never shown again. (min length 10; max length 500)

ShopifyAuthorizeOut

Field Type Required Description
url string yes The shop's consent page: open it in the browser.
redirect_uri string yes Where it sends the browser back.

ShopifyCallbackInput

Field Type Required Description
query string yes The query string the shop's consent page sent the browser back with, as it came (its signature covers every parameter). (min length 1; max length 4000)

ShopifyConnectInput

Field Type Required Description
entity string yes Code (or id) of the company.
shop_domain string yes The shop's own address, <name>.myshopify.com (in the shop's admin under Settings, Domains). (pattern ^[a-z0-9][a-z0-9-]{0,59}\.myshopify\.com$)
client_id string or null The client id of the company's app, made in Shopify's Dev Dashboard and installed on the shop; with client_secret. (min length 10; max length 200)
client_secret string or null That app's client secret. Kept sealed, never shown again. (min length 10; max length 500)
access_token string or null Instead of an app's client id and secret: a custom app's Admin API access token (shpat_...). Kept sealed, never shown again. (min length 10; max length 500)

ShopifyConnection

Field Type Required Description
id string (uuid) yes Id of the connection.
entity string yes The company whose books the shop feeds.
shop_domain string yes The shop's own address, <name>.myshopify.com.
shop_name string yes The shop's name.
admin_url string yes The shop's admin in Shopify.
currency string yes The shop's currency.
taxes_included boolean yes Whether the shop's prices include the tax; Stabiso's list prices are net, so they are worked out from them.
method "app" | "consent" | "token" yes app: with an app's client id and secret; consent: the app let in on the shop's consent page; token: with a custom app's access token.
status "active" | "reconnect" yes reconnect: the shop stopped accepting the app; connect again.
products_read_to string (date-time) yes The products are read up to here (UTC).
last_sync_at string (date-time) or null yes When the shop was last read (UTC).
last_error string or null yes Why the last round failed, in plain words.
products integer yes Variants of the shop sold as products here.
orders_read_to string (date-time) yes The orders are read up to here (UTC); orders placed before the shop was connected are not taken.
orders integer yes The shop's orders taken into the books.
orders_open integer yes Of them, the ones not yet sent, invoiced and paid in full.
orders_with_problems integer yes Of them, the ones a step of which was refused (GET .../orders, problem).
linked_by object yes Who connected it.
linked_at string (date-time) yes When it was connected (UTC).

ShopifyOrderCreditNote

Field Type Required Description
id string (uuid) yes Id of the credit note (GET /v1/documents/{document_id}).
number string or null yes Its number; null before it is posted.
status string yes draft, pending_approval, posted, rejected or void.
total string yes Its total, with Stabiso's VAT.
refunded string yes What the shop refunded.
paid boolean yes Whether the payment out of the payment provider's balance paid it.

ShopifyOrderInvoice

Field Type Required Description
id string (uuid) yes Id of the invoice (GET /v1/documents/{document_id}).
number string or null yes Its number; null before it is posted.
status string yes draft, pending_approval, posted, rejected or void.
total string yes Its total, with Stabiso's VAT.
charged string yes What the shop charged for the same goods.
paid boolean yes Whether the receipt to the payment provider's balance paid it.

ShopifyOrderOut

Field Type Required Description
order_id integer yes Shopify's id of the order.
name string yes The order's name in the shop, e.g. #1001.
placed_at string (date-time) yes When it was placed (UTC).
customer string or null yes The buyer's name, or null for a guest; the customer is the sales order's.
paid boolean yes Whether the customer paid it in the shop.
charged string yes What the shop charged for it, in the shop's currency.
sales_order_id string (uuid) or null yes Id of its sales order (GET /v1/sales-documents/{document}); null until made.
sales_order string or null yes Number of its sales order.
state "cancelled" | "done" | "open" yes open: not yet sent, invoiced and paid in full; done; cancelled in the shop before anything was invoiced.
problem string or null yes Why the last step on it was refused, in plain words; it is done again in the next round.
invoices array of ShopifyOrderInvoice yes The invoice of each fulfilment, the oldest first.
purchase_orders array of ShopifyOrderPurchase yes The purchase orders of its drop-shipped goods, one per supplier.
credit_notes array of ShopifyOrderCreditNote yes The credit note of each refund of goods sent, the oldest first; paid once paid out of the payment provider's balance.

ShopifyOrderPurchase

Field Type Required Description
id string (uuid) yes Id of the purchase order (GET /v1/purchase-orders/{id}).
number string yes Its number.
vendor string yes Code of the supplier who ships the goods.
status string yes Its status, e.g. pending_approval, open, closed.

ShopifyPayoutOut

Field Type Required Description
payout_id integer yes Shopify's id of the payout.
issued_at string (date-time) yes When Shopify issued it (UTC).
status string yes Its status in Shopify: SCHEDULED, IN_TRANSIT, PAID, FAILED or CANCELED.
currency string yes The currency it is paid out in.
net string yes What reaches the bank.
fees string yes The fees Shopify kept of it.
adjustments string yes What chargebacks and other adjustments took from the balance (negative) or gave back.
state "booked" | "open" yes booked once it is on its way to the bank and what it kept is booked against the payment provider's balance; else open.
journal_entry_id string (uuid) or null yes Id of the entry that booked its fees and adjustments (GET /v1/journal-entries/{entry_id}); null when it kept nothing or is open.
journal_entry string or null yes Number of that entry once posted.
in_bank boolean yes Whether a bank statement line was posted as this payout to the balance.
problem string or null yes Why it was not booked, in plain words; it is tried again in the next round.

ShopifySetup

Field Type Required Description
available boolean yes Whether a shop can be connected on this system (false: secrets could not be kept sealed).
scopes array of string yes What the shop's app must be allowed (its Admin API access scopes).
redirect_uri string or null yes Where the shop's consent page sends the browser back: add it to the app's allowed redirection URLs to connect on the consent page.
connections array of ShopifyConnection yes The companies connected.

ShopifySupplierInput

Field Type Required Description
shop_vendor string yes The vendor the shop's products name. (min length 1; max length 255)
vendor string or null yes Code (or id) of the company's active vendor who ships them to the customers; null when the company ships them itself.

ShopifySupplierOut

Field Type Required Description
shop_vendor string yes A vendor the shop's products name.
variants integer yes The variants of its products Stabiso sells.
without_cost integer yes Those of them without a cost per item in the shop: a drop-shipped one raises no purchase order until it has one.
vendor string or null yes Code of the company's vendor who ships its products (drop shipping); null when the company ships them itself.
vendor_name string or null yes That vendor's name.

ShopifySyncOut

Field Type Required Description
read integer yes Variants read from the shop.
new_products integer yes Products made of them, or found by their SKU.
updated_products integer yes Products whose name, price or status changed.
orders_read integer yes Orders read from the shop.
new_orders integer yes Orders taken into the books.
purchase_orders integer yes Purchase orders raised with drop shippers.
invoiced integer yes Fulfilments invoiced.
paid integer yes Invoices paid to the payment provider's balance.
problems integer yes Orders a step of which was refused.
refunds integer yes Refunds settled: credit notes of the goods refunded, paid out of the payment provider's balance.
payouts integer yes Payouts of Shopify Payments booked: their fees and chargebacks against the payment provider's balance.
connection ShopifyConnection yes The connection after the round.

ShopifyVariantOut

Field Type Required Description
variant_id integer yes Shopify's id of the variant.
product_id string (uuid) yes Id of the product it is sold as here.
product string yes Code of that product.
sku string or null yes The variant's SKU in Shopify.
name string yes The product's title, and the variant's when it has options.
price string yes Its price in the shop's currency, as the shop shows it.
status string yes The Shopify product's status: ACTIVE, DRAFT, ARCHIVED.
vendor string or null yes The product's vendor in the shop.
cost string or null yes The variant's cost per item in the shop's currency; null when it has none.
read_at string (date-time) yes When it was last read (UTC).
Stabiso, the Enterprise System of Record · generated from the code and its guides · release 6f03a5e846b3