Developer reference
Riggr exposes your connected Shopify store two ways: a remote MCP server for AI clients like Claude, Codex, ChatGPT, and Cursor, and a Bearer-authenticated REST API for everything else.
Authentication
All API endpoints authenticate with a Bearer token. Generate one on the dashboard. You'll see the full key once. Include it on every request:
Authorization: Bearer rg_live_...Keys are revocable from the dashboard at any time, are tied to the user account that generated them, and grant access to that account's connected Shopify store.
MCP server
Point an AI client (Claude Desktop, Claude.ai, Cursor, Codex) straight at your store. Riggr runs a remote MCP server over Streamable HTTP at:
https://www.hiriggr.com/api/mcpPaste that URL into your client. The first request opens a Riggr browser tab where you sign in and click Allow; from then on the client stores a token and calls the server directly. You can see and revoke every authorized client from your dashboard.
For a one-click setup of the popular clients, open Connections in your dashboard.
Auth is OAuth 2.1 with PKCE per the MCP spec; dynamic client registration means clients discover everything they need from the .well-known metadata. Nothing to configure by hand.
Riggr's Shopify install is read-only. Active tools cover orders, fulfillments, products, locations, shipping, returns, and publications. Those responses omit customer name, email, phone, and street address. Tools tagged PCD Level 2 need Shopify Protected Customer Data Level 2 approval, which Riggr does not have. Tools tagged Not available need Shopify permissions Riggr does not have. Both are listed here so you can see why a call fails if you try them.
list_orders
List orders from your connected Shopify store. Shopify only shares orders from the last 60 days with Riggr, so older orders won't appear.
| Arg | Type | Required | Description |
|---|---|---|---|
query | string | No | Passed directly to Shopify Admin GraphQL's order search syntax, e.g. financial_status:paid updated_at:>=2026-01-01. Strictly more powerful than the REST updated_at_min filter. |
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. Omit for the first page. |
Returns { orders: [...], pageInfo: {...} }, where each order is Shopify Admin GraphQL's native order shape.
get_order
Takes { id }, a Shopify order GID. Returns { order: {...} }, the same shape as each item in list_orders. Orders older than 60 days won't be found.
get_shop
Takes no arguments. Returns { domain, currency, timezone, locations }, the same fields as GET /api/v1/shop below.
list_locations
Takes no arguments. Returns { locations: [...] }. Every location on the store, active or not.
list_products
List products from your connected Shopify store.
| Arg | Type | Required | Description |
|---|---|---|---|
query | string | No | Shopify Admin GraphQL product search syntax, e.g. status:active vendor:Acme. |
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. |
Returns { products: [...], pageInfo: {...} }.
get_product
Takes { id }, a Shopify product GID. Returns { product: {...} } including up to 100 variants.
list_customersPCD Level 2
List customers from your connected Shopify store. Not available. This requires Shopify Protected Customer Data Level 2 approval, which Riggr does not have.
| Arg | Type | Required | Description |
|---|---|---|---|
query | string | No | Shopify Admin GraphQL customer search syntax, e.g. orders_count:>5. |
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. |
Returns { customers: [...], pageInfo: {...} }.
get_customerPCD Level 2
Takes { id }, a Shopify customer GID. Returns { customer: {...} } including lifetime order count and amount spent. Not available. This requires Shopify Protected Customer Data Level 2 approval, which Riggr does not have.
list_draft_ordersNot available
List draft (unpaid) orders from your connected Shopify store. Not available. Riggr does not have the Shopify permission required for this.
| Arg | Type | Required | Description |
|---|---|---|---|
query | string | No | Shopify Admin GraphQL draft order search syntax, e.g. status:open. |
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. |
Returns { draftOrders: [...], pageInfo: {...} }.
list_abandoned_checkoutsPCD Level 2
List abandoned checkouts (started but never completed). No search query support. Not available. This requires Shopify Protected Customer Data Level 2 approval, which Riggr does not have.
| Arg | Type | Required | Description |
|---|---|---|---|
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. |
Returns { abandonedCheckouts: [...], pageInfo: {...} }.
list_discountsNot available
List discounts (code-based and automatic) from your connected Shopify store. Not available. Riggr does not have the Shopify permission required for this.
| Arg | Type | Required | Description |
|---|---|---|---|
query | string | No | Shopify Admin GraphQL discount search syntax, e.g. status:active. |
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. |
Returns { discounts: [...], pageInfo: {...} }, where each discount is a DiscountCodeBasic or DiscountAutomaticBasic.
list_inventory_levelsNot available
List inventory levels for every item at a location. Not available. Riggr does not have the Shopify permission required for this.
| Arg | Type | Required | Description |
|---|---|---|---|
locationId | string (GID) | Yes | A location GID from list_locations or get_shop. |
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. |
Returns { location: {...}, inventoryLevels: [...], pageInfo: {...} }.
list_returns
List returns for a single order. Shopify has no shop-wide returns list, so this is scoped to one order at a time.
| Arg | Type | Required | Description |
|---|---|---|---|
orderId | string (GID) | Yes | An order GID from list_orders. |
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. |
Returns { order: {...}, returns: [...], pageInfo: {...} }.
list_marketing_eventsNot available
List marketing events (campaigns) recorded for the store. Not available. Riggr does not have the Shopify permission required for this.
| Arg | Type | Required | Description |
|---|---|---|---|
first | integer (1-250) | No | Page size. Defaults to 100. |
after | string (cursor) | No | Opaque cursor from a prior call's pageInfo.endCursor. |
Returns { marketingEvents: [...], pageInfo: {...} }.
All active Riggr tools throw a descriptive tool error (not a raw HTTP error) for an unauthenticated request, a missing or uninstalled store, a missing scope, or a Shopify rate limit (the retry delay is included in the error message, since MCP has no Retry-After header equivalent).
Client setup
Claude.ai: Settings → Connectors → Add custom connector → paste the URL above → sign in when prompted.
Claude Desktop: Add this to claude_desktop_config.json, then restart Claude:
{
"mcpServers": {
"riggr": {
"type": "http",
"url": "https://www.hiriggr.com/api/mcp"
}
}
}Cursor: Add this to ~/.cursor/mcp.json:
{
"mcpServers": {
"riggr": {
"url": "https://www.hiriggr.com/api/mcp"
}
}
}Codex: Run codex mcp add riggr --url https://www.hiriggr.com/api/mcp then codex mcp login riggr, or add this to ~/.codex/config.toml:
[mcp_servers.riggr]
url = "https://www.hiriggr.com/api/mcp"Alternative: API key
For scripts, or clients that don't support OAuth, generate an API key on the dashboard and send it as a Bearer token instead. The endpoint accepts either credential:
{
"mcpServers": {
"riggr": {
"type": "http",
"url": "https://www.hiriggr.com/api/mcp",
"headers": { "Authorization": "Bearer rg_live_..." }
}
}
}REST endpoints
Every MCP tool has a matching REST endpoint. Responses use the same JSON shape. List endpoints return { <resource>, pageInfo }, single-item endpoints return the raw entity. Path parameters that hold a Shopify GID (e.g. gid://shopify/Order/123) must be URL-encoded. Every endpoint requires a Bearer token; see the /api/v1/orders worked example below for full request + response shape. Endpoints tagged PCD Level 2 need Shopify Protected Customer Data Level 2 approval, which Riggr does not have. Endpoints tagged Not available need Shopify permissions Riggr does not have. Both stay listed so you can match a failed call to the reason here.
Orders & fulfillment
GET /api/v1/ordersfirst, after, updated_at_minList orders (ops fields + destination region only; no customer name, email, phone, or street). Worked example below.
GET /api/v1/orders/{id}Single order by Shopify GID (same field set: no customer name, email, phone, or street).
GET /api/v1/orders/{id}/returnsfirst, afterReturns for a specific order.
GET /api/v1/draft-ordersfirst, after, queryNot availableUnpaid draft orders. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/abandoned-checkoutsfirst, afterPCD Level 2Checkouts started but never completed. Not available. This requires Shopify Protected Customer Data Level 2 approval, which Riggr does not have.
GET /api/v1/fulfillment-ordersfirst, after, queryFulfillment orders: merchant-managed, assigned, and 3PL. Each carries its order name/ID, fulfillAt/fulfillBy, line-item product titles, and destination country only.
Products
GET /api/v1/productsfirst, after, queryList products with storewide totalInventory and tracksInventory. When tracksInventory is false, Shopify does not count stock and totalInventory is 0.
GET /api/v1/products/{id}Single product by GID with up to 100 variants.
Customers
GET /api/v1/customersfirst, after, queryPCD Level 2List customers. Not available. This requires Shopify Protected Customer Data Level 2 approval, which Riggr does not have.
GET /api/v1/customers/{id}PCD Level 2Single customer including lifetime totals. Not available. This requires Shopify Protected Customer Data Level 2 approval, which Riggr does not have.
GET /api/v1/companiesfirst, after, queryNot availableB2B companies. Not available. Riggr does not have the Shopify permission required for this.
Store & inventory
GET /api/v1/shopShop metadata and locations. Worked example below.
GET /api/v1/locationsEvery location, active or not.
GET /api/v1/locations/{locationId}/inventory-levelsfirst, afterNot availableInventory at a specific location. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/delivery-profilesfirst, afterShipping profiles and origin locations.
Marketing & discounts
GET /api/v1/discountsfirst, after, queryNot availableDiscounts: code-based and automatic. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/marketing-eventsfirst, afterNot availableRecorded marketing campaigns. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/gift-cardsfirst, after, queryNot availableGift cards with balances. Not available. Riggr does not have the Shopify permission required for this.
Payments
GET /api/v1/payoutsfirst, afterNot availableShopify Payments payouts. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/disputesfirst, afterNot availableShopify Payments chargebacks. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/payment-terms-templatesNot availableB2B payment term templates. Not available. Riggr does not have the Shopify permission required for this.
Content & publishing
GET /api/v1/articlesfirst, after, queryNot availableBlog articles. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/pagesfirst, after, queryNot availableOnline store pages. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/publicationsfirst, afterSales channels (publications).
GET /api/v1/product-feedsfirst, afterNot availableProduct feeds (e.g. Google, Facebook). Not available. Riggr does not have the Shopify permission required for this.
Metaobjects & analytics
GET /api/v1/metaobject-definitionsfirst, afterNot availableMetaobject definitions and their fields. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/metaobjectstype (required), first, afterNot availableMetaobject instances for a given type. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/shopifyqlquery (required)Not availableRun a ShopifyQL analytics query. Not available. Riggr does not have the Shopify permission required for this.
GET /api/v1/orders
Pull orders from your connected Shopify store, paginated. Shopify only shares orders from the last 60 days with Riggr, so older orders won't appear.
| Param | Type | Required | Description |
|---|---|---|---|
updated_at_min | ISO-8601 datetime | No | Only return orders updated at or after this timestamp. |
after | string (cursor) | No | Opaque cursor from a prior response's pageInfo.endCursor. Omit for the first page. |
first | integer (1-250) | No | Page size. Defaults to 100. |
Returns { orders: [...], pageInfo: { hasNextPage, endCursor } }. Each order keeps Shopify Admin GraphQL's field names; nested lists such as lineItems stay in Shopify's { edges: [{ node }] } shape.
{
"orders": [
{
"id": "gid://shopify/Order/1234567890",
"name": "#1001",
"displayFulfillmentStatus": "FULFILLED",
"createdAt": "2026-01-02T15:04:05Z",
"updatedAt": "2026-01-03T09:00:00Z",
"totalPriceSet": {
"shopMoney": { "amount": "58.00", "currencyCode": "USD" }
},
"tags": ["priority"],
"lineItems": {
"edges": [
{ "node": { "id": "gid://shopify/LineItem/1", "name": "Blue Hat", "quantity": 2 } }
]
},
"fulfillments": [
{ "id": "gid://shopify/Fulfillment/1", "status": "SUCCESS", "trackingInfo": [] }
]
}
],
"pageInfo": { "hasNextPage": true, "endCursor": "eyJsYXN0X2lkIjoxMjM0fQ==" }
}| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_query | Query params failed validation, e.g. first out of range or updated_at_min not ISO-8601. |
| 400 | invalid_id | The id in the path is not a Shopify GID of the right type (e.g. gid://shopify/Order/1234567890) or a plain numeric id. |
| 401 | unauthorized | Missing, invalid, or revoked Bearer token. |
| 409 | no_store_connected | This account has no connected Shopify store. |
| 410 | store_uninstalled | The connected Shopify store was uninstalled. |
| 429 | retryAfterSeconds | Rate-limited by Shopify. The Retry-After header is set, and the body carries retryAfterSeconds. |
| 502 | shopify_upstream | Shopify's Admin API returned an unexpected error. |
curl -H "Authorization: Bearer rg_live_..." \
"https://www.hiriggr.com/api/v1/orders?updated_at_min=2026-01-01T00:00:00Z&first=50"GET /api/v1/shop
Fetch shop metadata (domain, currency, timezone, locations).
| Field | Type | Description |
|---|---|---|
domain | string | The store's *.myshopify.com domain. |
currency | string | ISO 4217 currency code, e.g. USD. |
timezone | string | IANA timezone, e.g. America/Chicago. |
locations | array | Store locations. Each has id, name, and address. |
curl -H "Authorization: Bearer rg_live_..." \
"https://www.hiriggr.com/api/v1/shop"Pagination pattern
For the first page, omit after. Each response includes a pageInfo.endCursor and a pageInfo.hasNextPage. Pass endCursor back as the after param to fetch the next page. Stop when hasNextPage is false.
let after;
while (true) {
const res = await fetch(`${base}/api/v1/orders?first=100${after ? `&after=${after}` : ""}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { orders, pageInfo } = await res.json();
handle(orders);
if (!pageInfo.hasNextPage) break;
after = pageInfo.endCursor;
}Incremental sync
For steady-state syncs, keep track of the most recent updated_at you've seen and pass it as updated_at_min on subsequent requests. The endpoint orders results by updated_at ascending, so cursor-paginated responses give a consistent delta window.
Rate limits & retries
The pull endpoint doesn't add rate limits of its own. It passes through Shopify's per-store limits. If Shopify returns 429, the endpoint forwards the Retry-After header and a JSON body with retryAfterSeconds. Back off and retry.