Skip to content

Public API (Beta)

The Public API lets your own systems (an ERP, a CRM, a custom storefront) create quotes and read them back, without opening the app admin. It is in Beta and is available on the Enterprise plan only. Shopify Plus is not required: any Shopify plan can use it with the Enterprise plan of the app.

  1. In your app admin, go to Settings → API keys (in the Quote settings card).
  2. Click Create API key and fill in:
    • Name: for example, ERP integration.
    • Permissions: Read quotes (quotes:read) and/or Create quotes (quotes:write). Select at least one.
    • Expires: Never, in 30 days, in 90 days or in 1 year.
  3. Copy the key right away. For your security it is shown only once and cannot be viewed again.

You can have up to 5 active keys. To stop a system from calling the API, click Revoke next to its key. The key stops working immediately and this cannot be undone.

If your shop is on a plan below Enterprise, the API keys page shows an upgrade message instead of the key list.

Send requests to https://public-api.bss-b2b.solutions/quote/v1 and put your key in the X-BSS-API-KEY header on every request. The older x-api-key header still works.

Method and path Permission What it does
GET /quote/v1/shop none Checks that the key works and returns your shop (domain, shop_name, plan_code)
POST /quote/v1/quotes quotes:write Creates a quote
GET /quote/v1/quotes/:id quotes:read Reads a quote of your shop

Check the key:

Terminal window
curl -s https://public-api.bss-b2b.solutions/quote/v1/shop -H "X-BSS-API-KEY: $QUOTE_API_KEY"

Create a quote for an existing customer:

Terminal window
curl -s -X POST https://public-api.bss-b2b.solutions/quote/v1/quotes \
-H "X-BSS-API-KEY: $QUOTE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-attempt-1" \
-d '{
"customer_id": "gid://shopify/Customer/1234567890",
"note": "Need net-30 terms",
"variants": [
{ "product_id": "gid://shopify/Product/111", "variant_id": "gid://shopify/ProductVariant/222", "quantity": 10 }
]
}'

To create a quote for a guest, send email (and optionally first_name and last_name) instead of customer_id. Send exactly one of the two. Unknown fields in the body are rejected. Send each variant_id only once per request: a repeated variant_id is rejected with VALIDATION_ERROR.

Read a quote:

Terminal window
curl -s https://public-api.bss-b2b.solutions/quote/v1/quotes/42 -H "X-BSS-API-KEY: $QUOTE_API_KEY"

A successful response looks like { "status": "success", "data": { ... }, "meta": { "timestamp": "...", "version": "...", "requestId": "..." } }. All field names are snake_case. The data holds id, status, origin, customer_id, email, first_name, last_name, currency_code, note, proposal_sent, variants (with product_id, variant_id, quantity, quoted_price), created_at and expired_at. Quotes created through the API have origin set to public_api.

status is a number: 0 unread, 1 in review, 2 converted to an order, 3 rejected, 4 accepted. quoted_price is 0 until the merchant sends a proposal, then it is the price the merchant proposed for that line.

Creating a quote answers 201. If you send the same Idempotency-Key again within 24 hours, you get the original quote back with 200 and the header Idempotent-Replayed: true, so a retry never creates a duplicate. The key is 8 to 64 characters of letters, digits, _ or -.

Limit Value
Requests per shop 60 per 60 seconds, all routes and all of your API keys together
Quotes created per shop 20 per minute and 300 per day
Failed authentication per client 60 per 60 seconds from one IP address (missing or wrong key), then 429
Requests per IP address 300 per 60 seconds across the whole API, see below
Request body 1.5 MB maximum (JSON). A larger body returns 413 (see Errors)
Line items per quote 200 for a customer quote, 20 for a guest quote
Quantity per line 100,000
Note 2,000 characters (names 100, email 254)
Guest quotes 3 per email per 10 minutes, 30 per shop per hour
Active API keys 5 per shop

Successful responses and API errors for an authenticated request include headers that tell you where you stand against the limit that is closest to running out for that request (for example, the 3-per-email guest limit when you create a guest quote, otherwise the 20-per-minute create limit or the 60-per-minute shop limit).

Header Meaning
X-RateLimit-Limit Requests allowed in that window
X-RateLimit-Remaining Requests left in the current window
X-RateLimit-Reset Seconds until the window resets (a number of seconds, not a timestamp)

When you hit a limit the API answers 429 with the same three headers plus Retry-After (seconds to wait). Responses with status 401, 402 or 403 do not include the X-RateLimit-* headers. Failed authentication from one client is limited separately: that 429 carries no X-RateLimit-* headers, only Retry-After.

  • Each shop has one shared budget of 60 requests per 60 seconds, so several keys or systems of the same shop count together.
  • On a 429, stop and wait for the Retry-After seconds before you try again. Use exponential backoff and do not retry in a tight loop.
  • Repeatedly exceeding the IP limit (3 times within 10 minutes) blocks that IP address for 30 minutes, so a client that ignores Retry-After can lock itself out.
  • Keep each request body under 1.5 MB.

A request body larger than 2 MB is rejected before it reaches the API, with an HTML error page instead of the JSON error shape above.

Limits may change over time. If you need higher limits, contact our support team.

Errors have the shape { "status": "error", "errors": { "code": "...", "message": "...", "details": [...], "traceId": "..." }, "meta": { ... } }. details is present for validation errors and lists the field and message of each problem. Quote the traceId when you contact support.

HTTP Code Meaning
400 INVALID_BODY The body is not valid JSON
401 ACCESS_KEY_MISSING, ACCESS_KEY_INVALID No key, or the key is unknown, revoked or expired
402 PLAN_UPGRADE_REQUIRED Your shop is not on the Enterprise plan
403 AUTHORIZATION_DENIED The key does not have the permission this route needs
404 RESOURCE_NOT_FOUND The quote does not exist in your shop
409 REQUEST_IN_PROGRESS The same Idempotency-Key is still being processed
413 PAYLOAD_TOO_LARGE The request body is larger than 1.5 MB
422 VALIDATION_ERROR, CUSTOMER_NOT_FOUND, VARIANT_NOT_FOUND, TOO_MANY_LINE_ITEMS The request is not valid. TOO_MANY_LINE_ITEMS is returned when a quote has more line items than allowed, for both guest and customer quotes
429 RATE_LIMIT_EXCEEDED Too many requests, wait for Retry-After. This also applies to the per-IP limit
503 SERVICE_UNAVAILABLE Quote creation is temporarily unavailable, try again later

The full machine-readable description of the API (OpenAPI 3.1: endpoints, request and response schemas, error codes, rate limit headers) is available on request. Contact our support team and we will send you the specification file.

Updating or cancelling a quote, webhooks and OAuth are not part of the Beta.