Skip to main content
Export your Qwairy data for analysis in spreadsheets, databases, or BI platforms.
This guide uses the API client from the Guides index. Copy it to your project first.

What You’ll Build

Export pipelines for:
  • CSV files: For Excel, Google Sheets
  • JSON files: For data pipelines
  • BigQuery: For Google Cloud analytics
  • Snowflake: For enterprise data warehousing

Fetch All Data

First, gather data from all endpoints.
async function fetchAllData(client, brandId, period = 30) {
  const [performance, competitors, sources] = await Promise.all([
    client.getPerformance(brandId, { period }),
    client.getCompetitors(brandId, { period, limit: 100 }),
    client.getSourceDomains(brandId, { period, limit: 100 }),
  ]);

  return {
    exportedAt: new Date().toISOString(),
    brandId,
    period,
    performance: {
      scores: performance.scores,
      methodology: performance.methodology,
    },
    competitors: competitors.competitors.map(c => ({
      id: c.id,
      name: c.name,
      relationship: c.relationship,
      shareOfVoice: c.shareOfVoice,
      totalMentions: c.totalMentions,
      avgPosition: c.avgPosition,
      avgSentiment: c.avgSentiment,
    })),
    sources: sources.sources.map(s => ({
      id: s.id,
      domain: s.domain,
      type: s.type,
      isSelf: s.isSelf,
      totalMentions: s.totalMentions,
      rate: s.rate,
      avgPosition: s.avgPosition,
    })),
  };
}
def fetch_all_data(client, brand_id: str, period: int = 30) -> dict:
    """Fetch all data for export."""
    from concurrent.futures import ThreadPoolExecutor
    from datetime import datetime

    with ThreadPoolExecutor(max_workers=3) as executor:
        perf_future = executor.submit(client.get_performance, brand_id, period=period)
        comp_future = executor.submit(client.get_competitors, brand_id, period=period, limit=100)
        src_future = executor.submit(client.get_source_domains, brand_id, period=period, limit=100)

        performance = perf_future.result()
        competitors = comp_future.result()
        sources = src_future.result()

    return {
        'exported_at': datetime.now().isoformat(),
        'brand_id': brand_id,
        'period': period,
        'performance': {
            'scores': performance['scores'],
            'methodology': performance['methodology'],
        },
        'competitors': [
            {
                'id': c['id'],
                'name': c['name'],
                'relationship': c['relationship'],
                'share_of_voice': c['shareOfVoice'],
                'total_mentions': c['totalMentions'],
                'avg_position': c['avgPosition'],
                'avg_sentiment': c['avgSentiment'],
            }
            for c in competitors['competitors']
        ],
        'sources': [
            {
                'id': s['id'],
                'domain': s['domain'],
                'type': s['type'],
                'is_self': s['isSelf'],
                'total_mentions': s['totalMentions'],
                'rate': s['rate'],
                'avg_position': s['avgPosition'],
            }
            for s in sources['sources']
        ],
    }

Export to CSV

const fs = require('fs');

function exportToCSV(data, outputDir = './exports') {
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  const timestamp = data.exportedAt.split('T')[0];

  // Competitors CSV
  const competitorHeaders = ['id', 'name', 'relationship', 'shareOfVoice', 'totalMentions', 'avgPosition', 'avgSentiment'];
  const competitorRows = data.competitors.map(c => competitorHeaders.map(h => c[h]).join(','));
  fs.writeFileSync(
    `${outputDir}/competitors_${timestamp}.csv`,
    [competitorHeaders.join(','), ...competitorRows].join('\n')
  );

  // Sources CSV
  const sourceHeaders = ['id', 'domain', 'type', 'isSelf', 'totalMentions', 'rate', 'avgPosition'];
  const sourceRows = data.sources.map(s => sourceHeaders.map(h => s[h]).join(','));
  fs.writeFileSync(
    `${outputDir}/sources_${timestamp}.csv`,
    [sourceHeaders.join(','), ...sourceRows].join('\n')
  );

  // Performance CSV (single row)
  const perfHeaders = ['mentionRate', 'sourceRate', 'coverage', 'shareOfVoice', 'sentiment'];
  const perfValues = [
    data.performance.scores.mentionRate,
    data.performance.scores.sourceRate,
    data.performance.scores.coverage,
    data.performance.scores.shareOfVoice,
    data.performance.scores.sentiment,
  ];
  fs.writeFileSync(
    `${outputDir}/performance_${timestamp}.csv`,
    [perfHeaders.join(','), perfValues.join(',')].join('\n')
  );

  return {
    files: [
      `${outputDir}/competitors_${timestamp}.csv`,
      `${outputDir}/sources_${timestamp}.csv`,
      `${outputDir}/performance_${timestamp}.csv`,
    ],
  };
}
import csv
import os


def export_to_csv(data: dict, output_dir: str = './exports') -> dict:
    """Export data to CSV files."""
    os.makedirs(output_dir, exist_ok=True)
    timestamp = data['exported_at'].split('T')[0]
    files = []

    # Competitors CSV
    comp_file = f'{output_dir}/competitors_{timestamp}.csv'
    with open(comp_file, 'w', newline='') as f:
        if data['competitors']:
            writer = csv.DictWriter(f, fieldnames=data['competitors'][0].keys())
            writer.writeheader()
            writer.writerows(data['competitors'])
    files.append(comp_file)

    # Sources CSV
    src_file = f'{output_dir}/sources_{timestamp}.csv'
    with open(src_file, 'w', newline='') as f:
        if data['sources']:
            writer = csv.DictWriter(f, fieldnames=data['sources'][0].keys())
            writer.writeheader()
            writer.writerows(data['sources'])
    files.append(src_file)

    # Performance CSV
    perf_file = f'{output_dir}/performance_{timestamp}.csv'
    scores = data['performance']['scores']
    with open(perf_file, 'w', newline='') as f:
        writer = csv.DictWriter(f, fieldnames=['mention_rate', 'source_rate', 'coverage', 'share_of_voice', 'sentiment'])
        writer.writeheader()
        writer.writerow({
            'mention_rate': scores['mentionRate'],
            'source_rate': scores['sourceRate'],
            'coverage': scores['coverage'],
            'share_of_voice': scores['shareOfVoice'],
            'sentiment': scores['sentiment'],
        })
    files.append(perf_file)

    return {'files': files}

Export to JSON

const fs = require('fs');

function exportToJSON(data, outputDir = './exports') {
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  const timestamp = data.exportedAt.split('T')[0];
  const filepath = `${outputDir}/qwairy_export_${timestamp}.json`;

  fs.writeFileSync(filepath, JSON.stringify(data, null, 2));

  return { file: filepath, size: fs.statSync(filepath).size };
}
import json
import os


def export_to_json(data: dict, output_dir: str = './exports') -> dict:
    """Export data to JSON file."""
    os.makedirs(output_dir, exist_ok=True)
    timestamp = data['exported_at'].split('T')[0]
    filepath = f'{output_dir}/qwairy_export_{timestamp}.json'

    with open(filepath, 'w') as f:
        json.dump(data, f, indent=2)

    return {'file': filepath, 'size': os.path.getsize(filepath)}

Database Schemas

Create these tables before exporting to BigQuery or Snowflake.
-- Create dataset
CREATE SCHEMA IF NOT EXISTS qwairy;

-- Competitors table
CREATE TABLE IF NOT EXISTS qwairy.competitors (
  id STRING NOT NULL,
  name STRING NOT NULL,
  relationship STRING,
  share_of_voice FLOAT64,
  total_mentions INT64,
  avg_position FLOAT64,
  avg_sentiment FLOAT64,
  exported_at TIMESTAMP NOT NULL,
  brand_id STRING NOT NULL
);

-- Sources table
CREATE TABLE IF NOT EXISTS qwairy.sources (
  id STRING NOT NULL,
  domain STRING NOT NULL,
  type STRING,
  is_self BOOL,
  total_mentions INT64,
  rate FLOAT64,
  avg_position FLOAT64,
  exported_at TIMESTAMP NOT NULL,
  brand_id STRING NOT NULL
);

-- Performance table
CREATE TABLE IF NOT EXISTS qwairy.performance (
  mentionRate FLOAT64,
  sourceRate FLOAT64,
  coverage FLOAT64,
  shareOfVoice FLOAT64,
  sentiment FLOAT64,
  methodology STRING,
  exported_at TIMESTAMP NOT NULL,
  brand_id STRING NOT NULL
);
-- Create schema
CREATE SCHEMA IF NOT EXISTS QWAIRY;

-- Competitors table
CREATE TABLE IF NOT EXISTS QWAIRY.COMPETITORS (
  ID VARCHAR(50) NOT NULL,
  NAME VARCHAR(255) NOT NULL,
  RELATIONSHIP VARCHAR(50),
  SHARE_OF_VOICE FLOAT,
  TOTAL_MENTIONS INTEGER,
  AVG_POSITION FLOAT,
  AVG_SENTIMENT FLOAT,
  EXPORTED_AT TIMESTAMP_NTZ NOT NULL,
  BRAND_ID VARCHAR(50) NOT NULL
);

-- Sources table
CREATE TABLE IF NOT EXISTS QWAIRY.SOURCES (
  ID VARCHAR(50) NOT NULL,
  DOMAIN VARCHAR(255) NOT NULL,
  TYPE VARCHAR(50),
  IS_SELF BOOLEAN,
  TOTAL_MENTIONS INTEGER,
  RATE FLOAT,
  AVG_POSITION FLOAT,
  EXPORTED_AT TIMESTAMP_NTZ NOT NULL,
  BRAND_ID VARCHAR(50) NOT NULL
);

-- Performance table
CREATE TABLE IF NOT EXISTS QWAIRY.PERFORMANCE (
  MENTION_RATE FLOAT,
  SOURCE_RATE FLOAT,
  COVERAGE FLOAT,
  SHARE_OF_VOICE FLOAT,
  SENTIMENT FLOAT,
  METHODOLOGY VARCHAR(5000),
  EXPORTED_AT TIMESTAMP_NTZ NOT NULL,
  BRAND_ID VARCHAR(50) NOT NULL
);

Export to BigQuery

const { BigQuery } = require('@google-cloud/bigquery');

async function exportToBigQuery(data, datasetId = 'qwairy', projectId = process.env.GCP_PROJECT_ID) {
  const bigquery = new BigQuery({ projectId });

  // Create dataset if not exists
  const [datasets] = await bigquery.getDatasets();
  if (!datasets.find(d => d.id === datasetId)) {
    await bigquery.createDataset(datasetId);
  }

  const dataset = bigquery.dataset(datasetId);

  // Insert competitors
  await dataset.table('competitors').insert(
    data.competitors.map(c => ({
      ...c,
      exportedAt: data.exportedAt,
      brandId: data.brandId,
    }))
  );

  // Insert sources
  await dataset.table('sources').insert(
    data.sources.map(s => ({
      ...s,
      exportedAt: data.exportedAt,
      brandId: data.brandId,
    }))
  );

  // Insert performance
  await dataset.table('performance').insert([{
    ...data.performance.scores,
    methodology: JSON.stringify(data.performance.methodology),
    exportedAt: data.exportedAt,
    brandId: data.brandId,
  }]);

  return { dataset: datasetId, tables: ['competitors', 'sources', 'performance'] };
}
from google.cloud import bigquery


def export_to_bigquery(data: dict, dataset_id: str = 'qwairy', project_id: str = None) -> dict:
    """Export data to BigQuery."""
    import os
    import json

    project_id = project_id or os.environ.get('GCP_PROJECT_ID')
    client = bigquery.Client(project=project_id)

    # Create dataset if not exists
    dataset_ref = client.dataset(dataset_id)
    try:
        client.get_dataset(dataset_ref)
    except Exception:
        client.create_dataset(dataset_ref)

    # Insert competitors
    competitors_table = f'{project_id}.{dataset_id}.competitors'
    rows = [
        {**c, 'exported_at': data['exported_at'], 'brand_id': data['brand_id']}
        for c in data['competitors']
    ]
    if rows:
        client.insert_rows_json(competitors_table, rows)

    # Insert sources
    sources_table = f'{project_id}.{dataset_id}.sources'
    rows = [
        {**s, 'exported_at': data['exported_at'], 'brand_id': data['brand_id']}
        for s in data['sources']
    ]
    if rows:
        client.insert_rows_json(sources_table, rows)

    # Insert performance
    perf_table = f'{project_id}.{dataset_id}.performance'
    perf_row = {
        **data['performance']['scores'],
        'methodology': json.dumps(data['performance']['methodology']),
        'exported_at': data['exported_at'],
        'brand_id': data['brand_id'],
    }
    client.insert_rows_json(perf_table, [perf_row])

    return {'dataset': dataset_id, 'tables': ['competitors', 'sources', 'performance']}

Export to Snowflake

const snowflake = require('snowflake-sdk');

async function exportToSnowflake(data, config) {
  const connection = snowflake.createConnection({
    account: config.account,
    username: config.username,
    password: config.password,
    warehouse: config.warehouse,
    database: config.database,
    schema: config.schema || 'QWAIRY',
  });

  await new Promise((resolve, reject) => {
    connection.connect((err) => err ? reject(err) : resolve());
  });

  const execute = (sql, binds = []) => new Promise((resolve, reject) => {
    connection.execute({ sqlText: sql, binds, complete: (err, stmt, rows) => err ? reject(err) : resolve(rows) });
  });

  // Insert competitors
  for (const c of data.competitors) {
    await execute(
      `INSERT INTO competitors (id, name, relationship, share_of_voice, total_mentions, avg_position, avg_sentiment, exported_at, brand_id)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
      [c.id, c.name, c.relationship, c.shareOfVoice, c.totalMentions, c.avgPosition, c.avgSentiment, data.exportedAt, data.brandId]
    );
  }

  // Insert sources
  for (const s of data.sources) {
    await execute(
      `INSERT INTO sources (id, domain, type, is_self, total_mentions, rate, avg_position, exported_at, brand_id)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
      [s.id, s.domain, s.type, s.isSelf, s.totalMentions, s.rate, s.avgPosition, data.exportedAt, data.brandId]
    );
  }

  connection.destroy();
  return { schema: config.schema || 'QWAIRY', tables: ['competitors', 'sources'] };
}
import snowflake.connector


def export_to_snowflake(data: dict, config: dict) -> dict:
    """Export data to Snowflake."""
    conn = snowflake.connector.connect(
        account=config['account'],
        user=config['username'],
        password=config['password'],
        warehouse=config['warehouse'],
        database=config['database'],
        schema=config.get('schema', 'QWAIRY'),
    )
    cursor = conn.cursor()

    # Insert competitors
    for c in data['competitors']:
        cursor.execute(
            '''INSERT INTO competitors (id, name, relationship, share_of_voice, total_mentions, avg_position, avg_sentiment, exported_at, brand_id)
               VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)''',
            (c['id'], c['name'], c['relationship'], c['share_of_voice'], c['total_mentions'],
             c['avg_position'], c['avg_sentiment'], data['exported_at'], data['brand_id'])
        )

    # Insert sources
    for s in data['sources']:
        cursor.execute(
            '''INSERT INTO sources (id, domain, type, is_self, total_mentions, rate, avg_position, exported_at, brand_id)
               VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)''',
            (s['id'], s['domain'], s['type'], s['is_self'], s['total_mentions'],
             s['rate'], s['avg_position'], data['exported_at'], data['brand_id'])
        )

    conn.commit()
    cursor.close()
    conn.close()

    return {'schema': config.get('schema', 'QWAIRY'), 'tables': ['competitors', 'sources']}

Usage

const client = new QwairyClient(process.env.QWAIRY_API_TOKEN);

// Fetch data
const data = await fetchAllData(client, 'your-brand-id', 30);

// Export to files
const csvResult = exportToCSV(data);
console.log('CSV files:', csvResult.files);

const jsonResult = exportToJSON(data);
console.log('JSON file:', jsonResult.file, `(${jsonResult.size} bytes)`);

// Export to BigQuery (requires @google-cloud/bigquery)
// const bqResult = await exportToBigQuery(data);
// console.log('BigQuery tables:', bqResult.tables);
client = QwairyClient()

# Fetch data
data = fetch_all_data(client, 'your-brand-id', period=30)

# Export to files
csv_result = export_to_csv(data)
print(f"CSV files: {csv_result['files']}")

json_result = export_to_json(data)
print(f"JSON file: {json_result['file']} ({json_result['size']} bytes)")

# Export to BigQuery (requires google-cloud-bigquery)
# bq_result = export_to_bigquery(data)
# print(f"BigQuery tables: {bq_result['tables']}")

Scheduling Exports

Automate daily or weekly exports:
PlatformConfiguration
Cron0 1 * * * (daily at 1am)
GitHub Actionsschedule: cron: '0 1 * * *'
AWS LambdaEventBridge scheduled rule
Google CloudCloud Scheduler + Cloud Functions

Next Steps