Synoveo SDK

Synoveo SDK

Official TypeScript SDK for the Synoveo API

The official @synoveo/sdk package provides a type-safe client for the Synoveo API with automatic token management, retry logic, and error handling.

Installation

npm install @synoveo/sdk

Quick Start

import { SynoveoClient } from '@synoveo/sdk'

const client = new SynoveoClient({
  clientId: 'your_client_id',
  clientSecret: 'your_client_secret',
})

// List locations
const { locations } = await client.locations.list()

// Get profile
const profile = await client.profile.getProfile('locations/123')

// Create a post
const post = await client.posts.create('locations/123', {
  summary: 'Hello from Synoveo!',
  topicType: 'STANDARD',
})

Configuration

const client = new SynoveoClient({
  // Required
  clientId: 'your_client_id',
  clientSecret: 'your_client_secret',

  // Optional
  baseUrl: 'https://api.synoveo.com',  // Custom API URL
  timeout: 30000,                       // Request timeout (ms)
  tokenRefreshBuffer: 300,              // Refresh token 5 min before expiry

  // Retry configuration
  retry: {
    maxRetries: 3,
    baseDelay: 1000,
    maxDelay: 30000,
    retryOn: [429, 500, 502, 503, 504],
  },

  // Logging
  logger: console,    // Custom logger or false to disable
  logLevel: 'info',   // 'debug' | 'info' | 'warn' | 'error'

  // Hooks
  hooks: {
    onTokenRefresh: (token) => console.log('Token refreshed'),
    onQuotaUpdate: (quota) => console.log(`Used: ${quota.used}/${quota.limit}`),
    onError: (error) => console.error('API error:', error.code),
  },
})

Services

Locations

// List all locations
const { locations } = await client.locations.list()

// Get a specific location
const location = await client.locations.getLocation('locations/123')

// Get connection status
const status = await client.locations.connectionStatus('locations/123')

Profile

// Get full profile
const profile = await client.profile.getProfile('locations/123')

// Update hours
await client.profile.updateHours('locations/123', {
  regularHours: {
    periods: [
      { openDay: 'MONDAY', openTime: { hours: 9 }, closeDay: 'MONDAY', closeTime: { hours: 17 } },
    ],
  },
})

Posts

// List posts with automatic pagination
for await (const post of client.posts.listAll('locations/123')) {
  console.log(post.summary)
}

// Create a post
const post = await client.posts.create('locations/123', {
  summary: 'Special offer!',
  callToAction: { actionType: 'LEARN_MORE', url: 'https://example.com' },
  topicType: 'OFFER',
})

// Delete a post
await client.posts.deletePost('locations/123', 'postId')

Reviews

// List reviews
const { reviews, averageRating, totalReviewCount } = await client.reviews.list('locations/123')

// Reply to a review
await client.reviews.reply('locations/123', 'reviewName', 'Thank you for your feedback!')

Sync

// Push data to Google
const result = await client.sync.push('locations/123', 'profile', {
  title: 'Updated Business Name',
})

// Get sync comparison
const comparison = await client.sync.comparison('locations/123')

Error Handling

import { SynoveoClient, SynoveoError, ErrorCodes } from '@synoveo/sdk'

try {
  await client.posts.create(locationId, post)
} catch (error) {
  if (error instanceof SynoveoError) {
    console.log('Error code:', error.code)
    console.log('Message:', error.message)
    console.log('Status:', error.status)
    console.log('Retryable:', error.retryable)
    console.log('Request ID:', error.requestId)

    // Type-safe error checking
    if (error.isQuotaError()) {
      console.log('Quota resets at:', error.details.resetAt)
    }

    if (error.isPlanError()) {
      console.log('Requires plan:', error.details.requiredPlan)
    }
  }
}

Testing

The SDK includes a mock client for testing:

import { createMockClient } from '@synoveo/sdk/testing'

const mockClient = createMockClient({
  locations: {
    list: async () => ({ locations: [{ name: 'locations/123', title: 'Test' }] }),
  },
})

// Use in tests
const { locations } = await mockClient.locations.list()

TypeScript

All types are exported for use in your application:

import type {
  Location,
  LocalPost,
  Review,
  MediaItem,
  SynoveoClientConfig,
} from '@synoveo/sdk'

On this page