Skip to main content
Glama
inflow-client.js7.36 kB
// @ts-check /** * Inflow Inventory API Client * Handles all HTTP requests to the Inflow API */ import axios from 'axios'; export class InflowClient { /** * @param {Object} config * @param {string} config.apiKey - Inflow API key * @param {string} config.companyId - Inflow company ID * @param {string} [config.apiUrl] - Base API URL * @param {string} [config.apiVersion] - API version */ constructor(config) { this.config = config; this.apiUrl = config.apiUrl || 'https://cloudapi.inflowinventory.com'; this.apiVersion = config.apiVersion || '2025-06-24'; // Create axios instance with default config this.client = axios.create({ baseURL: this.apiUrl, headers: { 'Authorization': `Bearer ${config.apiKey}`, 'Content-Type': 'application/json', 'Accept': `application/json;version=${this.apiVersion}` } }); } /** * List all products with optional filters * @param {Object} [options] * @param {string} [options.name] - Filter by name * @param {string} [options.description] - Filter by description * @param {boolean} [options.isActive] - Filter by active status * @param {string} [options.barcode] - Filter by barcode * @param {string} [options.smart] - Full-text search on name, description, category, barcode, SKU * @param {string} [options.include] - Related entities to include (e.g., 'inventoryLines,defaultImage') * @param {number} [options.limit] - Max results to return * @returns {Promise<Object>} */ async listProducts(options = {}) { try { const params = new URLSearchParams(); // Add filters if (options.name) params.append('filter[name]', options.name); if (options.description) params.append('filter[description]', options.description); if (options.isActive !== undefined) params.append('filter[isActive]', options.isActive.toString()); if (options.barcode) params.append('filter[barcode]', options.barcode); if (options.smart) params.append('filter[smart]', options.smart); // Add includes if (options.include) params.append('include', options.include); // Add limit if (options.limit) params.append('limit', options.limit.toString()); const response = await this.client.get( `/${this.config.companyId}/products?${params.toString()}` ); return { success: true, data: response.data }; } catch (error) { return this._handleError(error, 'listProducts'); } } /** * Get a specific product by ID * @param {string} productId * @param {string} [include] - Related entities to include * @returns {Promise<Object>} */ async getProduct(productId, include = null) { try { const params = include ? `?include=${include}` : ''; const response = await this.client.get( `/${this.config.companyId}/products/${productId}${params}` ); return { success: true, data: response.data }; } catch (error) { return this._handleError(error, 'getProduct'); } } /** * Get product inventory summary * @param {string} productId * @returns {Promise<Object>} */ async getProductSummary(productId) { try { const response = await this.client.get( `/${this.config.companyId}/products/${productId}/summary` ); return { success: true, data: response.data }; } catch (error) { return this._handleError(error, 'getProductSummary'); } } /** * Create or update a product * @param {Object} product - Product object with productId * @returns {Promise<Object>} */ async upsertProduct(product) { try { if (!product.productId) { return { success: false, error: 'productId is required for upsert' }; } const response = await this.client.put( `/${this.config.companyId}/products`, product ); return { success: true, data: response.data }; } catch (error) { return this._handleError(error, 'upsertProduct'); } } /** * List stock adjustments with optional filters * @param {Object} [options] * @param {string} [options.adjustmentNumber] - Filter by adjustment number * @param {string} [options.include] - Related entities to include * @param {number} [options.limit] - Max results to return * @returns {Promise<Object>} */ async listStockAdjustments(options = {}) { try { const params = new URLSearchParams(); if (options.adjustmentNumber) params.append('filter[adjustmentNumber]', options.adjustmentNumber); if (options.include) params.append('include', options.include); if (options.limit) params.append('limit', options.limit.toString()); const response = await this.client.get( `/${this.config.companyId}/stock-adjustments?${params.toString()}` ); return { success: true, data: response.data }; } catch (error) { return this._handleError(error, 'listStockAdjustments'); } } /** * Get a specific stock adjustment by ID * @param {string} stockAdjustmentId * @param {string} [include] - Related entities to include * @returns {Promise<Object>} */ async getStockAdjustment(stockAdjustmentId, include = null) { try { const params = include ? `?include=${include}` : ''; const response = await this.client.get( `/${this.config.companyId}/stock-adjustments/${stockAdjustmentId}${params}` ); return { success: true, data: response.data }; } catch (error) { return this._handleError(error, 'getStockAdjustment'); } } /** * Create or update a stock adjustment * @param {Object} stockAdjustment - Stock adjustment object with stockAdjustmentId * @returns {Promise<Object>} */ async upsertStockAdjustment(stockAdjustment) { try { if (!stockAdjustment.stockAdjustmentId) { return { success: false, error: 'stockAdjustmentId is required for upsert' }; } const response = await this.client.put( `/${this.config.companyId}/stock-adjustments`, stockAdjustment ); return { success: true, data: response.data }; } catch (error) { return this._handleError(error, 'upsertStockAdjustment'); } } /** * Handle API errors * @private */ _handleError(error, operation) { console.error(`Inflow API Error (${operation}):`, error.message); if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx return { success: false, error: error.response.data?.message || error.message, status: error.response.status, details: error.response.data }; } else if (error.request) { // The request was made but no response was received return { success: false, error: 'No response received from Inflow API', details: error.message }; } else { // Something happened in setting up the request return { success: false, error: error.message }; } } }

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/intelligent-staffing-systems/mcp-inflow-ingredients'

If you have feedback or need assistance with the MCP directory API, please join our Discord server