Granite Shopify API
Shopify stores connected with the Granite for Shopify app.
Shopify stores connected with the Granite for Shopify app.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/granite-md:granite-md-shopify-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Granite Shopify API
version: 1.0.0
summary: REST API for Granite clients, bots, and integrations.
description: 'Conventions (apply to every operation; see PLAN.md 3.2 and 3.6):
- **Base URL** `https://api.granite.md`. All public operations live under `/v1`.
After Phase 6 ships, `/v1` changes are additive only.
- **Errors** use RFC 9457 problem details (`application/problem+json`, schema `Problem`).
The `type` URI is `https://granite.md/problems/`; `code` refines it for programmatic handling.
Every response carries `X-Request-ID`, also echoed as `request_id` in problems.
- **Pagination** is cursor based. List operations accept `cursor` and `limit` and return
`{ "items": [...], "next_cursor": "..." }`. `next_cursor` is absent on the last page.
Cursors are opaque; clients must not parse or build them.
- **Idempotency**: non-idempotent `POST` operations accept an `Idempotency-Key` header
(1-255 printable ASCII). Repeating a request with the same key and body within 24 hours
returns the original response; the same key with a different body returns `409` with
code `idempotency_key_reused`.
- **IDs** are UUIDv7 strings. **Timestamps** are RFC 3339 in UTC.
- **Authentication**: `Authorization: Bearer ` with a session access token,
a personal API token (`gr_pat_...`), or an OAuth access token. Scopes are listed per operation.
- **Rate limits**: each personal API token may make 600 requests a minute. Over the limit
the API answers `429` with code `token_rate_limited` and a `Retry-After` header (seconds).'
license:
name: Proprietary
identifier: LicenseRef-Proprietary
servers:
- url: https://api.granite.md
description: Production
- url: http://localhost:8080
description: Local development
security:
- bearerAuth: []
tags:
- name: Shopify
description: Shopify stores connected with the Granite for Shopify app.
paths:
/v1/me/shopify-stores:
get:
operationId: listShopifyStores
tags:
- Shopify
summary: Shopify stores connected to you
description: 'Stores you connected to Granite with the Granite for Shopify app, and stores connected to
workspaces you administer. Each store''s notes are in its vault.'
responses:
'200':
description: Stores.
content:
application/json:
schema:
$ref: '#/components/schemas/ShopifyStoreList'
default:
$ref: '#/components/responses/Error'
/v1/me/shopify-stores/{shop_domain}:
parameters:
- name: shop_domain
in: path
required: true
schema:
type: string
maxLength: 255
delete:
operationId: disconnectShopifyStore
tags:
- Shopify
summary: Disconnect a Shopify store
description: The store stops syncing; its vault and notes stay where they are.
responses:
'204':
description: Disconnected.
default:
$ref: '#/components/responses/Error'
/v1/shopify-links/{code}:
parameters:
- name: code
in: path
required: true
description: The one-time code from the link the app in Shopify opened.
schema:
type: string
maxLength: 100
get:
operationId: getShopifyLink
tags:
- Shopify
summary: See which store a connect link is for
description: 'The store behind a connect link and the accounts you may connect it to: your own, or a
workspace you own or administer. Codes work for 15 minutes (404 `shopify_link_invalid`).'
responses:
'200':
description: The store and your choices.
content:
application/json:
schema:
$ref: '#/components/schemas/ShopifyLinkPreview'
default:
$ref: '#/components/responses/Error'
post:
operationId: completeShopifyLink
tags:
- Shopify
summary: Connect a Shopify store
description: 'Connects the store to the chosen account and creates the vault " (Shopify)"
for it (the plan''s vault and storage limits apply), then the store''s catalog is imported.
The code then stops working. Needs a signed-in session.'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ShopifyLinkComplete'
responses:
'200':
description: The connected store.
content:
application/json:
schema:
$ref: '#/components/schemas/ShopifyStore'
default:
$ref: '#/components/responses/Error'
components:
schemas:
ShopifyStore:
type: object
required:
- shop_domain
- shop_name
- status
properties:
shop_domain:
type: string
shop_name:
type: string
status:
type: string
enum:
- installed
- uninstalled
- redacted
connected:
type: boolean
vault_id:
type: string
format: uuid
owner_type:
type: string
enum:
- user
- workspace
connected_at:
type: string
format: date-time
ShopifyLinkPreview:
type: object
required:
- shop_domain
- shop_name
- owners
properties:
shop_domain:
type: string
shop_name:
type: string
owners:
type: array
items:
$ref: '#/components/schemas/ShopifyOwnerChoice'
connected_to:
type: string
description: The account the store is connected to now (absent when it is not connected).
Problem:
type: object
description: RFC 9457 problem details.
required:
- type
- title
- status
properties:
type:
type: string
format: uri
examples:
- https://granite.md/problems/conflict
title:
type: string
status:
type: integer
format: int32
detail:
type: string
instance:
type: string
code:
type: string
description: Machine-readable refinement of `type`, for example `version_conflict`.
request_id:
type: string
errors:
type: array
description: Per-field validation errors.
items:
$ref: '#/components/schemas/FieldError'
ShopifyOwnerChoice:
type: object
required:
- type
- id
- name
- plan
properties:
type:
type: string
enum:
- user
- workspace
id:
type: string
format: uuid
name:
type: string
plan:
type: string
description: The Granite plan name; it decides the app's features.
ShopifyLinkComplete:
type: object
required:
- owner_type
- owner_id
properties:
owner_type:
type: string
enum:
- user
- workspace
owner_id:
type: string
format: uuid
FieldError:
type: object
required:
- field
- detail
properties:
field:
type: string
description: JSON path of the invalid field, for example `ops[2].path`.
detail:
type: string
ShopifyStoreList:
type: object
required:
- items
properties:
items:
type: array
items:
$ref: '#/components/schemas/ShopifyStore'
headers:
RequestID:
description: Identifier of this request, for support and log correlation.
schema:
type: string
responses:
Error:
description: Error response.
headers:
X-Request-ID:
$ref: '#/components/headers/RequestID'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: Session access token, personal API token, or OAuth access token.