Documentation
Documentation
Learn how to integrate ShinRAG into your applications using the REST API or our official TypeScript SDK.
Quick Start
ShinRAG provides two ways to interact with your pipelines, agents, and indexes:
- REST API: Direct HTTP requests for any programming language
- SDK: Official TypeScript/JavaScript SDK with full type safety
1. Get Your API Key
Your API key starts with sk_ and is required for all requests.
2. Find Your Resource IDs
Each pipeline, agent, and index has a unique ID. You can easily copy these IDs using the Copy ID button:
Pipeline ID:
Go to Pipelines, open any pipeline, and click the Copy ID button next to the pipeline name
Agent ID:
Go to Agents, open any agent, and click the Copy ID button next to the agent name
Index ID:
Go to Indexes, open any index, and click the Copy ID button next to the index name
3. Install the SDK (Optional)
For TypeScript/JavaScript projects, install our official SDK:
npm:
npm install @shinrag/sdkpnpm:
pnpm add @shinrag/sdkAuthentication
All API requests require authentication using an API key. Your API key starts with sk_.
You can authenticate in two ways:
Option 1: X-API-Key Header (Recommended)
X-API-Key: sk_your_api_key_hereOption 2: Authorization Header
Authorization: Bearer sk_your_api_key_hereOrganization Scoping
Resources in ShinRAG belong to an organization. To access org-scoped agents, pipelines, indexes, and other resources, include your organization ID in requests.
import { ShinRAGClient } from '@shinrag/sdk';
// Organization-scoped client
const client = new ShinRAGClient({
apiKey: 'sk_your_api_key_here',
organizationId: 'org_123' // Access org resources
});
// Personal workspace client (no org ID needed)
const personalClient = new ShinRAGClient({
apiKey: 'sk_your_api_key_here'
});Agents
Agents are RAG-powered assistants that retrieve relevant context from assigned indexes and generate answers using LLMs.
Query an Agent
const result = await client.queryAgent('agent_id', {
question: 'What are the key features?',
maxResults: 5, // Max results from indexes (default: 10)
temperature: 0.7, // LLM temperature 0.0-2.0 (default: 0.7)
maxTokens: 1000 // Max tokens for generation
});
console.log(result.answer);
console.log('Sources:', result.sources);
console.log('Tokens used:', result.tokensUsed);
console.log('Model:', result.model);Response Type
interface QueryAgentResponse {
answer: string | null;
sources: Array<{
dataset?: string;
index?: string;
score: number;
text: string;
}>;
tokensUsed: number;
model: string;
warning?: string;
diagnostic?: {
totalResultsFound: number;
threshold: number | null;
topScores: number[];
};
}Manage Agents
// List all agents
const agents = await client.listAgents();
// Get a specific agent
const agent = await client.getAgent('agent_id');
// Create an agent
const newAgent = await client.createAgent({
name: 'Support Bot',
description: 'Answers customer questions',
provider: 'openai',
model: 'gpt-4o',
indexIds: ['index_id_1', 'index_id_2'],
usePlatformKey: true
});
// Update an agent
const updated = await client.updateAgent('agent_id', {
name: 'Updated Bot',
instructions: 'Be concise and helpful'
});
// Delete an agent
await client.deleteAgent('agent_id');Pipelines
Pipelines are visual workflows that chain together agents, synthesis nodes, conditionals, and integrations.
Execute a Pipeline
// Execute a pipeline
const result = await client.executePipeline('pipeline_id', {
input: 'What are the key features mentioned in the documentation?'
});
console.log(result.output);
console.log('Execution ID:', result.executionId);
console.log('Tokens used:', result.totalTokensUsed);
// Iterate through node results
result.nodeResults.forEach(node => {
console.log(`Node ${node.nodeId}: ${node.status}`);
if (node.output) console.log(` Output: ${node.output}`);
if (node.warning) console.log(` Warning: ${node.warning}`);
});
// Convenience alias
const result2 = await client.queryPipeline('pipeline_id', {
input: 'What are the key features?'
});Response Type
interface ExecutePipelineResponse {
executionId: string;
status: string;
output?: string;
outputs?: Array<{
nodeId: string;
label?: string;
output: string;
}>;
error?: string;
nodeResults: Array<{
nodeId: string;
status: string;
output?: string;
tokensUsed: number;
warning?: string;
}>;
totalTokensUsed: number;
}Execution Status & History
// Get execution status
const status = await client.getPipelineExecutionStatus(
'pipeline_id',
'execution_id'
);
// Get full execution details
const execution = await client.getPipelineExecution(
'pipeline_id',
'execution_id'
);
// List executions with pagination
const page = await client.getPipelineExecutions('pipeline_id', {
limit: 20,
cursor: undefined // Use page.nextCursor for next page
});
console.log(page.executions);
console.log('Has more:', page.hasMore);Manage Pipelines
// List all pipelines
const pipelines = await client.listPipelines();
// Get a specific pipeline
const pipeline = await client.getPipeline('pipeline_id');
// Delete a pipeline
await client.deletePipeline('pipeline_id');Indexes
Indexes store your vector embeddings for semantic search. Query them directly or assign them to agents.
Query an Index
// Search with text
const result = await client.queryIndex({
indexId: 'index_id',
queryText: 'What are the key features?',
limit: 10,
filter: { category: 'docs' } // Optional metadata filter
});
console.log(`Found ${result.results.length} results`);
result.results.forEach(item => {
console.log(`Score: ${item.score}, ID: ${item.id}`);
console.log('Content:', item.payload.text);
});
// Or use the convenience alias
const result2 = await client.searchIndex({
indexId: 'index_id',
queryText: 'authentication',
limit: 5
});
// Search with a pre-computed vector
const vectorResult = await client.queryIndex({
indexId: 'index_id',
queryVector: [0.1, 0.2, 0.3, /* ... */],
limit: 10
});Response Type
interface QueryIndexResponse {
success: boolean;
results: Array<{
id: string;
score: number;
payload: Record<string, unknown>;
}>;
}Manage Indexes & Records
import { PineconeEmbeddingModel } from '@shinrag/sdk';
// List all indexes
const indexes = await client.listIndexes();
// Create an index
const newIndex = await client.createIndex({
name: 'Product Docs',
pineconeIndexName: 'my-pinecone-index',
embeddingModel: PineconeEmbeddingModel.OPENAI_SMALL,
metric: 'cosine' // 'cosine' | 'euclidean' | 'dotproduct'
});
// Get index records with pagination
const records = await client.getIndexRecords('index_id', {
limit: 50,
paginationToken: 'next_page_token',
prefix: 'doc_'
});
// Update records (upsert, delete)
const result = await client.updateIndexRecords('index_id', {
records: [
{ id: 'rec_1', metadata: { text: 'Updated content' } },
{ id: 'rec_new', metadata: { text: 'New record' }, isNew: true },
{ id: 'rec_old', metadata: {}, isDeleted: true }
]
});
// Check ingestion job status
const job = await client.getIngestionStatus('job_id');
console.log(job.status); // 'pending' | 'processing' | 'completed' | 'failed'
console.log(job.progress); // 0-100Integrations
Connect external services like Slack, GitHub, databases, and search APIs to use in your pipeline nodes.
// List all integrations
const integrations = await client.listIntegrations();
// Get available integration types
const types = await client.getIntegrationTypes();
const byCategory = await client.getIntegrationTypesByCategory();
// Create an integration (e.g. PostgreSQL)
const pg = await client.createIntegration({
type: 'postgres',
name: 'Production DB',
credentials: {
host: 'db.example.com',
port: 5432,
database: 'mydb',
user: 'readonly',
password: 'secret'
},
validateCredentials: true
});
// Test a connection
const test = await client.testIntegration('integration_id');
console.log('Connected:', test.success);
// Execute an integration
const result = await client.executeIntegration('integration_id', {
config: { query: 'SELECT * FROM users LIMIT 10' },
input: 'Fetch user data'
});
// Slack OAuth
const { url } = await client.getSlackAuthUrl();
// redirect user to url, then on callback:
const slack = await client.completeSlackOAuth(code);
const { channels } = await client.refreshSlackChannels('integration_id');
// GitHub OAuth
const { url: ghUrl } = await client.getGitHubAuthUrl();
const gh = await client.completeGitHubOAuth(code);
const { repositories } = await client.refreshGitHubRepositories('integration_id');
const { issues } = await client.getGitHubIssues('integration_id', 'owner', 'repo');
const { pullRequests } = await client.getGitHubPullRequests('integration_id', 'owner', 'repo');Supported types: slack, discord, webhook, github, postgres, mysql, mongodb, snowflake, bigquery, perplexity, tavily, http, email
Widgets
Embed AI chat widgets on your website. Widget query endpoints are public and don't require API key authentication.
// Manage widgets (authenticated)
const widgets = await client.listWidgets();
const widget = await client.createWidget({
name: 'Support Chat',
agentId: 'agent_id'
});
// Public endpoints (no auth needed for end users)
const info = await client.getWidgetByKey('widget_key');
// Query a widget with session continuity
const answer = await client.queryWidget('widget_key', {
question: 'How do I get started?',
sessionId: 'session_123' // Optional: maintain conversation
});
console.log(answer.answer);
console.log('Session:', answer.sessionId);
// Get conversation history
const history = await client.getWidgetSessionHistory(
'widget_key',
'session_123'
);
console.log(history.messages); // Array of { role, content }Batch Execution
Run a pipeline with multiple inputs in a single batch for bulk processing.
// Create a batch
const batch = await client.createBatch('pipeline_id', {
inputs: [
'What is the return policy?',
'How do I contact support?',
'What are the shipping options?'
],
name: 'FAQ Batch'
});
// Poll for completion
let status = await client.getBatchStatus(batch.batchId);
while (status.status === 'pending' || status.status === 'processing') {
await new Promise(r => setTimeout(r, 2000));
status = await client.getBatchStatus(batch.batchId);
console.log(`Progress: ${status.processedItems}/${status.totalItems}`);
}
// Check results
if (status.results) {
status.results.forEach(item => {
console.log(`Input: ${item.input}`);
console.log(`Output: ${item.output}`);
});
}Webhooks & Schedules
Automate pipeline execution with webhooks (trigger on external events) and schedules (run on a cron schedule).
Webhooks
// Create a webhook to trigger a pipeline
const webhook = await client.createWebhook('pipeline_id', {
name: 'Incoming Data Webhook',
description: 'Triggers pipeline on new data',
secretToken: 'my-secret', // Optional: for verification
inputMapping: '{{body.query}}' // Optional: extract input from payload
});
console.log('Webhook URL:', webhook.webhookKey);
// List & delete webhooks
const webhooks = await client.listWebhooks('pipeline_id');
await client.deleteWebhook('pipeline_id', 'webhook_id');Schedules
// Create a cron schedule
const schedule = await client.createSchedule('pipeline_id', {
name: 'Daily Report',
cronExpression: '0 9 * * *', // Every day at 9 AM
inputTemplate: 'Generate daily summary',
timezone: 'America/New_York' // Optional
});
console.log('Next run:', schedule.nextRunAt);
// List & delete schedules
const schedules = await client.listSchedules('pipeline_id');
await client.deleteSchedule('pipeline_id', 'schedule_id');Cost Tracking
Monitor token usage, compute costs, and track spending across your pipelines.
// Get cost summary (last 30 days)
const summary = await client.getCostSummary(30);
console.log('Total cost:', summary.totalCostDollars);
console.log('Total tokens:', summary.totalTokens);
console.log('Executions:', summary.executionCount);
// Cost breakdown by pipeline
const pipelineCosts = await client.getPipelineCosts(30);
pipelineCosts.forEach(p => {
console.log(`${p.chainName}: $${p.totalCostDollars}`);
});
// Daily cost trend
const trend = await client.getCostTrend(30);
// Cost for a specific execution
const execCost = await client.getExecutionCost('execution_id');
console.log('Node costs:', execCost.nodeCosts);
// Get current cost rates
const rates = await client.getCostRates();API Keys
Programmatically manage your API keys.
// List all API keys
const keys = await client.listApiKeys();
// Create a new API key
const newKey = await client.createApiKey({ name: 'Production' });
console.log(newKey.key); // sk_... (only shown once!)
// Delete an API key
await client.deleteApiKey('key_id');Error Handling
The SDK throws ShinRAGError for API errors with detailed information.
import { ShinRAGClient, ShinRAGError } from '@shinrag/sdk';
const client = new ShinRAGClient({
apiKey: 'sk_your_api_key_here'
});
try {
const result = await client.executePipeline('pipeline-id', {
input: 'Your query here'
});
console.log(result.output);
} catch (error) {
if (error instanceof ShinRAGError) {
console.error('API Error:', error.message);
console.error('Status Code:', error.statusCode);
console.error('Response:', error.response);
} else {
console.error('Unknown error:', error);
}
}Error Codes
| Status Code | Description |
|---|---|
400 | Bad Request - Invalid request body or missing required fields |
401 | Unauthorized - Invalid or missing API key |
403 | Forbidden - You don't have permission to access this resource (e.g., not a member of the organization) |
404 | Not Found - Resource not found or doesn't belong to your account |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Server error occurred |