PIM Category API: Get Category Names, IDs, and Products
Author name: Mark James
By the end of this tutorial, you will have a working implementation that reads product category names from an API, maps them to internal identifiers, and filters product lists for your storefront. Centralizing this logic ensures your e-commerce channels, B2B portals, and internal tools display consistent catalog data. Before writing any code, gather your prerequisites. You need an active API key with Data Viewer permissions to read product lists, a key with Data Editor permissions to list categories, and a separate key with Data Manager permissions to create or edit categories. You also need access to your platform workspace, because PIMinto acts as the single source of truth for organizing these technical catalogs and digital assets. We will use standard JavaScript to handle the requests and parse the responses.

1. Decode getCategory().name Before Calling the API
Developers searching for a "getcategory().name" borefeature api solution usually encounter two separate problems. The first is parsing generic JavaScript object properties, and the second is mapping highly specific technical attributes to a catalog structure. We address the syntax first.
The syntax getCategory().name is a standard property-access pattern. It invokes getCategory() and reads the name property from the returned object. In a synchronous call, the function returns that object before the property access occurs.
// Illustrative synchronous property accessconst currentCategory = getCategory();
const categoryName = currentCategory.name;
This pattern breaks in modern web integrations because API requests are asynchronous, meaning a network call returns a promise rather than the final object. Attempting to read .name directly from an unawaited promise returns undefined, so you must resolve it using await before accessing the data. When your code evaluates getCategory().name without waiting for the network resolution, the runtime attempts to inspect the pending Promise instance itself. Because a Promise does not expose the payload's properties, the expression evaluates to undefined or throws a runtime error in strict TypeScript environments.
// Illustrative asynchronous requestconst categoryData = await fetchCategory(categoryId);
const categoryName = categoryData?.name ?? 'Unknown Category';
API responses frequently wrap their data in an envelope, meaning the actual object you want might live inside a payload or data property. If the response returns { "data": { "category": { "name": "Valves" } } }, the direct .name lookup fails, and you must navigate the envelope first. In nested JSON envelopes, the root response object often contains metadata such as status codes, timestamps, pagination objects, or error arrays alongside the category record. Attempting a flat access like response.name yields undefined, which cascades into broken UI headers or missing navigation labels. Writing a resilient accessor function protects your frontend rendering pipeline against these slight schema variations:
// Illustrative response envelope handlingconst response = await fetch('/api/categories/123');
const payload = await response.json();
const category = payload.data?.category ?? payload.category ?? payload;
const categoryName = category?.name ?? null;
Optional chaining through the ?. operator prevents an uncaught exception when an intermediate object key is missing or set to null. Coupling optional chaining with the nullish coalescing operator ?? allows you to provide a sensible fallback string, such as "Uncategorized" or "Catalog Products", when an incoming category record lacks a defined title.
The published Piminto API v1.3.27 documentation details category discovery, category trees, and management operations without establishing a literal SDK method named getCategory(). Instead, you construct your own fetch requests against the documented REST endpoints rather than relying on assumed function names. Understanding this boundary saves hours of debugging: when you encounter a code sample using getCategory().name, treat it as an illustrative abstraction representing an HTTP call followed by a JSON property lookup, rather than an out-of-the-box helper provided by the PIMinto client library.
2. Confirm the PIMinto Category Operation and Permissions
Different catalog tasks require different API endpoints. You have to decide whether your application needs to discover the category hierarchy, modify category details, or retrieve the products assigned to a specific node. Each endpoint serves a distinct purpose in the product information lifecycle, and attempting to use a product listing route to manage taxonomy structures leads to permission errors or malformed payloads.
Use the documented PIMS Categories Management API route, POST /pim/manage/categories, to administer the catalog. This single endpoint handles the listCategories, addCategory, editCategory, and deleteCategory actions based on the payload you send.
The structure of the management request body determines the operation executed on the server. You pass an action string inside the JSON body, accompanied by the relevant parameters:
POST /pim/manage/categoriesContent-Type: application/json
Authorization: Bearer YOUR_API_KEY
{
"action": "listCategories"
}
Permissions dictate which actions succeed. While a Data Editor API key allows your integration to list categories, creating, editing, or deleting those categories requires elevated Data Manager permissions. Mutations always use the internal category ID rather than the human-readable display name, which means you need to check your response schema carefully, as the exact property paths depend on the specific management action you execute.
| Management action | Required API key permission | Primary payload parameters | Operational role |
|---|---|---|---|
listCategories | Data Editor | action | Retrieves the list of available categories for tree construction |
addCategory | Data Manager | action, name, parent_id (or path) | Creates a new category node under an existing parent |
editCategory | Data Manager | action, id, name, path | Updates category metadata or moves nodes in the hierarchy |
deleteCategory | Data Manager | action, id | Removes an empty category node using its internal numeric ID |
For product retrieval, PIMinto uses a different route, so avoid the management endpoint when your goal is displaying a product grid to a customer. The separation between the management endpoint and the data-viewer retrieval endpoint ensures that storefront read traffic remains isolated from administrative write operations, preserving system stability during high-volume catalog synchronization jobs.

3. Build a Reliable Category ID-to-Name Map
Storefronts and mobile applications run faster when they do not query category metadata on every single page load. You can retrieve the category tree once, build a local map, and use that index to translate internal IDs into display names. This approach cuts redundant network overhead, which keeps page generation fast and responsive during high-traffic catalog browsing sessions.
First, normalize the API response by creating a flat JavaScript Map where the key is the category ID, and the value is an object containing the display name and the parent path.
// Illustrative category mapping logicconst categoryIndex = new Map(
categories.map(category => [
category.id,
{
name: category.name,
path: category.path
}
])
);
// Retrieve the display name using the ID
const activeCategory = categoryIndex.get(42);
const headingText = activeCategory?.name ?? "All Products";
This map separates the operational identifier from the human-readable label. The id handles API routing and mutations, while the name appears in your navigation menus and page headings, and the path preserves the hierarchy context. When your application renders a category landing page, it can pull the exact heading text directly from the map using the URL slug or category ID without making another round-trip call to the API.
PIMinto enforces a duplicate-name restriction, but this rule is scoped to categories under the same parent. You could have a "Replacement Parts" category under "Pumps" and another "Replacement Parts" category under "Valves". Because names are not globally unique, your integration must rely on the ID for precise targeting and the path for context.
If your backend code relied on category strings to filter records, a query for "Replacement Parts" would create ambiguity, potentially mixing pump seals with valve gaskets. By indexing everything on the unique integer id, your application avoids taxonomy collisions while maintaining clear breadcrumbs for buyers.
// Example helper for constructing breadcrumbs from the category pathfunction buildBreadcrumbs(categoryId, categoryIndex) {
const category = categoryIndex.get(categoryId);
if (!category || !category.path) {
return [{ label: 'Home', url: '/' }];
}
const segments = category.path.split(' > ');
return segments.map((segment, index) => ({
label: segment,
url: `/catalog/${encodeURIComponent(segment.toLowerCase().replace(/\s+/g, '-'))}`
}));
}
Maintaining this hierarchy manually across spreadsheets causes inventory errors and broken navigation links. A centralized product data management software platform replaces those spreadsheets, allowing your application to rebuild its internal map automatically whenever a merchandising team renames or moves a category. Because the internal ID remains fixed even when merchandising teams adjust category titles, your storefront routing tables stay intact while customer-facing copy updates across your digital channels.
4. Retrieve Products Using the Category ID
Once you have the category ID, pass it to the product retrieval endpoint, documented by PIMinto as GET /v/pc/:categoryId. This operation returns active products associated with active categories.
Authenticate this request with a Data Viewer API key. Passing 0 as the category ID parameter tells the API to return a flattened list of products across all active categories, and you can add pagination parameters like pageSize and pageNum to control the response payload size.
// Illustrative product retrieval requestconst categoryId = 42;
const pageSize = 24;
const pageNum = 1;
const url = new URL(`https://api.piminto.com/v/pc/${categoryId}`);
url.searchParams.append('pageSize', pageSize);
url.searchParams.append('pageNum', pageNum);
// Append dynamic attribute filters if provided in the user request
url.searchParams.append('material', 'Stainless Steel');
url.searchParams.append('connection_type', 'Threaded');
const productResponse = await fetch(url, {
headers: {
'Authorization': `Bearer ${VIEWER_API_KEY}`,
'Accept': 'application/json'
}
});
if (!productResponse.ok) {
throw new Error(`Catalog request failed with status: ${productResponse.status}`);
}
const products = await productResponse.json();
You can narrow these results using query-string attribute filters, which PIMinto configures as cat_filters. The related product attribute must be filterable and cannot be a Collection attribute. Supplying multiple filters in a single request prompts the API to recalculate list or range values based on the product data assigned to that specific category, a process detailed in the official guide to getting a list of products in the specified category and filtering by specified attributes.
This dynamic recalculation is valuable for high-SKU catalogs. For example, if a user filters an industrial category by a specific housing material, the PIMinto endpoint recalculates the available range of compatible pressure ratings and connection sizes based solely on the remaining matching products. This prevents buyers from selecting dead-end filter combinations that return zero results.
When the response arrives, your application maps the technical product data to the UI, using the local category index you built earlier to display the correct page title. Combining the category name from your local map with the filtered product results produces a complete page state:
// Illustrative page-assembly helperfunction renderCategoryPage(categoryId, productPayload, categoryIndex) {
const categoryMeta = categoryIndex.get(categoryId);
return {
title: categoryMeta?.name ?? 'Catalog Overview',
breadcrumbs: categoryMeta?.path ?? 'Catalog',
totalItems: productPayload.totalCount ?? productPayload.products?.length ?? 0,
items: productPayload.products ?? []
};
}

5. Apply the Pattern to a Technical Catalog
Technical manufacturing catalogs frequently blur the line between a product category and a product attribute. The term "BoreFeature" illustrates this confusion.
Werk24 documents a Bore model for features extracted from technical drawings that represents a bore feature in an engineering or technical drawing.
Developers coming from engineering drawing pipelines or computer-aided manufacturing systems often carry over terminology from CAD or optical drawing extraction tools. In those systems, a "Bore" represents an internal circular profile or machined hole, complete with geometric tolerances and surface roughness values. When connecting CAD-extracted data to an e-commerce platform or B2B distributor portal, teams must decide whether "Bore Feature" constitutes a top-level classification category, a secondary subcategory, or a set of technical attributes attached to physical products like flanged sleeves or ball bearings.
Treat it as an illustrative data structure. If a manufacturer configures "Bore Features" as a product category, the API response might look like this JSON snippet:
{"id": 815,
"name": "Bore Features",
"path": "Industrial Components > Machining > Bore Features"
}
The integer 815 belongs in your product-list API request, while the string "Bore Features" targets the <h1> tag of your storefront, and the path "Industrial Components > Machining > Bore Features" supplies the breadcrumb navigation.
A specific measurement, such as a 50mm bore diameter, belongs as a filterable product attribute because storing measurements this way keeps your catalog taxonomy clean. This structure is valuable for PIM for manufacturers, where complex SKUs require strict separation between hierarchical groups and technical specifications. If you mistakenly created a unique category for every single bore diameter, your category tree would explode into thousands of unmanageable single-product folders. Grouping items under broader category nodes and filtering them by precise numeric attributes preserves a clean navigation tree while allowing granular parametric search.
{"sku": "SLV-815-50MM",
"title": "50mm Flanged Bushing Sleeve",
"category_id": 815,
"attributes": {
"bore_diameter": "50mm",
"outer_diameter": "62mm",
"tolerance_class": "H7",
"material": "Phosphor Bronze"
}
}
PIMinto provides the architecture to manage this complexity by combining a PIM and DAM environment that keeps category labels, technical attributes, specification sheets, and CAD files aligned. Connecting this data to external channels via native connectors ensures your partner networks receive accurate information without requiring manual exports. You can configure a PIM brand portal to share these assets securely, which lets you control exactly which product attributes and child categories remain visible to external vendors. The platform also includes an AI PIM Assistant to help enrich product descriptions before syncing them downstream, and its pricing model supports unlimited users and data outputs.
6. Troubleshoot and Maintain the Integration
API integrations fail in predictable ways when handling category data, but you can resolve most issues by checking the execution sequence and the data payloads. Building proactive error-handling routines into your integration layer keeps your application resilient when upstream catalog structures change.
Start by diagnosing JavaScript promise failures. If your application logs [object Promise] instead of a category name, you forgot the await keyword. If the code throws a TypeError: Cannot read properties of undefined (reading 'name'), you are targeting the wrong layer of the API response envelope. Logging the raw JSON payload to the console lets you adjust your property path to match the actual data structure.
// Robust category name resolver with defensive validationasync function safelyGetCategoryName(categoryId, fetchFunction) {
try {
const rawResponse = await fetchFunction(categoryId);
if (!rawResponse) {
console.warn(`Empty response received for category ID ${categoryId}`);
return 'General Products';
}
// Handle stringified payloads if the fetch transport did not auto-parse JSON
const parsedData = typeof rawResponse === 'string' ? JSON.parse(rawResponse) : rawResponse;
const categoryObject = parsedData.data?.category ?? parsedData.category ?? parsedData;
if (!categoryObject || typeof categoryObject !== 'object') {
console.warn(`Category data structure malformed for ID ${categoryId}`);
return 'General Products';
}
return categoryObject.name ?? 'Unnamed Category';
} catch (error) {
console.error(`Failed to resolve category name for ID ${categoryId}:`, error);
return 'General Products';
}
}
If you ignore HTTP status codes, permission errors can make mutations appear to fail silently. Because attempting to execute the editCategory action with a Data Viewer API key results in a rejection, you need a Data Manager key for any POST request that alters the catalog hierarchy. If your backend service performs both data ingestion and public storefront rendering, maintain separate API client instances with dedicated tokens to avoid accidental privilege escalation or unauthorized read failures.
Category renames fail if they violate the duplicate-name constraint, meaning the API rejects the request if you attempt to assign a value that already exists under the same parent node. Furthermore, if your edit payload includes a path parameter, the API ignores the name parameter entirely, so a new category name placed directly inside the path string will execute the rename operation instead. When performing programmatic batch updates across your catalog, always verify the parent node assignment to avoid submitting duplicate sibling labels.
// Illustrative safe edit category payload constructionfunction buildCategoryUpdatePayload(categoryId, desiredName, parentPath) {
// If supplying a path, embed the new name as the terminal segment
if (parentPath) {
const updatedPath = `${parentPath} > ${desiredName}`;
return {
action: "editCategory",
id: categoryId,
path: updatedPath
};
}
return {
action: "editCategory",
id: categoryId,
name: desiredName
};
}
Category deletions fail when the target node still contains child categories, requiring you to reassign or delete all nested children before the API allows you to remove the parent. If an automated script attempts to delete a parent branch directly, the API returns an error response. You must write a recursive cleanup routine that traverses the branch from the deepest leaf nodes upward to the parent node, or reassign those nested categories to a new parent ID before executing the deletion call.
Filtering failures occur when clients request invalid attribute types. If your product grid returns an unfiltered list despite appending query parameters, check the attribute configuration in the PIM to ensure the target attribute is marked as filterable and is not a Collection attribute. Collection attributes, which contain unstructured arrays or grouped multi-field assets, cannot be parsed by the category filter engine.
Finally, the product retrieval endpoint does not return inactive products or fully detailed category metadata because the GET /v/pc/:categoryId route serves only active products assigned to active categories. Auditing inactive items requires a dedicated product-management search route.
You can verify your completed integration with a short checklist. Start by logging the category ID, name, and path to confirm your local map built correctly. Next, rename a test category in your PIM workspace and check that the storefront updates its heading after the next sync. You should also test a mutation request using a read-only key to guarantee your application catches the permission error gracefully, before finally passing category ID 0 to retrieve products from all active categories.
| Verification step | Expected result | Common failure cause |
|---|---|---|
| Initialize ID Map | Map contains valid integer keys with display names and paths | Missing await or unparsed response envelope |
Category Query with ID 0 | Returns active products across all active categories | Using an inactive category ID or expired Data Viewer token |
| Apply Query Attribute Filter | Response recalculates ranges and matches filtered criteria | Filtering by a Collection attribute or non-filterable field |
| Execute Category Rename | Category title updates across breadcrumbs and headers | Sibling name collision under the same parent node |
| Delete Non-Empty Node | API rejects deletion request | Child subcategories still attached to the target parent ID |
Robust integrations rely on a clean, centralized data source. PIMinto gives growing e-commerce and B2B brands the tools to eliminate spreadsheet chaos through transparent pricing, free onboarding, and native connectors that push accurate category data directly to Shopify, Google Shopping, and custom applications.
Ready to stop fighting disorganized product data? Discover how PIMinto centralizes your categories, attributes, and digital assets into a single source of truth for all your sales channels.
Modified on: 2026-09-21