surveycoder-sdk
v1.0.2
Published
TypeScript SDK for Survey Coder Pro API — AI-powered survey coding
Maintainers
Readme
surveycoder-sdk
TypeScript SDK for Survey Coder Pro — AI-powered open-ended survey coding.
Installation
npm install surveycoder-sdkQuick Start (5 steps)
import { SurveyCoderClient } from 'surveycoder-sdk';
// 1. Initialize client
const client = new SurveyCoderClient({
apiKey: 'scp_live_your_api_key_here',
});
// 2. Code survey responses (< 50 = sync, >= 50 = async job)
const result = await client.code({
responses: [
{ id: '1', text: 'Great product but too expensive' },
{ id: '2', text: 'Love the quality and fast delivery' },
{ id: '3', text: 'Customer service was terrible' },
],
coding_type: 'qualitative',
language: 'en',
});
// 3. Access results
console.log(result.codebook); // AI-generated categories + codes
console.log(result.results); // Per-response code assignments
console.log(result.credits_used); // Credits consumed
// 4. Export to Excel
const excel = await client.export.excel({
project_id: result.project_id,
layout: 'wide_by_question',
});
fs.writeFileSync('coded.xlsx', excel);
// 5. Check usage
const usage = await client.getUsage();
console.log(`${usage.credits_remaining} credits remaining`);Async Jobs (>= 50 responses)
const job = await client.code({ responses: largeDataset });
if ('id' in job) {
// Async — poll until complete
const result = await client.waitForJob(job.id);
console.log(result);
}Projects API
// List all projects
const projects = await client.projects.list();
// Create project
const project = await client.projects.create({
name: 'Q4 NPS Feedback',
language: 'en',
coding_type: 'qualitative',
});
// Upload responses
await client.projects.uploadResponses(project.id, questionId, [
{ id: 'R001', text: 'Great service' },
{ id: 'R002', text: 'Too slow' },
]);
// Generate codebook & run coding
const cbJob = await client.projects.generateCodebook(project.id, questionId);
await client.waitForJob(cbJob.id);
const codeJob = await client.projects.runCoding(project.id, questionId);
await client.waitForJob(codeJob.id);
// Get results (paginated)
const results = await client.projects.getResults(project.id, questionId, { page: 1, limit: 100 });Quality Checks
// Pre-scan for bots, spam, garbage responses
const scan = await client.quality.preScan({
project_id: projectId,
question_id: questionId,
});
console.log(`${scan.flagged} flagged of ${scan.total_responses}`);
// Full quality analysis
const analysis = await client.quality.analyze({ project_id: projectId, question_id: questionId });
// Exclude problematic respondents
await client.quality.exclude(projectId, questionId, ['resp1', 'resp2']);
// Consistency check after coding
const consistency = await client.quality.consistency(projectId, questionId);Codebook Management
// Import a manual codebook
await client.codebook.import({
project_id: projectId,
question_id: questionId,
categories: [
{
name: 'Service Quality',
codes: [
{ name: 'Fast delivery', definition: 'Comments about delivery speed', sentiment: 'Positive' },
{ name: 'Slow delivery', definition: 'Complaints about delays', sentiment: 'Negative' },
],
},
],
});
// Clone codebook from another project
await client.codebook.clone(sourceProjectId, sourceQuestionId, targetProjectId, targetQuestionId);
// Get AI recommendation for coding type
const rec = await client.codebook.recommendType(projectId, questionId);
console.log(`Recommended: ${rec.recommended_type} (${rec.confidence})`);Refinement
// Get AI suggestions after coding
const suggestions = await client.refinement.suggestions({
project_id: projectId,
question_id: questionId,
});
// Apply a suggestion
await client.refinement.apply({
project_id: projectId,
question_id: questionId,
action: 'merge',
suggestion_id: suggestions[0].id,
});
// Undo last refinement
await client.refinement.undo(projectId, questionId);CX Analytics (NPS/CSAT/CES)
// Full CX dashboard
const dashboard = await client.analytics.dashboard({
project_id: projectId,
segment_column: 'region',
});
console.log(`NPS: ${dashboard.metric_score}`);
// Executive summary (AI-generated)
const summary = await client.analytics.executiveSummary(projectId);
// Theme x Segment cross-tab
const crossTab = await client.analytics.crossTab({
project_id: projectId,
question_id: questionId,
segment_column: 'age_group',
});
// Impact analysis (which themes drive scores)
const impact = await client.analytics.impact({
project_id: projectId,
question_id: questionId,
});Export
// Excel with Code Dictionary
const excel = await client.export.excel({
project_id: projectId,
layout: 'wide_by_question',
include_sentiment: true,
include_code_dictionary: true,
});
fs.writeFileSync('coded.xlsx', excel);
// CSV
const csv = await client.export.csv({
project_id: projectId,
layout: 'columns_by_mention',
});
fs.writeFileSync('coded.csv', csv);Error Handling
import {
SurveyCoderClient,
AuthenticationError,
RateLimitError,
ValidationError,
NotFoundError,
} from 'surveycoder-sdk';
try {
await client.code({ responses: [...] });
} catch (err) {
if (err instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (err instanceof RateLimitError) {
console.error(`Rate limited — retry in ${err.retryAfterSeconds}s`);
} else if (err instanceof ValidationError) {
console.error(`Bad request: ${err.message}`);
} else if (err instanceof NotFoundError) {
console.error('Resource not found');
}
}Configuration
const client = new SurveyCoderClient({
apiKey: 'scp_live_...', // Required
baseUrl: 'https://api.surveycoder.io', // Default
timeout: 300000, // 5 min default
maxRetries: 3, // Retry on 429/500/503
});Features
- Auto-retry with exponential backoff on 429/500/503
- Typed errors —
AuthenticationError,RateLimitError,ValidationError,NotFoundError - Idempotency keys auto-generated for write operations
- Job polling via
waitForJob()for large datasets - Full v2 API coverage — projects, quality, refinement, analytics, codebook, export
- Type-safe — full TypeScript types for all requests/responses
- Zero dependencies — uses native
fetch
API Documentation
https://api.surveycoder.io/docs
License
MIT
