openapi: 3.1.0
info:
title: Curated for You API
description: "\n# API Usage Guide\n\n## Overview\n\nThe Curated for You API provides endpoints to manage\
\ and retrieve\ninformation authentication, curations, companies, and attributes. This\nguide will\
\ help you understand how to authenticate and interact with\nthe API effectively. Your permissions\
\ are setup beforehand when you\njoin the organization, for additional permissions please contact\
\ your\ncustomer care representative.\n\n## Authentication\n\nThe Curated for You API uses OAuth 2.0\
\ Bearer token\nauthentication. Follow these steps to authenticate your requests:\n\n```bash\ncurl\
\ -X POST 'https://api.curatedforyou.io/api/v1/user/login' \\\n -H 'Content-Type: application/x-www-form-urlencoded'\
\ \\\n --data-urlencode 'username=your_email@example.com' \\\n --data-urlencode 'password=your_password'\n\
```\n\n### Use the Token\n\nAfter a successful login, you will receive a token. This token lasts\n\
for 30 minutes(?). Include the received token in the Authorization header\nfor all subsequent requests\n\
\n```bash\ncurl -G 'https://api.curatedforyou.io/api/v2/endpoint' \\\n -H 'Authorization: Bearer\
\ ENTER_AUTH_TOKEN_HERE' \\\n -H 'accept: application/json'\n```\n\n## Get Curation Products Guide\n\
\n### 1. Get Company Information\n\nRetrieve the companies you have access to:\n\n```bash\ncurl -G\
\ 'https://api.curatedforyou.io/api/v2/companies' \\\n -H 'Authorization: Bearer ENTER_AUTH_TOKEN_HERE'\
\ \\\n -H 'accept: application/json' \\\n -d 'projection=code_name' \\\n -d 'projection=display_name'\n\
```\n\nIn this example, we use projection limit our response to only\n`display_name` and the `code_name`.\n\
\n### 2. Get Curations\n\n\nUse the found `company_id` to get the curations within that company:\n\
\n```bash\ncurl -G 'https://api.curatedforyou.io/api/v2/curations' \\\n -H 'Authorization: Bearer\
\ ENTER_AUTH_TOKEN_HERE' \\\n -H 'accept: application/json' \\\n -d 'company_id=ENTER_COMPANY_ID_HERE'\
\ \\\n -d 'sort_by=created_at:desc' \\\n -d 'limit=50' \\\n -d 'offset=0' \\\n -d 'projection=curation_display_name'\
\ \\\n -d 'projection=curation_group_number' \\\n -d 'projection=curation_description' \\\n -d\
\ 'projection=export_page_url_handle' \\\n -d 'projection=company_product_ids'\n```\n\nThis example\
\ shows the different ways we can return information by\nspecifying different projections.\n\n###\
\ 3. Get Most Recent Snapshot\n\nAfter finding your specific curation we can query the snapshot that\n\
was exported to determine what information we should be displaying.\n\nThe curation_group_number is\
\ the important id to use and the\ninformation on how and what was exported can be found in the\n\
`meta_data` field.\n\n```bash\ncurl -G 'https://api.curatedforyou.io/api/v2/curation_snapshots' \\\
\n -H 'Authorization: Bearer ENTER_AUTH_TOKEN_HERE' \\\n -H 'accept: application/json' \\\n -d\
\ 'company_id=ENTER_COMPANY_ID_HERE' \\\n -d 'curation_group_number=CURATION_GROUP_NUMBER_HERE' \\\
\n -d 'sort_by=created_at:desc' \\\n -d 'limit=50' \\\n -d 'offset=0' \\\n -d 'projection=products'\
\ \\\n -d 'projection=meta_data' \\ # <<< where the last export time is found\n -d 'projection=display_name'\
\ \\\n -d 'projection=created_at'\n```\n"
version: 2.0.1
x-logo:
url: https://app.curatedforyou.io/cfy_logo.png
paths:
/api/v2/curations/:
get:
tags:
- Curations
summary: Fetch Curations
description: "This endpoint returns filtered and sorted curations based on specified query parameters.\
\ The response includes\npagination information and supports projection to customize the fields\
\ returned.\n\n### Terminology\n- Curation Group Number: A permanent unique identifier assigned\
\ to each curation that remains constant even if the curation is renamed or modified\n\n- Company\
\ Product ID: An external product identifier provided by the customer for integration purposes\n\
\n### Brief fields (projection only)\n- page_type and parent_curation_cgn are returned only when\
\ requested in projection.\n Values are taken from curation_briefs.attributes for this company\
\ and CGN with scope \"curation\"."
operationId: fetch_curations_api_v2_curations__get
parameters:
- name: company_id
in: query
required: true
schema:
type: integer
description: 'Company ID that owns the curations.
Required for filtering curations and permission checks.'
title: Company Id
description: 'Company ID that owns the curations.
Required for filtering curations and permission checks.'
example: 1
- name: curation_group_number
in: query
required: false
schema:
anyOf:
- type: array
items:
type: integer
- type: 'null'
description: 'Filter by Curation Group Numbers (CGNs).
Multiple CGNs can be provided to filter for multiple groups.'
title: Curation Group Number
description: 'Filter by Curation Group Numbers (CGNs).
Multiple CGNs can be provided to filter for multiple groups.'
- name: search
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 'Search keyword to filter curations by display name.
Uses case-insensitive partial matching.'
title: Search
description: 'Search keyword to filter curations by display name.
Uses case-insensitive partial matching.'
- name: sort_by
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 'Sort parameter in format ''field:direction:is_nulls_last''.
Defaults to ''curation_display_name:asc:true'' if not specified.
**Available sort fields:**
- curation_display_name: Sort by display name
- product_count: Sort by number of products
- last_export_date: Sort by last export date
- has_brief: Sort by whether curation brief exists
- freeze_body.frozen_at: Sort by when the curation was frozen
**Direction values:**
- asc: Ascending order
- desc: Descending order**is_nulls_last values:**
- true: Null values appear last
- false: Null values appear first
'
title: Sort By
description: 'Sort parameter in format ''field:direction:is_nulls_last''.
Defaults to ''curation_display_name:asc:true'' if not specified.
**Available sort fields:**
- curation_display_name: Sort by display name
- product_count: Sort by number of products
- last_export_date: Sort by last export date
- has_brief: Sort by whether curation brief exists
- freeze_body.frozen_at: Sort by when the curation was frozen
**Direction values:**
- asc: Ascending order
- desc: Descending order**is_nulls_last values:**
- true: Null values appear last
- false: Null values appear first
'
example: created_at:desc
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
description: 'Maximum number of curations to return.
Used for pagination.'
default: 50
title: Limit
description: 'Maximum number of curations to return.
Used for pagination.'
example: 50
- name: offset
in: query
required: false
schema:
type: integer
minimum: 0
description: 'Number of curations to skip.
Used for pagination.'
default: 0
title: Offset
description: 'Number of curations to skip.
Used for pagination.'
example: 0
- name: projection
in: query
required: false
schema:
anyOf:
- type: array
items:
type: string
- type: 'null'
description: '**Available Fields:**
id, curation_display_name, curation_group_number, curation_description, export_page_url_handle,
export_page_header, export_page_description, export_page_meta_title, export_page_meta_description,
promoted_to_live_at, last_export_date, created_at, updated_at, geo, settings, product_count,
company_product_ids
**Additional optional fields (projection only):**
page_type, parent_curation_cgn — from the curation brief (scope=curation) for this CGN; null
when missing or invalid.'
title: Projection
description: '**Available Fields:**
id, curation_display_name, curation_group_number, curation_description, export_page_url_handle,
export_page_header, export_page_description, export_page_meta_title, export_page_meta_description,
promoted_to_live_at, last_export_date, created_at, updated_at, geo, settings, product_count,
company_product_ids
**Additional optional fields (projection only):**
page_type, parent_curation_cgn — from the curation brief (scope=curation) for this CGN; null
when missing or invalid.'
example:
- id
- curation_display_name
- curation_group_number
- curation_description
- export_page_url_handle
- company_product_ids
- name: authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
responses:
'200':
description: Successful Response
content:
application/json:
schema:
title: Response Fetch Curations Api V2 Curations Get
examples:
default:
summary: Default Response
value:
data:
- id: 123
curation_display_name: Summer Collection 2024
curation_group_number: 456
curation_group_name: Summer Collections
version_status: live
product_count: 42
first_product:
product_id: 789
image_url: https://example.com/image.jpg
product_name: Summer Dress
total: 100
limit: 50
offset: 0
'400':
description: Bad Request
content:
application/json:
examples:
invalid_status:
summary: Invalid Status
value:
detail: 'Invalid status fields: [invalid_status]'
'403':
description: Forbidden
content:
application/json:
examples:
no_permission:
summary: No Permission
value:
detail: You do not have permission to read curations.
restricted_status:
summary: Restricted Status
value:
detail: You do not have permission to read updating/inactive/archived curations.
'404':
description: Not Found
content:
application/json:
example:
detail: Company not found
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/curations/'\\\n\
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/curations/\"\nparams =\
\ {'company_id': Query(PydanticUndefined), 'curation_owner_ids': Query(None), 'curation_group_number':\
\ Query(None), 'curation_cgns': Query(None), 'search': Query(None), 'status': Query(None), 'sort_by':\
\ Query(None), 'limit': Query(50), 'offset': Query(0), 'projection': Query(None), 'freeze':\
\ Query(None)}\nheaders ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers, params=params)\nprint(response.json())"
label: Python3
/api/v2/companies/:
get:
tags:
- Companies
summary: Get Companies
description: 'This endpoint returns filtered & sorted companies.
AUTHENTICATION (dual-mode):
- Global admin (Clerk or legacy) → all companies.
- Clerk non-admin → companies whose Clerk org the user belongs to (Redis).
- Legacy non-admin → companies from permission_id=3 entries in DB.'
operationId: get_companies_api_v2_companies__get
parameters:
- name: projection
in: query
required: false
schema:
anyOf:
- type: array
items:
type: string
- type: 'null'
description: Fields to return.
title: Projection
description: Fields to return.
example:
- id
- code_name
- display_name
- name: authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
responses:
'200':
description: Successful Response
content:
application/json:
schema:
title: Response Get Companies Api V2 Companies Get
examples:
default:
summary: Default Response
value:
data:
- code_name: example_company
display_name: Example Company
id: 191
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/companies/'\\\n\
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/companies/\"\nparams =\
\ {'code_name': Query(None), 'is_active': Query(None), 'visibility': Query(None), 'sort_by':\
\ Query(None), 'limit': Query(50), 'offset': Query(0), 'projection': Query(None), 'ai_attributes_enabled':\
\ Query(None), 'has_clerk_organization_id': Query(None), 'clerk_organization_id': Query(None)}\n\
headers ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers, params=params)\nprint(response.json())"
label: Python3
/api/v2/users/login:
post:
summary: Login
description: 'Authenticate yourself using your <a href="https://app.curatedforyou.io" target="_blank">CFY
App</a> credentials.
The response contains a bearer token, which you will need to provide to the **Authorization**
header to make other requests in the Curation API.'
operationId: login_api_v2_users_login_post
requestBody:
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Body_login_api_v2_users_login_post'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Token'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request POST 'https://api.curatedforyou.io/api/v2/users/login'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n\\\n --data-raw '{\n \"username\": \"jeffe@example.com\"\
,\n \"password\": \"secretpassword\"\n} '"
label: Curl
- lang: Python
source: "import requests\nimport json\n\nurl = \"https://api.curatedforyou.io/api/v2/users/login\"\
\npayload = json.dumps({\n \"username\": \"jeffe@example.com\",\n \"password\": \"secretpassword\"\
\n})\nheaders ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"POST\", url,\
\ headers=headers, data=payload)\nprint(response.json())"
label: Python3
/api/v2/shopify/install:
get:
tags:
- shopify
summary: Install
description: 'Shopify OAuth install handler.
Verifies HMAC, stores nonce in Redis keyed by nonce value (not shop),
then redirects the merchant to Shopify''s OAuth consent screen.'
operationId: install_api_v2_shopify_install_get
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/shopify/install'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/install\"\nheaders\
\ ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/callback:
get:
tags:
- shopify
summary: Callback
description: 'Shopify OAuth callback.
Verifies HMAC + nonce, exchanges code for access token, stores token in
GCP Secret Manager, upserts ShopifyStore DB row, redirects into Admin iframe.'
operationId: callback_api_v2_shopify_callback_get
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/shopify/callback'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/callback\"\nheaders\
\ ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/app:
get:
tags:
- shopify
summary: App Status Page
description: 'Serve the Account Status page (embedded app home).
No session token required for the page load — App Bridge v4 injects the token
into subsequent fetch() calls automatically.'
operationId: app_status_page_api_v2_shopify_app_get
responses:
'200':
description: Successful Response
content:
text/html:
schema:
type: string
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/shopify/app'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/app\"\nheaders\
\ ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/app/collections:
get:
tags:
- shopify
summary: App Collections Page
description: Serve the Collections page of the embedded app.
operationId: app_collections_page_api_v2_shopify_app_collections_get
responses:
'200':
description: Successful Response
content:
text/html:
schema:
type: string
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/shopify/app/collections'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/app/collections\"\
\nheaders ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/ensure-installed:
post:
tags:
- shopify
summary: Ensure Installed
description: 'Exchange session token for offline access token on first load.
Managed installation bypasses /install and /callback — Shopify handles
consent itself and loads application_url directly in the iframe. This
endpoint detects the missing store record and exchanges the session token
(JWT) for a non-expiring offline access token via Shopify''s token exchange
API.
Idempotent: returns immediately if store record already exists.'
operationId: ensure_installed_api_v2_shopify_ensure_installed_post
responses:
'200':
description: Successful Response
content:
application/json:
schema:
additionalProperties: true
type: object
title: Response Ensure Installed Api V2 Shopify Ensure Installed Post
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request POST 'https://api.curatedforyou.io/api/v2/shopify/ensure-installed'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\nimport json\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/ensure-installed\"\
\nheaders ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"POST\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/status:
get:
tags:
- shopify
summary: Get Store Status
description: 'Return whether the store is linked to a CFY company account.
Returns unlinked (not 404) when the store is brand-new — there is a brief window
after OAuth where the session token is valid but the DB upsert hasn''t committed yet.'
operationId: get_store_status_api_v2_shopify_status_get
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/StoreStatusResponse'
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/shopify/status'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/status\"\nheaders\
\ ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/all-collections:
get:
tags:
- shopify
summary: List All Collections
description: 'Fetch all Shopify collections for this store via GraphQL.
Works for any installer regardless of company_id — reviewers see real data.
Paginates up to MAX_PAGES (500 collections).'
operationId: list_all_collections_api_v2_shopify_all_collections_get
responses:
'200':
description: Successful Response
content:
application/json:
schema:
items:
$ref: '#/components/schemas/AllCollectionResponse'
type: array
title: Response List All Collections Api V2 Shopify All Collections Get
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/shopify/all-collections'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/all-collections\"\
\nheaders ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/collections:
get:
tags:
- shopify
summary: List Collections
description: 'Return CFY-managed collections for this store.
Note: this endpoint is for the export pipeline, not the embedded UI.
The embedded UI uses /all-collections (Tab 2) and /status (Tab 1).
Returns empty list if the store is not yet linked to a CFY company.'
operationId: list_collections_api_v2_shopify_collections_get
responses:
'200':
description: Successful Response
content:
application/json:
schema:
items:
$ref: '#/components/schemas/CollectionResponse'
type: array
title: Response List Collections Api V2 Shopify Collections Get
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request GET 'https://api.curatedforyou.io/api/v2/shopify/collections'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/collections\"\n\
headers ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"GET\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/request-setup:
post:
tags:
- shopify
summary: Request Setup
description: 'Log an account setup request and notify CFY staff via Slack.
Idempotent per store per 24 hours — prevents flooding from repeated clicks.'
operationId: request_setup_api_v2_shopify_request_setup_post
responses:
'200':
description: Successful Response
content:
application/json:
schema:
additionalProperties: true
type: object
title: Response Request Setup Api V2 Shopify Request Setup Post
x-codeSamples:
- lang: Shell
source: "curl --location\\\n --request POST 'https://api.curatedforyou.io/api/v2/shopify/request-setup'\\\
\n--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w'\\\
\n--header 'Content-Type: application/json'\\\n"
label: Curl
- lang: Python
source: "import requests\nimport json\n\nurl = \"https://api.curatedforyou.io/api/v2/shopify/request-setup\"\
\nheaders ={\n \"Authorization\": \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NzMwNDkxNzgsImV4cCI6MTcwNDU4NTE3OCwiYXVkIjoid3d3LmV4YW1w\"\
,\n \"Content-Type\": \"application/json\"\n}\nresponse = requests.request(\"POST\", url,\
\ headers=headers)\nprint(response.json())"
label: Python3
/api/v2/shopify/collections/{handle}/res
# --- truncated at 32 KB (55 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/curated-for-you/refs/heads/main/openapi/curated-for-you-openapi-original.yml