Skip to main content

Yext Integration

🎯 Overview

The Yext integration enables DashClicks to manage business listings across 150+ directories and publisher platforms (Google, Facebook, Yelp, etc.) through Yext's Business Listings API. It provides entity creation, listing optimization, publisher management, and duplicate listing scan capabilities.

Provider: Yext (https://www.yext.com)
API Version: v2
API Versioning: Uses v parameter (default: 20200525)
Integration Type: REST API with API Key authentication

📁 Directory Structure

Documentation Structure:

yext/
├── 📄 index.md - Yext integration overview and setup
├── 📄 entities.md - Business entity management (CRUD operations)
├── 📄 account.md - Account verification and listing initialization
├── 📄 categories.md - Business category management
├── 📄 publishers.md - Publisher directory listing
├── 📄 optimization.md - Listing optimization tasks and links
└── 📄 scan.md - Duplicate listing detection and monitoring

Source Code Location:

  • Base Path: external/Integrations/Yext/
  • Services: services/ (6 service files)
  • Controllers: Controllers/
  • Models: external/models/ (yext-specific)

🗄️ MongoDB Collections

📚 Detailed Schema: See Database Collections Documentation

account

  • Purpose: Store Yext entity ID for DashClicks accounts
  • Model: external/models/account.js
  • Primary Use: Link DashClicks accounts to Yext business entities
  • Key Fields:
    • yext.entity - Yext entity ID (location ID)
    • yext_status - Yext service activation status
  • Purpose: Store publisher directory logos
  • Model: external/models/yext-publishers-logo.js
  • Primary Use: Display publisher logos in listing reports
  • Key Fields:
    • publisherId - Publisher ID from Yext
    • logo - Logo image URL

yext-scans

  • Purpose: Store duplicate listing scan results
  • Model: external/models/yext-scans.js
  • Primary Use: Cache scan data and monitor duplicate listings
  • Key Fields:
    • account_id - DashClicks account ID
    • scan_data.jobId - Yext scan job ID
    • scan_data.sites - Array of detected listings
    • business_info - Business data used for scan
  • TTL: Documents expire automatically (expiresAt field)

🔐 Authentication & Configuration

Authentication Method: API Key (Header-based)

Required Environment Variables:

VariableDescriptionRequired
YEXT_API_KEYSPrimary Yext API key
YEXT_API_KEY_SCANDedicated API key for scan service
YEXT_API_VPARAMAPI version parameter (default: 20200525)

Authentication Pattern:

// All API requests include api-key header
headers: {
'api-key': process.env.YEXT_API_KEYS
}

API Versioning:

All Yext API endpoints require a v query parameter for versioning:

const v = process.env.YEXT_API_VPARAM || '20200525';

// Example request
axios({
url: 'https://api.yext.com/v2/accounts/me/entities',
params: { v: v },
headers: { 'api-key': process.env.YEXT_API_KEYS },
});

🏗️ Architecture Overview

Key Responsibilities:

  • Entity Management: Create, update, delete business entities (locations)
  • Listing Distribution: Activate listings to 150+ publisher directories
  • Optimization: Manage listing optimization tasks for better visibility
  • Duplicate Detection: Scan for duplicate listings across the web
  • Publisher Management: List available publisher directories
  • Category Management: Manage business category classifications
  • Analytics: Generate reports on listing performance

API Communication Pattern:

  • REST API with JSON requests/responses
  • Header-based API key authentication
  • Query parameter API versioning (v=20200525)
  • Synchronous request/response for most operations
  • Asynchronous job-based processing for scans

Rate Limiting:

  • Yext enforces rate limits per API key (specific limits not documented in code)
  • No explicit rate limiting handling implemented
  • Recommendation: Implement retry logic with exponential backoff

Business Logic Flow:

graph TB
A[DashClicks Account] -->|Create Entity| B[Yext Entity/Location]
B -->|Save entity ID| C[account.yext.entity]
B -->|Activate Service| D[SKU: LC-00000019]
D -->|Distribute to| E[150+ Publishers]
E -->|Google, Facebook, Yelp, etc| F[Live Listings]
F -->|Monitor| G[Optimization Tasks]
F -->|Detect Duplicates| H[Yext Scan Service]

🔗 Features & Capabilities

Core Features

  • 📘 Entities - CRUD operations for business entities/locations
  • 📗 Account - Account verification and entity initialization
  • 📙 Categories - Business category listing
  • 📕 Publishers - Publisher directory management
  • 📓 Optimization - Listing optimization tasks and links
  • 📔 Scan - Duplicate listing detection

🔄 Integration Data Flow

Entity Creation and Activation

sequenceDiagram
participant DC as DashClicks API
participant YextService as Yext Service
participant AccountDB as Account Collection
participant YextAPI as Yext API

DC->>YextService: Create entity (business data)
YextService->>AccountDB: Check existing entity
AccountDB-->>YextService: No entity found

YextService->>YextAPI: POST /entities
Note over YextService,YextAPI: Headers: api-key<br/>Body: Business info
YextAPI-->>YextService: Entity created (meta.id)

YextService->>AccountDB: Save entity ID
Note over AccountDB: account.yext.entity = entityId

YextService->>YextAPI: POST /existinglocationaddrequests
Note over YextService,YextAPI: Activate SKU: LC-00000019
YextAPI-->>YextService: Service activated

YextService-->>DC: Entity created and activated

style YextService fill:#e3f2fd
style YextAPI fill:#fff4e6

Listing Scan Flow

sequenceDiagram
participant DC as DashClicks API
participant ScanService as Scan Service
participant ScanDB as YextScan Collection
participant YextAPI as Yext Scan API

DC->>ScanService: Get scan results
ScanService->>ScanDB: Find existing scan

alt Scan exists
ScanDB-->>ScanService: Return cached jobId
ScanService->>YextAPI: GET /scan/:jobId/:sites
YextAPI-->>ScanService: Scan results
ScanService->>ScanDB: Update cached results
else No scan or expired
ScanService->>YextAPI: POST /scan (create new)
YextAPI-->>ScanService: jobId + sites
ScanService->>YextAPI: GET /scan/:jobId/:sites
YextAPI-->>ScanService: Scan results
ScanService->>ScanDB: Cache new scan
end

ScanService-->>DC: Return scan results with logos

style ScanService fill:#e3f2fd
style YextAPI fill:#fff4e6

🔗 Submodules

🚨 Error Handling

Common Error Scenarios:

  1. Entity Not Initialized

    • Error: "Listings not initialized for this account."
    • Cause: Account doesn't have yext.entity field
    • Solution: Create entity first using entities service
  2. Entity ID Mismatch

    • Error: "Entity Id mismatch!"
    • Cause: Provided entity ID doesn't match account's stored entity
    • Solution: Verify entity ownership before operations
  3. Invalid API Key

    • Status: 401 Unauthorized
    • Cause: Missing or invalid YEXT_API_KEYS
    • Solution: Check environment variables
  4. Optimization Not Eligible

    • Error: "User not eligible for the optimization task(s)."
    • Cause: Entity doesn't have active optimization tasks
    • Solution: Check entity status and active services

📊 Monitoring & Logging

  • Scan Service: Uses logger utility for error tracking
  • Error Logging: Errors logged with context (initiator, error, message)
  • No Metrics: No explicit metrics collection implemented

⚠️ Important Integration Notes

  1. API Versioning: All requests must include v parameter (default: 20200525)
  2. Service Activation: After entity creation, must activate with SKU: LC-00000019
  3. Entity Verification: All operations verify entity ID matches account before proceeding
  4. Separate API Keys: Scan service uses dedicated API key (YEXT_API_KEY_SCAN)
  5. Scan Caching: Scan results cached in MongoDB with TTL expiration
  6. Publisher Logos: Logos stored separately and joined to listing data
  7. Account Dependency: Most operations require account to have yext.entity set
  8. No Rate Limiting: No explicit rate limit handling - relies on Yext's limits
  9. Error Handling: Account/entity errors return structured error objects
  10. Optimization Links: Redirect URL required for optimization task links

🔧 Quick Start Examples

Create and Activate Entity

// 1. Create entity
const entity = await entitiesService.create({
accountId: '507f1f77bcf86cd799439011',
body: {
name: 'My Business',
address: {
line1: '123 Main St',
city: 'New York',
region: 'NY',
postalCode: '10001',
},
phone: '+1-555-0100',
},
query: { v: '20200525' },
});

// Entity automatically:
// - Saved to account.yext.entity
// - Activated with SKU LC-00000019

Get Listing Status

// Check if account has entity
const entityId = await accountService.find(accountId);

if (entityId.error) {
console.log('Listings not initialized');
} else {
// Get listings by location
const listings = await entitiesService.listListingsByLocation({
accountId: accountId,
params: { entityId: entityId, v: '20200525' },
});
}

Scan for Duplicates

// Scan for duplicate listings
const scan = await scanService.getScan(accountId, {
name: 'My Business',
address: '123 Main St, New York, NY 10001',
phone: '+1-555-0100',
});

console.log('Scan Job ID:', scan.scan_data.jobId);
console.log('Detected Listings:', scan.scan_data.sites.length);
💬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:31 AM