> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pcnaid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Unified Commercial Suite API overview

> Administrative, app-proxy, merchant, and webhook interfaces for Unified Commercial Suite.

# Unified Commercial Suite API overview

## Surfaces and authentication

| Category | Base path | Auth method |
| - | - | - |
| Admin APIs | `/api/*` | Verified Shopify session; company and price-list mutations additionally require the account owner |
| App proxy | `/apps/b2b-toolkit/*` on the store domain | Shopify app-proxy HMAC signature |
| Merchant API | `/api/merchant/*` | `Authorization: Bearer ucs_<key>` |
| Webhooks | `/webhooks` | Shopify HMAC-SHA256 |

Admin APIs return a consistent envelope:

```json theme={null}
{ "success": true, "message": "Operation completed", "data": {} }
```

Errors return:

```json theme={null}
{ "success": false, "error": "Error description" }
```

## Error codes

| Status | Meaning |
| - | - |
| `200` | Success |
| `202` | Corporate order accepted for approval rather than draft creation |
| `400` | Bad request (missing fields, invalid action) |
| `401` | Unauthorized (invalid signature or session) |
| `402` | Active plan does not include the requested capability |
| `403` | Authenticated principal or buyer is not authorized |
| `404` | Resource not found |
| `405` | Unsupported webhook method (`/webhooks` accepts only `POST`) |
| `409` | Duplicate/in-progress webhook, already-consumed approval/impersonation state, or checkout `CUSTOMER_TAX_EXEMPT_CONFLICT` |
| `422` | Company order-limit violation |
| `500` | Internal server error |

## Companies API

**Base:** `/api/companies`. Reads use a verified Shopify admin session; mutations require account-owner authorization.

* `GET /api/companies` — list companies.
* `POST /api/companies` (`application/x-www-form-urlencoded`) with `action` of `create`, `update`, or `delete`.

Create and update fields include `name`, `paymentTerms` (`net15`, `net30`, `net45`, `net60`, `net90`), `discountPercentage`, `externalId`, `b2bTier`, `taxExempt`, `assignedRep`, `minimumOrderQuantity`, and `maximumOrderValue`. A Shopify Company GID as `externalId` requires Shopify Plus and the Premium `company_accounts` entitlement.

These endpoints are called by the embedded admin and require a Shopify admin session; they cannot be called with `curl` directly. The storefront wholesale application form is served through the app proxy at `/apps/b2b-toolkit/register` on the store domain.

## Price lists API

**Base:** `/api/pricelists`. Mutations enforce plan limits and can return `402`.

* `GET /api/pricelists` — list price lists.
* `GET /api/pricelists?id=1` — get one price list with its rules.
* `POST /api/pricelists` with `action` of `create`, `update`, `delete`, `add_rule`, `delete_rule`, `assign_to_company`, or `unassign_from_company`.

Rule fields include `ruleType` (`percentage_discount`, `fixed_price`, or `collection_discount`), `variantId`, `productId`, `collectionId`, `discountPercentage`, `fixedPrice`, `currency`, and `minQuantity`.

## Checkout API

**Base:** `/api/checkout`. `POST` only. Authenticates a Shopify staff session plus plan, tenant, buyer, pricing, and order-limit checks.

Like the other Admin APIs, checkout is called by the embedded admin and requires a verified Shopify admin session; it cannot be called with `curl` directly.

The endpoint ignores client-derived catalog details and fetches the current variant price, product, collections, and shop currency from Shopify Admin GraphQL before calculating B2B price and order limits. Corporate buyers can receive `202` with `approvalRequired: true`. For a taxable company whose customer remains independently exempt, it returns `409` with `code: "CUSTOMER_TAX_EXEMPT_CONFLICT"`; a stale relationship to a deleted customer returns `404` with `code: "SHOPIFY_CUSTOMER_NOT_FOUND"`.

## App proxy - pricing

**Public path:** `/apps/b2b-toolkit/pricing` on the store domain. HMAC-validated; publicly reachable from the storefront. Shopify proxies this to the app's internal `/proxy/pricing` route.

* `GET /apps/b2b-toolkit/pricing?variants=...` returns `isB2B` and the customer's rules.
* `POST /apps/b2b-toolkit/pricing` with an `items` array returns calculated `prices`.

```json theme={null}
{
  "success": true,
  "isB2B": true,
  "prices": [
    { "variantId": "gid://shopify/ProductVariant/456", "originalPrice": 29.99, "finalPrice": 25.49, "discountPercentage": 15, "savings": 4.50 }
  ]
}
```

## App proxy - quotes

**Public path:** `/apps/b2b-toolkit/quotes` on the store domain. HMAC-validated. The theme RFQ block requires product context. Shopify proxies this to the app's internal `/proxy/quotes` route.

* `POST /apps/b2b-toolkit/quotes` submits a quote request and returns `201` with a `quoteNumber`.
* `GET /apps/b2b-toolkit/quotes` lists the customer's quotes.

## Import / export API

**Base:** `/api/import-export`. Reads use a verified Shopify admin session; mutations require account-owner authorization.

* `GET /api/import-export?entity=companies&format=csv` returns raw CSV with `Content-Disposition: attachment`.
* `POST /api/import-export` with `intent` of `import_companies` or `import_contacts` and a `csv` field. Contact rows require `company_external_id` and `shopify_customer_id`; `role` defaults to `member` and accepts `admin`, `member`, or `viewer`.

## Merchant API

**Base:** `/api/merchant/*`. Premium plan. Keys are managed in the embedded admin at `/app/merchant-api`. Supported scopes are `read:companies`, `read:price_lists`, `read:quotes`, and `write:quotes`.

* `GET /api/merchant/companies`
* `GET /api/merchant/price-lists`
* `GET /api/merchant/quotes`
* `GET /api/merchant/quotes/:id`
* `POST /api/merchant/quotes/:id` with `{ "action": "accept" }`

```bash theme={null}
curl --fail-with-body "https://example.com/api/merchant/companies" \
  -H "Authorization: Bearer ${UCS_API_KEY:?Set UCS_API_KEY}"
```

## Webhooks

**Base:** `/webhooks`. `POST` only. The endpoint verifies Shopify's HMAC-SHA256 signature.

| Topic | Action |
| - | - |
| `APP_UNINSTALLED` | Delete operational shop data and sessions while retaining paid-trial and replay history until `SHOP_REDACT` |
| `APP_SUBSCRIPTIONS_UPDATE` | Persist signed terminal state before Admin work; reconcile ACTIVE state for billing cadence |
| `CUSTOMERS_DATA_REQUEST` | GDPR: deliver the export or persist and queue a request-keyed retry job |
| `CUSTOMERS_REDACT` | GDPR: delete the delivered export metafield and all customer data from D1 |
| `SHOP_REDACT` | GDPR: delete all shop data from D1, only once a live-session check confirms the shop is not installed |
| `CUSTOMERS_CREATE` | Implemented but unregistered pending Protected Customer Data approval |
| `CUSTOMERS_UPDATE` | Implemented but unregistered pending Protected Customer Data approval |

Outbound webhooks (Premium) are delivered with HMAC-SHA256; verify the `x-ucs-signature` header with your signing secret. Endpoints are managed at `/app/merchant-api`.

## Rate limits

The application does not implement a custom request-rate limiter. Cloudflare Worker and D1 quotas are account-plan and platform limits. Shopify Admin GraphQL calls remain subject to Shopify's query-cost throttling.

[Pcnaid Documentation](https://docs.pcnaid.com/namespace/index.md) › [Shopify Ecosystem](https://docs.pcnaid.com/hubs/shopify-ecosystem/index.md) › [Unified Commercial Suite](https://docs.pcnaid.com/nodes/shopify/unified-commercial-suite/index.md) › [Developer](https://docs.pcnaid.com/nodes/shopify/unified-commercial-suite/developer/index)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.