Appearance
Quickstart Guide
Get up and running with the OriginalVoices API in minutes. This guide will walk you through installation, authentication, and your first API call.
Installation
Install the originalvoices npm package:
bash
npm install originalvoicesAuthentication
Before you can use the API, you'll need an API key. Get your API key from the OriginalVoices Platform.
Once you have your API key, you can initialize the client. If you don't pass an apiKey to the constructor, it will automatically fallback to the ORIGINALVOICES_API_KEY environment variable:
javascript
import { OriginalVoices } from "originalvoices";
const client = new OriginalVoices({
apiKey: process.env.ORIGINALVOICES_API_KEY,
});API Key Security
Never commit your API key to version control. Use environment variables or a secrets management service.
Getting Insights
OriginalVoices provides three ways to gather insights from your target audience. Each endpoint is designed for different research needs, from exploratory topic analysis to open, single and multiple choice questions.
Topic
We automatically generate three questions based on your defined topic. For each question, we provide a summary of how the audience answered, the key themes identified, an analysis of those themes, and theme prevalence (how often each theme was mentioned across all responses).
When to use
Use when you want to broadly understand how an audience feels about a topic before - or without - defining specific questions.
typescript
const { data } = await client.topic.getInsights({
audiencePrompt: "US, 25-45, tech professionals",
topic: "Remote work productivity tools",
});
console.log({ data });The response includes:
questions: Array of automatically generated questions, each containing:question: The question textsummary: Summary of what the audience said about this questionthemes: Array of key themes identified, each containing:title: The theme namesummary: Description of what this theme representsprevalence: How often this theme was mentioned (as a percentage)
Ask/Open
Use to ask any open-ended question. For the response, you will get a summary of the answers given to your open-ended question, along with key themes, theme analysis, and theme prevalence (how often each theme appeared across all responses).
When to use
Best for exploratory research, message testing, product feedback, or when you want to understand why something matters beyond purely measuring it quantitatively.
typescript
const { data } = await client.ask.open({
audiencePrompt: "UK, 18-30, fitness enthusiasts",
question: "When purchasing running shoes, what's most important to you?",
});
console.log({ data });The response includes:
summary: Summary of responses to your open-ended questionthemes: Array of key themes identified, each containing:title: The theme namesummary: Description of what this theme representsprevalence: How often this theme appeared across all responses (as a percentage)
Ask/Choices
Use to ask single or multipe choice questions. For the response, you will get a quantitative breakdown of the predefined answer options, including percentages for each answer choice.
When to use
Use when you want measurable preferences or decisions - such as feature prioritisation, yes/no responses, or option testing.
typescript
const { data } = await client.ask.choices({
audiencePrompt: "US, 25-45, tech professionals",
question:
"Which of the following is most important when buying running shoes?",
choices: ["Price", "Comfort", "Style", "Durability"],
isMultipleChoice: false,
});
console.log({ data });The response includes:
choices: Array of answer options, each containing:choice: The option textpercentage: Percentage of responses that selected this option
Rate limiting
The API enforces rate limits to ensure fair usage and system stability. Default rate limits are:
- 60 requests per minute (1 request per second)
- 10,000 requests per day
When you exceed these limits, you'll receive a 429 Too Many Requests response. Rate limit information is included in response headers:
X-RateLimit-Limit: Maximum number of requests allowedX-RateLimit-Remaining: Number of requests remaining in the current windowX-RateLimit-Reset: Time when the rate limit resets (Unix timestamp)
typescript
try {
const { data } = await client.topic.getInsights({
audiencePrompt: "US, 25-45, tech professionals",
topic: "Remote work productivity tools",
});
} catch (error) {
if (error.status === 429) {
console.error(
"Rate limit exceeded. Please wait before making more requests."
);
// Implement exponential backoff or wait for the reset time
}
}Rate Limit Best Practices
- Implement exponential backoff when you receive 429 responses
- Monitor the
X-RateLimit-Remainingheader to avoid hitting limits - For higher rate limits reach out to support@originalvoices.ai
Errors
HTTP API Errors
| Status code | Error code | Description |
|---|---|---|
| 400 | validation | Schema validation failed. Includes field-level details in the details array. |
| 400 | missing_audience_parameter | Either audienceId or audiencePrompt is required. |
| 400 | audience_title_exists | An audience with this title already exists for your organization. |
| 401 | missing_api_key | Missing API key. Please provide an API key in the Authorization header. |
| 401 | invalid_api_key | Invalid API key provided. |
| 401 | api_key_revoked | API key has been revoked. |
| 401 | unauthorized | Generic unauthorized error. |
| 402 | insufficient_balance | Your account does not have enough credits to perform this action. |
| 402 | payment_required | Generic payment required error. |
| 404 | audience_not_found | Audience not found. |
| 422 | insufficient_twins | Insufficient twins found. Please try again with a more specific prompt. Read more: https://docs.originalvoices.ai/errors/insufficient-twins.html |
| 422 | policy_violation | Policy violated. Read more: https://docs.originalvoices.ai/question-guidelines.html |
| 429 | rate_limit_exceeded | Generic rate limit exceeded error. |
| 500 | internal_server_error | An internal server error occurred. |
Notes:
- Validation errors (400 with
validationcode) include adetailsarray with field-level validation messages. - Generic error codes (e.g.,
bad_request,unauthorized) are used as fallbacks when a specific error code isn't provided. - All error responses follow the format:
{ requestId: string, data: null, error: { message: string, code: string, details?: Array<{field: string, message: string}> } }
Next Steps
- Explore the How It Works page to understand the platform concepts
- Check out the API Reference for detailed endpoint documentation
- Experiment with different audiences and topics to see how insights vary