Skip to main content

Overview

The SeggWat API allows you to programmatically access and manage feedback data from your applications. This is useful for:
  • Backend integrations: Process feedback in your own systems
  • Custom dashboards: Build your own analytics and reporting tools
  • Automation: Trigger workflows based on feedback events
  • Data exports: Extract feedback for analysis or backup
  • Third-party integrations: Connect SeggWat to other tools in your stack

Prerequisites

Before you start, ensure you have:
  1. A SeggWat account with at least one project
  2. An Organization Access Token (API key) - see Authentication
  3. Your project ID (found in the dashboard under project settings)

Getting Started

1. Create an API Token

1

Navigate to Settings

Log in to your SeggWat Dashboard and click Settings in the sidebar.
2

Generate Token

Go to the API Tokens tab and click Create New Token. Optionally add a label like “Backend Integration” or “CI/CD Pipeline”.
3

Store Securely

Copy the token immediately - it will only be shown once! Store it in your environment variables:
export SEGGWAT_API_KEY=oat_xxxxxxxxxxxxxxxxxxxxx
Never commit API tokens to version control. Use environment variables or a secrets manager.

2. Find Your Project ID

  1. Go to your project in the dashboard
  2. Click Settings in the project sidebar
  3. Copy the Project ID (UUID format)

Common Use Cases

List All Feedback

Retrieve a paginated list of feedback for a project:
curl -X GET "https://seggwat.com/api/v1/projects/YOUR_PROJECT_ID/feedback?page=1&limit=20" \
  -H "X-API-Key: $SEGGWAT_API_KEY"

Filter Feedback by Status

Get only new, unprocessed feedback:
curl -X GET "https://seggwat.com/api/v1/projects/YOUR_PROJECT_ID/feedback?status=New&limit=50" \
  -H "X-API-Key: $SEGGWAT_API_KEY"

Search Feedback by Content

Search for specific keywords in feedback messages:
curl -X GET "https://seggwat.com/api/v1/projects/YOUR_PROJECT_ID/feedback?search=bug" \
  -H "X-API-Key: $SEGGWAT_API_KEY"

Get Single Feedback Item

Retrieve detailed information about a specific feedback item:
curl -X GET "https://seggwat.com/api/v1/projects/YOUR_PROJECT_ID/feedback/FEEDBACK_ID" \
  -H "X-API-Key: $SEGGWAT_API_KEY"

Integration Examples

Slack Notification Bot

Send new feedback to a Slack channel:
import fetch from 'node-fetch';

const SEGGWAT_API_KEY = process.env.SEGGWAT_API_KEY;
const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;
const PROJECT_ID = process.env.SEGGWAT_PROJECT_ID;

async function sendNewFeedbackToSlack() {
  // Get new feedback
  const response = await fetch(
    `https://seggwat.com/api/v1/projects/${PROJECT_ID}/feedback?status=New&limit=10`,
    {
      headers: { 'X-API-Key': SEGGWAT_API_KEY }
    }
  );

  const data = await response.json();

  // Send each to Slack
  for (const feedback of data.feedback) {
    await fetch(SLACK_WEBHOOK_URL, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        text: `New ${feedback.type} feedback`,
        blocks: [
          {
            type: 'section',
            text: {
              type: 'mrkdwn',
              text: `*New ${feedback.type} Feedback*\n${feedback.message}`
            }
          },
          {
            type: 'context',
            elements: [
              {
                type: 'mrkdwn',
                text: `Path: ${feedback.path || 'N/A'} | Version: ${feedback.version || 'N/A'}`
              }
            ]
          }
        ]
      })
    });
  }
}

// Run every 5 minutes
setInterval(sendNewFeedbackToSlack, 5 * 60 * 1000);

CSV Export Script

Export feedback to a CSV file for analysis:
import csv
import requests
import os

SEGGWAT_API_KEY = os.getenv('SEGGWAT_API_KEY')
PROJECT_ID = os.getenv('SEGGWAT_PROJECT_ID')

def export_to_csv(filename='feedback.csv'):
    all_feedback = []
    page = 1

    # Fetch all pages
    while True:
        response = requests.get(
            f'https://seggwat.com/api/v1/projects/{PROJECT_ID}/feedback',
            headers={'X-API-Key': SEGGWAT_API_KEY},
            params={'page': page, 'limit': 100}
        )

        data = response.json()
        all_feedback.extend(data['feedback'])

        if page >= data['pagination']['total_pages']:
            break
        page += 1

    # Write to CSV
    with open(filename, 'w', newline='') as csvfile:
        fieldnames = ['id', 'message', 'type', 'status', 'source', 'created_at', 'path', 'version']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

        writer.writeheader()
        for feedback in all_feedback:
            writer.writerow({
                'id': feedback['id'],
                'message': feedback['message'],
                'type': feedback['type'],
                'status': feedback['status'],
                'source': feedback['source'],
                'created_at': feedback['created_at'],
                'path': feedback.get('path', ''),
                'version': feedback.get('version', '')
            })

    print(f"Exported {len(all_feedback)} feedback items to {filename}")

if __name__ == '__main__':
    export_to_csv()

GitHub Issue Creator

Automatically create GitHub issues from bug reports:
import fetch from 'node-fetch';
import { Octokit } from '@octokit/rest';

const SEGGWAT_API_KEY = process.env.SEGGWAT_API_KEY;
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const PROJECT_ID = process.env.SEGGWAT_PROJECT_ID;
const GITHUB_OWNER = 'your-org';
const GITHUB_REPO = 'your-repo';

const octokit = new Octokit({ auth: GITHUB_TOKEN });

async function createIssuesFromBugs() {
  // Get bug-type feedback that's new
  const response = await fetch(
    `https://seggwat.com/api/v1/projects/${PROJECT_ID}/feedback?type=Bug&status=New`,
    {
      headers: { 'X-API-Key': SEGGWAT_API_KEY }
    }
  );

  const data = await response.json();

  for (const feedback of data.feedback) {
    // Create GitHub issue
    await octokit.issues.create({
      owner: GITHUB_OWNER,
      repo: GITHUB_REPO,
      title: `[User Feedback] ${feedback.message.substring(0, 60)}...`,
      body: `
## User Feedback

**Type:** ${feedback.type}
**Source:** ${feedback.source}
**Created:** ${feedback.created_at}
**Path:** ${feedback.path || 'N/A'}
**Version:** ${feedback.version || 'N/A'}

### Message

${feedback.message}

---
*Feedback ID: ${feedback.id}*
*View in SeggWat: https://seggwat.com/dashboard/feedback/${feedback.id}*
      `,
      labels: ['feedback', 'bug']
    });

    console.log(`Created GitHub issue for feedback ${feedback.id}`);
  }
}

createIssuesFromBugs();

Error Handling

Always handle API errors gracefully:
async function safeFetchFeedback() {
  try {
    const response = await fetch(
      `https://seggwat.com/api/v1/projects/${PROJECT_ID}/feedback`,
      {
        headers: { 'X-API-Key': SEGGWAT_API_KEY }
      }
    );

    if (!response.ok) {
      if (response.status === 401) {
        throw new Error('Invalid API key');
      } else if (response.status === 403) {
        throw new Error('Access denied to this project');
      } else if (response.status === 404) {
        throw new Error('Project not found');
      }
      throw new Error(`API error: ${response.status}`);
    }

    return await response.json();
  } catch (error) {
    console.error('Failed to fetch feedback:', error.message);
    return null;
  }
}

Rate Limits

The SeggWat API currently enforces the following rate limits:
  • Feedback endpoints: 20 requests per minute per IP
  • Health endpoints: 300 requests per minute per IP
If you exceed these limits, you’ll receive a 429 Too Many Requests response.

Best Practices

Store API keys in environment variables, not in your source code:
SEGGWAT_API_KEY=oat_xxxxxxxxxxxxxxxxxxxxx
SEGGWAT_PROJECT_ID=550e8400-e29b-41d4-a716-446655440000
Add exponential backoff for failed requests:
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      if (response.ok) return response;
      if (response.status === 429) {
        // Rate limited, wait and retry
        await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
        continue;
      }
      throw new Error(`HTTP ${response.status}`);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}
Use caching for data that doesn’t change frequently:
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

async function getCachedFeedback(feedbackId) {
  const cacheKey = `feedback-${feedbackId}`;
  const cached = cache.get(cacheKey);

  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }

  const data = await getFeedback(feedbackId);
  cache.set(cacheKey, { data, timestamp: Date.now() });
  return data;
}
Check the “Last Used” timestamp in your dashboard to monitor which tokens are active and identify unused ones.

Next Steps