Skip to main content
Explore common integration scenarios and learn how to implement them using the ClearLine POS API. Each use case includes a business overview, technical approach, required endpoints, and working code examples.

🛒 Process POS Transaction → Trigger Loyalty

When a customer completes a purchase at the point of sale, automatically record the transaction and award loyalty points or trigger marketing actions based on their purchase behavior.
This workflow involves three key steps:
  1. Start Interaction - Initialize a POS session for the terminal
  2. Send Transaction - Submit transaction details with customer data, items, amounts, and payment info
  3. Handle Response - Process loyalty points awarded and any triggered campaigns
API Endpoints Used:
// Step 1: Start POS session
const interactionResponse = await fetch('https://public-api-demo.clearline.me/pos/clover/startInteraction', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    terminalId: "TERM-05",
    posLocationId: "LOC123"
  })
});

const { data } = await interactionResponse.json();
const sessionId = data.sessionId;

// Step 2: Send transaction with customer data
const transactionResponse = await fetch('https://public-api-demo.clearline.me/pos/clover/transaction', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    sessionId: sessionId,
    posLocationId: "LOC123",
    terminalId: "TERM-05",
    transactionId: "TXN-" + Date.now(),
    transactionAmount: 12.97,
    customer: {
      id: "CUST-001",
      firstName: "John",
      lastName: "Doe",
      contacts: [
        { type: "Email", value: "john.doe@example.com" },
        { type: "Phone", value: "+15555551234" }
      ]
    },
    products: [
      { 
        productId: "COFFEE-001", 
        productName: "Large Coffee", 
        price: 3.99, 
        quantity: 2,
        totalPrice: 7.98
      },
      { 
        productId: "MUFFIN-002", 
        productName: "Blueberry Muffin", 
        price: 4.99, 
        quantity: 1,
        totalPrice: 4.99
      }
    ]
  })
});

const result = await transactionResponse.json();
console.log('Transaction processed:', result);

// Check loyalty response
if (result.data.loyalty) {
  console.log('Loyalty points awarded:', result.data.loyalty);
}
Include customer contact information in the transaction request to enable loyalty tracking and marketing campaign triggers.

Learn More

View complete transaction API reference →

🎟️ Validate Coupon at Checkout

Enable cashiers to scan or enter coupon codes during checkout and validate them in real-time before applying discounts.
Workflow:
  1. Lookup Coupon - Search for a coupon by code
  2. Validate Coupon - Check coupon status and eligibility
  3. Apply Discount - Use coupon information to calculate discount in your POS
  4. Record Usage - Include coupon details in the transaction
API Endpoints Used:
The validate endpoint confirms the coupon exists and is active. Your POS system is responsible for applying business rules like minimum purchase amounts and calculating the actual discount.
// Step 1: Lookup coupon by code
const lookupResponse = await fetch('https://public-api-demo.clearline.me/v2/pos/clover/coupon/couponCodes/lookup', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    posLocationId: "LOC123",
    code: "SAVE20"
  })
});

const lookupResult = await lookupResponse.json();

if (!lookupResult.data?.couponCodes || lookupResult.data.couponCodes.length === 0) {
  console.error('Coupon not found');
  return;
}

const couponDetails = lookupResult.data.couponCodes[0];
console.log('Coupon found:', couponDetails);

// Step 2: Validate coupon
const validateResponse = await fetch('https://public-api-demo.clearline.me/v2/pos/clover/coupon/couponCodes/validate', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    posLocationId: "LOC123",
    code: "SAVE20",
    rewardProvider: "TwoReward" // Optional: specify reward provider
  })
});

const validation = await validateResponse.json();

if (validation.success) {
  console.log('Coupon is valid and can be applied');
  // Your POS calculates the discount based on coupon details
} else {
  console.error('Coupon validation failed');
}
These endpoints verify coupon existence and status. Your POS system must implement discount calculation logic based on the coupon details returned.

Learn More

View complete coupons API reference →

📺 Display Marketing Content with Widgets

Show interactive marketing content on customer-facing displays that customers can engage with to join loyalty programs, view offers, or receive digital receipts via QR code or SMS.
Workflow:
  1. List Widgets - Get available marketing actions for the location
  2. Start Widget Session - Launch a widget for customer interaction
  3. Show QR Code - Display QR code for mobile engagement
  4. Send Message - Deliver content via SMS/email
API Endpoints Used:Widget Types:
  • Loyalty enrollment
  • Promotion signup
  • Digital receipt delivery
  • Survey/feedback collection
// Step 1: Get available widgets
const widgetsResponse = await fetch('https://public-api-demo.clearline.me/v2/pos/clover/widget/list', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    posLocationId: "LOC123"
  })
});

const { data: widgets } = await widgetsResponse.json();
console.log('Available widgets:', widgets);

// Step 2: Start widget session
const startResponse = await fetch('https://public-api-demo.clearline.me/v2/pos/clover/widget/start', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    posLocationId: "LOC123",
    terminalId: "TERM-05",
    widgetId: widgets[0].id
  })
});

const { data: session } = await startResponse.json();

// Step 3: Show QR code
const qrResponse = await fetch('https://public-api-demo.clearline.me/v2/pos/clover/widget/showQrCode', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    sessionId: session.sessionId,
    posLocationId: "LOC123"
  })
});

const { data: qrData } = await qrResponse.json();
console.log('QR code URL:', qrData.qrCodeHtmlLinkUrl);
Widgets are configured in the ClearLine admin portal. The list endpoint returns only active widgets for your location.

Learn More

View complete widgets API reference →

🔄 Sync Product Catalog

Maintain an up-to-date product catalog in ClearLine by automatically syncing products, categories, and promotions from your POS or inventory management system on a scheduled basis.
Sync Strategies:
StrategyWhen to UsePerformance
Full SyncInitial setup, weekly refreshSlower, comprehensive
Incremental SyncDaily updates, changed items onlyFaster, efficient
On-Demand SyncImmediate updates for specific itemsFastest, targeted
API Endpoints Used:
  • POST /pos/{posSystemId}/company/{posCompanyId}/import/products - Import products
  • POST /pos/{posSystemId}/company/{posCompanyId}/import/productCategories - Import categories
  • POST /pos/{posSystemId}/company/{posCompanyId}/import/promotions - Import promotions
Data Requirements:
  • Product ID (unique identifier)
  • Product name
  • Price and category
  • Manufacturer (optional)
// Scheduled nightly sync
async function nightlyCatalogSync() {
  try {
    console.log('Starting nightly catalog sync...');
    
    // Fetch products from your POS system
    const posProducts = await fetchProductsFromPOS();
    
    // Transform to ClearLine format
    const products = posProducts.map(p => ({
      productId: p.itemId,
      productName: p.itemName,
      price: p.unitPrice,
      productCategoryId: p.categoryCode,
      manufacturer: p.manufacturer
    }));
    
    // Import products in batches
    const response = await fetch('https://public-api-demo.clearline.me/pos/clover/company/comp123/import/products', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        items: products
      })
    });
    
    const result = await response.json();
    console.log('Import result:', result);
    
  } catch (error) {
    console.error('Catalog sync failed:', error);
  }
}

// Run at 2 AM daily
// cron: 0 2 * * *
Optimization Tips:
  • Batch products in groups of 500-1000 for optimal performance
  • Schedule during off-peak hours (2-5 AM)
  • Implement retry logic with exponential backoff
  • Monitor sync completion and error rates

Learn More

View complete import API reference →

🔧 Error Recovery & Retry Logic

Build resilient POS integrations that gracefully handle network failures, API errors, and timeout scenarios without losing transaction data or frustrating customers.
Common Error Scenarios:
  • Network timeouts (slow connection)
  • 5xx server errors (temporary API issues)
  • 4xx client errors (invalid requests)
  • Authentication failures (expired tokens)
  • Rate limiting (too many requests)
Retry Strategies:
Error TypeRetry StrategyMax Retries
Network TimeoutExponential backoff3
5xx Server ErrorExponential backoff3
429 Rate LimitWait for Retry-After header2
401 UnauthorizedRefresh token once1
4xx Client ErrorNo retry (fix request)0
Best Practices:
  • Implement exponential backoff (1s, 2s, 4s, 8s…)
  • Log all retry attempts for debugging
  • Queue failed transactions for later submission
  • Display clear error messages to cashiers
  • Provide manual retry option in POS UI
// Robust API client with retry logic
class ClearLineAPIClient {
  constructor(accessToken) {
    this.accessToken = accessToken;
    this.baseUrl = 'https://public-api-demo.clearline.me';
    this.maxRetries = 3;
  }

  async makeRequest(endpoint, options, retryCount = 0) {
    try {
      const response = await fetch(`${this.baseUrl}${endpoint}`, {
        ...options,
        headers: {
          'Authorization': `Bearer ${this.accessToken}`,
          'Content-Type': 'application/json',
          ...options.headers
        },
        timeout: 30000 // 30 second timeout
      });

      // Handle rate limiting
      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || 5;
        console.log(`Rate limited. Retrying after ${retryAfter} seconds...`);

        if (retryCount < 2) {
          await this.sleep(retryAfter * 1000);
          return this.makeRequest(endpoint, options, retryCount + 1);
        }
      }

      // Handle authentication failures
      if (response.status === 401) {
        console.log('Access token expired. Refreshing...');
        await this.refreshAccessToken();
        return this.makeRequest(endpoint, options, retryCount + 1);
      }

      // Handle server errors with exponential backoff
      if (response.status >= 500 && retryCount < this.maxRetries) {
        const backoffTime = Math.pow(2, retryCount) * 1000; // 1s, 2s, 4s
        console.log(`Server error. Retrying in ${backoffTime}ms...`);

        await this.sleep(backoffTime);
        return this.makeRequest(endpoint, options, retryCount + 1);
      }

      // Handle client errors (4xx) - don't retry
      if (response.status >= 400 && response.status < 500) {
        const error = await response.json();
        throw new Error(`Client error: ${error.message || response.statusText}`);
      }

      return await response.json();

    } catch (error) {
      // Network/timeout errors
      if (error.name === 'AbortError' || error.message.includes('timeout')) {
        if (retryCount < this.maxRetries) {
          const backoffTime = Math.pow(2, retryCount) * 1000;
          await this.sleep(backoffTime);
          return this.makeRequest(endpoint, options, retryCount + 1);
        }
      }

      // Queue for later retry
      await this.queueFailedRequest(endpoint, options);
      throw error;
    }
  }

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  async queueFailedRequest(endpoint, options) {
    // Store in local database for later retry
    console.log('Request queued for later retry');
  }

  async refreshAccessToken() {
    // Implement token refresh logic
  }
}

// Usage
const client = new ClearLineAPIClient('YOUR_ACCESS_TOKEN');
await client.makeRequest('/pos/clover/transaction', {
  method: 'POST',
  body: JSON.stringify({ /* transaction data */ })
});
Monitoring & Alerting:
  • Track retry rates in your monitoring system
  • Alert on high failure rates (>5% of requests)
  • Monitor average retry count per request
  • Set up alerts for queue depth (>100 failed requests)

Learn More

View error handling best practices →

Next Steps

Quick Start Guide

Get started with your first API integration

API Reference

Explore all available endpoints and parameters

Authentication Guide

Learn how to authenticate with ClearLine API

POS Integration

Detailed guides for POS integration workflows