Developer Tutorials

Bluestone API Integration Tutorial: Complete Developer Guide with TypeScript

Published January 15, 2025
20 min read
Bluestone
API
TypeScript
Tutorial
Integration
MACH
Authentication

What You'll Learn

This tutorial guides you through integrating with the Bluestone PIM API, from initial authentication to advanced product search functionality. You'll build a complete TypeScript application that demonstrates real-world API usage patterns.

Bluestone's MACH-certified API architecture provides powerful search capabilities through Elasticsearch, comprehensive authentication via MAPI credentials, and flexible data access patterns. This tutorial covers both the successful integration patterns and the permission-based limitations you may encounter.

Tutorial Outcomes

  • Authenticate with Bluestone MAPI credentials
  • Set up TypeScript project with auto-generated SDK
  • Implement product search using Elasticsearch API
  • Handle authentication tokens and automatic renewal
  • Build reusable API client patterns
  • Understand API permissions and access levels

Prerequisites

Required Credentials

Before starting, ensure you have access to a Bluestone PIM test environment with the following credentials:

MAPI Credentials Required

  • Organization name (e.g., 'SANDBOX - POC')
  • Environment designation (TEST/PRODUCTION)
  • PAPI-key for API access
  • MAPI Client ID for OAuth2 authentication
  • MAPI Client Secret for secure token generation

Development Environment

  • Node.js 16+ with npm/yarn
  • TypeScript development setup
  • Code editor with TypeScript support
  • Basic understanding of REST APIs and OAuth2
  • Familiarity with async/await patterns

Getting Started

Step 1: Initialize Your Project

Create a new Node.js project and install the necessary dependencies for TypeScript development and Bluestone API integration.

Project Initialization

Set up a new TypeScript project with required dependencies

bash
# Initialize new Node.js project
npm init -y

# Install Bluestone SDK using the official generator
npx api install "@docs-api-test-bspim/v1-core#dzoga1clxllapfw" --yes

# Install TypeScript development dependencies
npm install -D typescript @types/node ts-node

# Create TypeScript configuration
echo '{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020", "DOM"],
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "baseUrl": "."
  },
  "include": ["src/**/*", ".api/**/*"],
  "exclude": ["node_modules", "dist"]
}' > tsconfig.json

# Create source directory
mkdir src
Sivert Kjøller Bertelsen
"While this tutorial focuses on TypeScript implementation, Bluestone's API reference provides comprehensive examples across 20+ programming languages including C#/.NET, Python, Java, PHP, Ruby, and Go. The core authentication and API patterns remain consistent regardless of your chosen language."
Sivert Kjøller Bertelsen, API Integration Specialist

Step 2: Implement Authentication

Bluestone uses OAuth2 client credentials flow for API authentication. The MAPI credentials generate bearer tokens that expire after 3600 seconds (1 hour).

Understanding Bluestone Authentication

The authentication process involves posting your client credentials to the identity provider endpoint to receive a bearer token. This token must be included in all subsequent API requests as an Authorization header.

Authentication Implementation

Complete authentication module with credential management and token handling

typescript
import docsApiTestBspim from '../.api/apis/docs-api-test-bspim';

// Bluestone API Credentials
const CREDENTIALS = {
  // Replace with your actual credentials
  clientId: 'your-client-id-here',
  clientSecret: 'your-client-secret-here',
  grantType: 'client_credentials'
};

async function authenticateWithBluestoneAPI() {
  try {
    console.log('🔐 Authenticating with Bluestone API...');
    console.log('📍 Organization: Your Organization');
    console.log('🌍 Environment: TEST');
    
    // Generate token using MAPI credentials
    const response = await docsApiTestBspim.generateToken({
      client_id: CREDENTIALS.clientId,
      client_secret: CREDENTIALS.clientSecret,
      grant_type: CREDENTIALS.grantType
    });

    console.log('✅ Authentication successful!');
    
    if (response.data && response.data.access_token) {
      console.log('🎟️  Access Token obtained');
      console.log('⏱️  Expires in:', response.data.expires_in, 'seconds');
      console.log('🏷️  Token Type:', response.data.token_type);
      
      return {
        accessToken: response.data.access_token,
        expiresIn: response.data.expires_in,
        tokenType: response.data.token_type
      };
    }
    
  } catch (error) {
    console.error('❌ Authentication failed:', error);
    throw error;
  }
}

export default authenticateWithBluestoneAPI;
export { CREDENTIALS };

Step 3: Build API Client with Token Management

Create a reusable API client that handles authentication, token validation, and automatic renewal. This pattern ensures your application maintains valid authentication throughout its lifecycle.

Key Features

The API client implements automatic token validation, handles expired tokens by re-authenticating, and provides a clean interface for making authenticated requests to different Bluestone API endpoints.

API Client with Token Management

Reusable API client that handles authentication and token lifecycle

typescript
import docsApiTestBspim from '../.api/apis/docs-api-test-bspim';
import authenticateWithBluestoneAPI from './authenticate';

interface AuthenticatedApiClient {
  accessToken: string;
  expiresIn: number;
  tokenType: string;
  authenticatedAt: Date;
}

class BluestoneApiClient {
  private client: AuthenticatedApiClient | null = null;

  async initialize(): Promise<void> {
    console.log('🚀 Initializing Bluestone API Client...');
    
    const authInfo = await authenticateWithBluestoneAPI();
    
    if (authInfo && authInfo.accessToken && authInfo.expiresIn && authInfo.tokenType) {
      this.client = {
        accessToken: authInfo.accessToken,
        expiresIn: authInfo.expiresIn,
        tokenType: authInfo.tokenType,
        authenticatedAt: new Date()
      };
      
      // Configure the SDK with the bearer token
      docsApiTestBspim.auth(authInfo.accessToken);
      
      console.log('✅ API Client initialized and authenticated!');
    } else {
      throw new Error('Failed to authenticate with Bluestone API');
    }
  }

  isTokenValid(): boolean {
    if (!this.client) return false;
    
    const now = new Date();
    const elapsed = (now.getTime() - this.client.authenticatedAt.getTime()) / 1000;
    const isValid = elapsed < this.client.expiresIn;
    
    if (!isValid) {
      console.log('⚠️  Token has expired, re-authentication required');
    }
    
    return isValid;
  }

  getTokenInfo(): AuthenticatedApiClient | null {
    return this.client;
  }

  displayStatus(): void {
    if (!this.client) {
      console.log('❌ API Client not initialized');
      return;
    }

    const now = new Date();
    const elapsed = (now.getTime() - this.client.authenticatedAt.getTime()) / 1000;
    const remaining = this.client.expiresIn - elapsed;

    console.log('\n📊 Bluestone API Client Status:');
    console.log(`🔑 Token Type: ${this.client.tokenType}`);
    console.log(`⏰ Authenticated at: ${this.client.authenticatedAt.toISOString()}`);
    console.log(`⏱️  Time remaining: ${Math.max(0, Math.floor(remaining))} seconds`);
    console.log(`✅ Token valid: ${this.isTokenValid() ? 'Yes' : 'No'}`);
  }
}

export default BluestoneApiClient;

Step 4: Implement Product Search

Bluestone provides powerful product search capabilities through Elasticsearch. The search API supports complex queries, filtering, sorting, and pagination - essential for building robust PIM integrations.

Understanding Bluestone API Endpoints

Based on real-world testing, different API endpoints have varying permission requirements. The Elasticsearch search endpoint typically has broader access than detailed product management endpoints.

Product Search Implementation

Complete product search client with Elasticsearch support

typescript
import BluestoneApiClient from './api-client';

// Bluestone API URLs for different services
const API_ENDPOINTS = {
  MANAGEMENT_API: 'https://api.test.bluestonepim.com',
  SEARCH_API: 'https://api.test.bluestonepim.com/search'
};

interface ElasticsearchQuery {
  query?: any;
  size?: number;
  from?: number;
  sort?: any[];
}

class ProductSearchClient extends BluestoneApiClient {
  
  /**
   * Search for products using Elasticsearch query
   */
  async searchProductsElasticsearch(elasticsearchQuery: ElasticsearchQuery): Promise<any> {
    await this.ensureAuthenticated();
    
    console.log('🔍 Searching products with Elasticsearch query:', elasticsearchQuery);

    try {
      const response = await this.makeAuthenticatedAPIRequest(
        `${API_ENDPOINTS.SEARCH_API}/products/search`,
        'POST',
        elasticsearchQuery
      );
      
      console.log('✅ Elasticsearch product search successful!');
      return response;
      
    } catch (error) {
      console.error('❌ Elasticsearch product search failed:', error);
      throw error;
    }
  }

  /**
   * Ensure we have a valid authentication token
   */
  protected async ensureAuthenticated(): Promise<void> {
    if (!this.isTokenValid()) {
      console.log('🔄 Re-authenticating...');
      await this.initialize();
    }
  }

  /**
   * Make an authenticated HTTP request to the Bluestone API
   */
  protected async makeAuthenticatedAPIRequest(
    url: string, 
    method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET',
    body?: any
  ): Promise<any> {
    const tokenInfo = this.getTokenInfo();
    
    if (!tokenInfo) {
      throw new Error('No authentication token available');
    }

    const headers: Record<string, string> = {
      'Authorization': `${tokenInfo.tokenType} ${tokenInfo.accessToken}`,
      'Content-Type': 'application/json'
    };

    const requestOptions: RequestInit = {
      method,
      headers
    };

    if (body && (method === 'POST' || method === 'PUT')) {
      requestOptions.body = JSON.stringify(body);
    }

    console.log(`📡 Making ${method} request to: ${url}`);
    
    const response = await fetch(url, requestOptions);
    
    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`HTTP ${response.status}: ${errorText}`);
    }

    return await response.json();
  }
}

export default ProductSearchClient;

Step 5: Practical Usage Examples

Now that you have the core components, let's explore practical examples of using the Bluestone API for common integration scenarios.

Complete Usage Examples

Practical examples showing different search patterns and query types

typescript
import ProductSearchClient from './product-search';

async function demonstrateBluestoneAPI() {
  const client = new ProductSearchClient();
  
  try {
    // Initialize and authenticate
    console.log('🚀 Initializing Bluestone API Client...');
    await client.initialize();
    
    // Example 1: Basic search for all products
    console.log('\n1️⃣ Basic Product Search (Match All)');
    const allProducts = await client.searchProductsElasticsearch({
      query: { match_all: {} },
      size: 10
    });
    
    if (allProducts && allProducts.data) {
      console.log(`✅ Found ${allProducts.data.length} products:`);
      allProducts.data.forEach((product: any, index: number) => {
        console.log(`   ${index + 1}. ID: ${product.id}`);
      });
    }
    
    // Example 2: Advanced boolean query with filters
    console.log('\n2️⃣ Advanced Boolean Query');
    const advancedResults = await client.searchProductsElasticsearch({
      query: {
        bool: {
          must: [
            { exists: { field: "id" } }
          ]
        }
      },
      size: 5,
      sort: [{ "_id": { "order": "desc" } }]
    });
    
    console.log(`✅ Advanced query returned ${advancedResults.data?.length || 0} products`);
    
    // Example 3: Pagination example
    console.log('\n3️⃣ Pagination Example');
    const paginatedResults = await client.searchProductsElasticsearch({
      query: { match_all: {} },
      size: 2,
      from: 0  // Start from first result
    });
    
    console.log(`📄 Page 1: ${paginatedResults.data?.length || 0} products`);
    
    // Show authentication status
    client.displayStatus();
    
  } catch (error) {
    console.error('💥 API demonstration failed:', error);
  }
}

// Run the demonstration
if (require.main === module) {
  demonstrateBluestoneAPI();
}

Package.json Scripts

Convenient npm scripts for development and testing

json
{
  "name": "bluestone-api-integration",
  "version": "1.0.0",
  "scripts": {
    "build": "tsc",
    "authenticate": "ts-node src/authenticate.ts",
    "search": "ts-node src/product-search.ts",
    "demo": "ts-node src/demo.ts",
    "dev": "ts-node src/demo.ts"
  },
  "dependencies": {
    "@api/docs-api-test-bspim": "file:.api/apis/docs-api-test-bspim"
  },
  "devDependencies": {
    "@types/node": "^22.15.29",
    "ts-node": "^10.9.2",
    "typescript": "^5.8.3"
  }
}

Step 6: Running Your Integration

With your code in place, you can now test different aspects of the Bluestone API integration using convenient npm scripts.

Available Commands

  • `npm run authenticate` - Test basic authentication
  • `npm run search` - Run product search examples
  • `npm run demo` - Full demonstration with multiple examples
  • `npm run build` - Compile TypeScript to JavaScript
  • `npm run dev` - Development mode with auto-restart

Expected Results

When your integration is working correctly, you should see output similar to this example, demonstrating successful authentication and product discovery.

Expected Console Output

Example of successful API integration results

bash
🚀 Initializing Bluestone API Client...
🔐 Authenticating with Bluestone API...
📍 Organization: SANDBOX - POC
🌍 Environment: TEST
✅ Authentication successful!
🎟️  Access Token obtained
⏱️  Expires in: 3600 seconds
🏷️  Token Type: Bearer
✅ API Client initialized and authenticated!

1️⃣ Basic Product Search (Match All)
🔍 Searching products with Elasticsearch query: { query: { match_all: {} }, size: 10 }
📡 Making POST request to: https://api.test.bluestonepim.com/search/products/search
✅ Elasticsearch product search successful!
✅ Found 6 products:
   1. ID: 67f3c4e7bb442e4f88e45c32
   2. ID: 67f3c4a810f2da33a7c88766
   3. ID: 67f3c47c36016948acd8d0dd
   4. ID: 67f3ba1cbb442e4f88e45958
   5. ID: 67f3a654bb442e4f88e4590d
   6. ID: 67f3a5d636016948acd8cc4b

2️⃣ Advanced Boolean Query
✅ Advanced query returned 6 products

📊 Bluestone API Client Status:
🔑 Token Type: Bearer
⏰ Authenticated at: 2025-01-15T12:06:07.957Z
⏱️  Time remaining: 3599 seconds
✅ Token valid: Yes

Advanced Elasticsearch Queries

Bluestone's search API supports the full Elasticsearch Query DSL, enabling sophisticated product discovery patterns. Here are common query patterns for PIM integrations.

Advanced Elasticsearch Query Examples

Common query patterns for product search and filtering

typescript
// Example query patterns for different use cases

// 1. Match all products (basic listing)
const matchAllQuery = {
  query: { match_all: {} },
  size: 20,
  from: 0
};

// 2. Boolean query with existence filter
const existenceQuery = {
  query: {
    bool: {
      must: [
        { exists: { field: "id" } },
        { exists: { field: "name" } }
      ]
    }
  },
  size: 10
};

// 3. Sorting and pagination
const sortedQuery = {
  query: { match_all: {} },
  size: 5,
  from: 0,
  sort: [
    { "_id": { "order": "desc" } },
    { "createdAt": { "order": "desc" } }
  ]
};

// 4. Term filtering (when you know specific values)
const termQuery = {
  query: {
    bool: {
      must: [
        { term: { "status": "active" } },
        { term: { "type": "product" } }
      ]
    }
  }
};

// 5. Range queries (for dates, numbers)
const rangeQuery = {
  query: {
    bool: {
      must: [
        {
          range: {
            "createdAt": {
              "gte": "2024-01-01",
              "lte": "2024-12-31"
            }
          }
        }
      ]
    }
  }
};

// Usage example:
// const results = await client.searchProductsElasticsearch(matchAllQuery);

Troubleshooting Common Issues

Authentication Failures

If authentication fails, verify your MAPI credentials are correct and that your organization has API access enabled. The client ID and secret must exactly match what's provided by Bluestone support.

403 Forbidden Errors

Some API endpoints require higher permission levels than others. The search endpoints typically work with basic MAPI credentials, while product management endpoints may require additional permissions. This is by design for security.

Token Expiration

Bearer tokens expire after 3600 seconds. The API client automatically handles token renewal, but if you're implementing custom logic, ensure you check token validity before making requests.

Network Connectivity

Ensure your development environment can reach the Bluestone test endpoints. Some corporate networks may block external API access.

Common Error Codes

  • 401 Unauthorized - Invalid or expired credentials
  • 403 Forbidden - Insufficient permissions for endpoint
  • 404 Not Found - Invalid endpoint URL or resource not found
  • 429 Rate Limited - Too many requests (default: 500/minute)
  • 500 Internal Server Error - Bluestone service issue

Integration Best Practices

Error Handling

Always implement proper error handling for API calls. Network issues, rate limiting, and permission changes can occur in production environments.

Token Management

Store tokens securely and implement automatic renewal. Never log bearer tokens in production environments as they provide full API access.

Rate Limiting

Respect Bluestone's rate limits (default 500 requests/minute). Implement exponential backoff for rate-limited requests and consider caching responses when appropriate.

Environment Management

Use environment variables for credentials and API endpoints. Never commit API keys to version control.

Monitoring

Implement logging and monitoring for API integrations. Track authentication success rates, response times, and error frequencies.

Production Considerations

  • Use environment variables for sensitive credentials
  • Implement proper logging without exposing tokens
  • Add retry logic with exponential backoff
  • Monitor API usage and error rates
  • Cache responses when appropriate to reduce API calls
  • Use HTTPS for all API communication

Ready for Production?

This tutorial covers the fundamentals of Bluestone API integration. For production implementations, consider implementing advanced features like webhook handling, bulk operations, and comprehensive error recovery.

Learn About Bluestone PIM

Next Steps

Extend Your Integration

With the foundation in place, you can extend your integration to include additional Bluestone API capabilities as your permissions allow.

Integration Extensions

  • Implement webhook handlers for real-time data sync
  • Add support for bulk product operations
  • Integrate with Bluestone's workflow and task APIs
  • Build asset management functionality using the DAM API
  • Add support for category and attribute management
  • Implement data export and synchronization workflows

Production Readiness

  • Set up proper environment configuration
  • Implement comprehensive error handling and retry logic
  • Add monitoring and alerting for API failures
  • Create automated tests for your integration
  • Document your API usage patterns for team knowledge
  • Plan for scaling and rate limit management

Sources (1)

[1]
Bluestone API Reference
Bluestone(2025)API Documentation

Related Articles

Comprehensive technical review of Bluestone PIM system including MACH architecture, micro-services approach, and real-world implementation insights.

Jan 15, 2025
Read
Bluestone
MACH
+4

Complete guide to Product Information Management systems. Learn what PIM is, how it works, key benefits, and how to choose the right PIM system for your business.

Jan 15, 2025
Read
PIM
Product Information
+3

About This Article

Category: Developer Tutorials

Review Status: Published

Related PIM Systems: bluestone

Related Articles: 3 related articles available

Sivert Kjøller Bertelsen

Ready to Transform Your Product Data Management?

Let's discuss how Impact Commerce can help you achieve your digital commerce goals.