Docs
Dashboard
On this page

    Categories

    7 endpoints. Each needs an API key or OAuth token with the scope shown; the key already names its store, so paths start at /v1/store. Generated from the live contract; also in openapi.json.

    Every product category in tree order, with product counts (own and with subcategories)

    GET/v1/store/categories

    Or name the store: GET /v1/stores/{storeId}/categories

    catalog:readrole: catalog:readlistCategories

    Response CategoryList

    • categoriesCategory[]required

    Example

    curl "https://api.shopfa.st/v1/store/categories" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY"
    const res = await fetch('https://api.shopfa.st/v1/store/categories', {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
      },
    });
    if (!res.ok) throw new Error((await res.json()).detail);
    const data = await res.json();
    import os, requests
    
    res = requests.request(
        "GET",
        "https://api.shopfa.st/v1/store/categories",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/categories", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Create a category, top-level or under a parent, optionally with products

    POST/v1/store/categories

    Or name the store: POST /v1/stores/{storeId}/categories

    catalog:writerole: catalog:writecreateCategory

    Body

    • titlestringrequired
    • handlestring | null
    • parentIdpcat_… | null
    • indexinteger | null
    • descriptionstring
    • imageUrlstring | null
    • publishedboolean
    • sort"manual" | "best_selling" | "newest" | "price_asc" | "price_desc" | "title"
    • seoTitlestring | null
    • seoDescriptionstring | null
    • productIdsprd_…[]

    Response CreateCategoryResponse

    • categoryCategoryrequired
    • categoriesCategory[]required
    • fullProductId[]required

    Example

    curl -X POST "https://api.shopfa.st/v1/store/categories" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "title": "string",
      "handle": null,
      "parentId": null,
      "index": null,
      "description": "",
      "imageUrl": null,
      "published": true,
      "sort": "manual",
      "seoTitle": null,
      "seoDescription": null,
      "productIds": []
    }'
    const res = await fetch('https://api.shopfa.st/v1/store/categories', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "title": "string",
        "handle": null,
        "parentId": null,
        "index": null,
        "description": "",
        "imageUrl": null,
        "published": true,
        "sort": "manual",
        "seoTitle": null,
        "seoDescription": null,
        "productIds": []
      }),
    });
    if (!res.ok) throw new Error((await res.json()).detail);
    const data = await res.json();
    import os, requests
    
    res = requests.request(
        "POST",
        "https://api.shopfa.st/v1/store/categories",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
        json={
          "title": "string",
          "handle": None,
          "parentId": None,
          "index": None,
          "description": "",
          "imageUrl": None,
          "published": True,
          "sort": "manual",
          "seoTitle": None,
          "seoDescription": None,
          "productIds": []
        },
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/categories", strings.NewReader(`{
      "title": "string",
      "handle": null,
      "parentId": null,
      "index": null,
      "description": "",
      "imageUrl": null,
      "published": true,
      "sort": "manual",
      "seoTitle": null,
      "seoDescription": null,
      "productIds": []
    }`))
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Rename a category or change its handle (the old one redirects), description, image, SEO, sort or visibility

    PATCH/v1/store/categories/{categoryId}

    Or name the store: PATCH /v1/stores/{storeId}/categories/{categoryId}

    catalog:writerole: catalog:writeupdateCategory

    Parameters

    • categoryIdpcat_…pathrequired

    Body

    • titlestring
    • handlestring
    • descriptionstring
    • imageUrlstring | null
    • publishedboolean
    • sort"manual" | "best_selling" | "newest" | "price_asc" | "price_desc" | "title"
    • seoTitlestring | null
    • seoDescriptionstring | null

    Response UpdateCategoryResponse

    • categoryCategoryrequired
    • categoriesCategory[]required

    Example

    curl -X PATCH "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "title": "string",
      "handle": "string",
      "description": "string",
      "imageUrl": "string",
      "published": false,
      "sort": "manual",
      "seoTitle": "string",
      "seoDescription": "string"
    }'
    const res = await fetch('https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk', {
      method: 'PATCH',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "title": "string",
        "handle": "string",
        "description": "string",
        "imageUrl": "string",
        "published": false,
        "sort": "manual",
        "seoTitle": "string",
        "seoDescription": "string"
      }),
    });
    if (!res.ok) throw new Error((await res.json()).detail);
    const data = await res.json();
    import os, requests
    
    res = requests.request(
        "PATCH",
        "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
        json={
          "title": "string",
          "handle": "string",
          "description": "string",
          "imageUrl": "string",
          "published": False,
          "sort": "manual",
          "seoTitle": "string",
          "seoDescription": "string"
        },
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("PATCH", "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk", strings.NewReader(`{
      "title": "string",
      "handle": "string",
      "description": "string",
      "imageUrl": "string",
      "published": false,
      "sort": "manual",
      "seoTitle": "string",
      "seoDescription": "string"
    }`))
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Delete a category: lift or delete its subcategories, file its products in the parent or take them out

    DELETE/v1/store/categories/{categoryId}

    Or name the store: DELETE /v1/stores/{storeId}/categories/{categoryId}

    catalog:writerole: catalog:writedeleteCategory

    Parameters

    • categoryIdpcat_…pathrequired
    • children"lift" | "delete"query
    • products"parent" | "unassign"query

    Response CategoryDeleteResult

    • deletedintegerrequired
    • liftedintegerrequired
    • reassignedintegerrequired
    • unassignedintegerrequired
    • categoriesCategory[]required

    Example

    curl -X DELETE "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY"
    const res = await fetch('https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk', {
      method: 'DELETE',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
      },
    });
    if (!res.ok) throw new Error((await res.json()).detail);
    const data = await res.json();
    import os, requests
    
    res = requests.request(
        "DELETE",
        "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("DELETE", "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Move a category under another parent (or to the top level) and to a place among its siblings

    POST/v1/store/categories/{categoryId}/move

    Or name the store: POST /v1/stores/{storeId}/categories/{categoryId}/move

    catalog:writerole: catalog:writemoveCategory

    Parameters

    • categoryIdpcat_…pathrequired

    Body

    • parentIdpcat_… | nullrequired
    • indexintegerrequired

    Response CategoryList

    • categoriesCategory[]required

    Example

    curl -X POST "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/move" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "parentId": "pcat_0123456789abcdefghjk",
      "index": 0
    }'
    const res = await fetch('https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/move', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "parentId": "pcat_0123456789abcdefghjk",
        "index": 0
      }),
    });
    if (!res.ok) throw new Error((await res.json()).detail);
    const data = await res.json();
    import os, requests
    
    res = requests.request(
        "POST",
        "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/move",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
        json={
          "parentId": "pcat_0123456789abcdefghjk",
          "index": 0
        },
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/move", strings.NewReader(`{
      "parentId": "pcat_0123456789abcdefghjk",
      "index": 0
    }`))
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Products filed directly in a category

    GET/v1/store/categories/{categoryId}/products

    Or name the store: GET /v1/stores/{storeId}/categories/{categoryId}/products

    catalog:readrole: catalog:readlistCategoryProducts

    Parameters

    • categoryIdpcat_…pathrequired

    Response CategoryProducts

    • productIdsProductId[]required

    Example

    curl "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/products" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY"
    const res = await fetch('https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/products', {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
      },
    });
    if (!res.ok) throw new Error((await res.json()).detail);
    const data = await res.json();
    import os, requests
    
    res = requests.request(
        "GET",
        "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/products",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/products", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    File products in a category or take them out

    POST/v1/store/categories/{categoryId}/products

    Or name the store: POST /v1/stores/{storeId}/categories/{categoryId}/products

    catalog:writerole: catalog:writechangeCategoryProducts

    Parameters

    • categoryIdpcat_…pathrequired

    Body

    • addprd_…[]
    • removeprd_…[]

    Response CategoryProductsResult

    • addedintegerrequired
    • removedintegerrequired
    • fullProductId[]required
    • categoriesCategory[]required

    Example

    curl -X POST "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/products" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "add": [],
      "remove": []
    }'
    const res = await fetch('https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/products', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "add": [],
        "remove": []
      }),
    });
    if (!res.ok) throw new Error((await res.json()).detail);
    const data = await res.json();
    import os, requests
    
    res = requests.request(
        "POST",
        "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/products",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
        json={
          "add": [],
          "remove": []
        },
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/categories/pcat_0123456789abcdefghjk/products", strings.NewReader(`{
      "add": [],
      "remove": []
    }`))
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Was this page helpful?