Skip to main content

JavaScript SDK

The official Cortex JavaScript SDK for Node.js and browser environments. Provides TypeScript support and modern async/await patterns.

๐Ÿ“ฆ Installationโ€‹

Node.jsโ€‹

npm install @cortex/sdk
# or
yarn add @cortex/sdk
# or
pnpm add @cortex/sdk

Browser (CDN)โ€‹

<script src="https://cdn.jsdelivr.net/npm/@cortex/sdk@latest/dist/cortex.min.js"></script>

Browser (ES Modules)โ€‹

import Cortex from 'https://cdn.skypack.dev/@cortex/sdk';

๐Ÿš€ Quick Startโ€‹

Node.jsโ€‹

import Cortex from '@cortex/sdk';
// or const Cortex = require('@cortex/sdk');

// Initialize client
const cortex = new Cortex({
apiKey: 'cortex_sk_your_api_key_here'
});

// Search the web
const result = await cortex.search('latest AI developments');
console.log(result.summary);

// Extract content
const content = await cortex.extract('https://example.com/article');
console.log(content.text);

// Validate claim
const validation = await cortex.validate('The iPhone 15 supports USB-C');
console.log(`Validation: ${validation.result}`);

Browserโ€‹

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@cortex/sdk@latest/dist/cortex.min.js"></script>
</head>
<body>
<script>
const cortex = new Cortex({
apiKey: 'cortex_sk_your_api_key_here'
});

async function searchExample() {
try {
const result = await cortex.search('quantum computing news');
document.getElementById('results').innerHTML = result.summary;
} catch (error) {
console.error('Search failed:', error);
}
}
</script>
</body>
</html>

๐Ÿ”ง Configurationโ€‹

Environment Variablesโ€‹

// .env file
CORTEX_API_KEY=cortex_sk_your_api_key_here
CORTEX_BASE_URL=https://api.usecortex.co/v1

// Client automatically reads environment variables
const cortex = new Cortex();

Configuration Objectโ€‹

const cortex = new Cortex({
apiKey: 'cortex_sk_your_api_key_here',
baseURL: 'https://api.usecortex.co/v1',
timeout: 30000,
maxRetries: 3,
retryDelay: 1000,
userAgent: 'MyApp/1.0',
defaultHeaders: {
'X-Custom-Header': 'value'
}
});

Configuration Fileโ€‹

// cortex.config.js
export default {
apiKey: process.env.CORTEX_API_KEY,
baseURL: 'https://api.usecortex.co/v1',
timeout: 30000,
maxRetries: 3
};

// Usage
import config from './cortex.config.js';
const cortex = new Cortex(config);

๐Ÿ” Search APIโ€‹

// Simple search
const result = await cortex.search('quantum computing breakthrough');
console.log(result.summary);
console.log(`Found ${result.sources.length} sources`);
const result = await cortex.search({
query: 'Tesla stock analysis',
maxResults: 10,
language: 'en',
country: 'us',
recency: 'week',
includeSources: true,
domainFilter: {
include: ['reuters.com', 'bloomberg.com'],
exclude: ['reddit.com']
}
});

// Access results
console.log(`Summary: ${result.summary}`);
console.log(`Confidence: ${result.confidenceScore}`);
console.log(`Processing time: ${result.metadata.processingTime}s`);

// Iterate through sources
result.sources.forEach(source => {
console.log(`- ${source.title} (${source.confidence.toFixed(2)})`);
console.log(` ${source.url}`);
console.log(` ${source.snippet}`);
});

Search with Optionsโ€‹

const result = await cortex.search({
query: 'machine learning model performance',
context: {
domain: 'technology',
intent: 'research',
complexity: 'technical'
},
options: {
deepSearch: true,
enableCache: true,
timeout: 20000
}
});
// Stream search results
const stream = cortex.searchStream('breaking news AI');

stream.on('progress', (event) => {
if (event.type === 'source') {
console.log(`Found: ${event.data.title}`);
} else if (event.type === 'summary') {
console.log(`Summary progress: ${event.data.progress}%`);
}
});

stream.on('complete', (result) => {
console.log('Search complete:', result.summary);
});

stream.on('error', (error) => {
console.error('Search failed:', error);
});

Promise-based Streamingโ€‹

const result = await cortex.search({
query: 'breaking news AI',
stream: true,
onProgress: (event) => {
console.log(`Progress: ${event.type}`, event.data);
}
});

console.log('Final result:', result.summary);

๐Ÿ“„ Extract APIโ€‹

URL Extractionโ€‹

// Extract content from URL
const content = await cortex.extract('https://example.com/article');

console.log(`Title: ${content.metadata.title}`);
console.log(`Author: ${content.metadata.author}`);
console.log(`Word count: ${content.metadata.wordCount}`);
console.log(`Content: ${content.text}`);

Advanced Extractionโ€‹

const content = await cortex.extract({
url: 'https://example.com/article',
format: 'markdown',
includeMetadata: true,
extractImages: true,
extractLinks: true,
cleanHtml: true
});

// Access structured content
console.log(`Title: ${content.metadata.title}`);
console.log(`Reading time: ${content.metadata.readingTime}`);
console.log(`Quality score: ${content.qualityScore}`);

// Access images
content.images.forEach(image => {
console.log(`Image: ${image.url} - ${image.alt}`);
});

// Access links
console.log(`Internal links: ${content.links.internal.length}`);
console.log(`External links: ${content.links.external.length}`);

Batch Extractionโ€‹

const urls = [
'https://example1.com/article',
'https://example2.com/article',
'https://example3.com/article'
];

// Extract multiple URLs concurrently
const results = await cortex.extractBatch(urls, { maxConcurrency: 5 });

for (const [url, content] of Object.entries(results)) {
if (content.success) {
console.log(`${url}: ${content.metadata.wordCount} words`);
} else {
console.log(`${url}: Failed - ${content.error}`);
}
}

PDF Extractionโ€‹

// Extract from PDF
const content = await cortex.extract({
url: 'https://example.com/document.pdf',
options: {
extractPages: [1, 2, 3],
preserveLayout: false,
ocrEnabled: true
}
});

console.log(content.text);

โœ… Validate APIโ€‹

Basic Validationโ€‹

// Validate a factual claim
const result = await cortex.validate('The Earth is round');

console.log(`Result: ${result.validationResult}`); // VERIFIED
console.log(`Confidence: ${result.confidenceScore}`);
console.log(`Consensus: ${result.consensusLevel}`);

Advanced Validationโ€‹

const result = await cortex.validate({
claim: 'Tesla delivered over 1.8 million vehicles in 2023',
sources: [
'https://ir.tesla.com/press-release/tesla-q4-2023',
'reuters.com',
'bloomberg.com'
],
context: {
domain: 'automotive',
claimType: 'statistical',
timeSensitive: true
},
options: {
confidenceThreshold: 0.8,
requirePrimarySources: true,
maxSources: 10
}
});

// Analyze evidence
console.log(`Validation: ${result.validationResult}`);
console.log(`Supporting sources: ${result.evidence.supporting.length}`);
console.log(`Contradicting sources: ${result.evidence.contradicting.length}`);

// Review evidence
result.evidence.supporting.forEach(evidence => {
console.log(`+ ${evidence.source}`);
console.log(` Confidence: ${evidence.confidence.toFixed(2)}`);
console.log(` Authority: ${evidence.authorityScore.toFixed(2)}`);
console.log(` Snippet: ${evidence.snippet}`);
});

Batch Validationโ€‹

const claims = [
{ id: 'claim1', claim: 'Python is open source' },
{ id: 'claim2', claim: 'The moon is made of cheese' },
{ id: 'claim3', claim: 'Bitcoin was created in 2009' }
];

const results = await cortex.validateBatch(claims);

results.forEach(result => {
console.log(`${result.id}: ${result.validationResult}`);
});

๐Ÿ“Š Cache APIโ€‹

Query Cacheโ€‹

// Check if result is cached
const cached = await cortex.cache.query('AI developments today');

if (cached.cacheHit) {
console.log('Using cached result');
console.log(`TTL remaining: ${cached.ttlRemaining}s`);
return cached.results;
} else {
// Perform new search
const result = await cortex.search('AI developments today');

// Store in cache
await cortex.cache.store({
query: 'AI developments today',
content: result,
ttl: 3600, // 1 hour
trustLevel: 'high'
});

return result;
}

Cache Managementโ€‹

// Get cache statistics
const stats = await cortex.cache.stats();
console.log(`Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`);
console.log(`Storage used: ${stats.storageUsed}`);

// Clear cache by tags
await cortex.cache.clear({ tags: ['outdated', 'temporary'] });

// Clear old entries
const cutoff = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); // 7 days ago
await cortex.cache.clear({ olderThan: cutoff });

๐Ÿ“ˆ Monitoringโ€‹

Usage Statisticsโ€‹

// Get usage stats
const usage = await cortex.monitoring.usage({ period: 'month' });

console.log(`Requests used: ${usage.requestsUsed}/${usage.requestsLimit}`);
console.log(`Success rate: ${(usage.performanceMetrics.successRate * 100).toFixed(1)}%`);
console.log(`Avg response time: ${usage.performanceMetrics.avgResponseTime.toFixed(2)}s`);
console.log(`Cache hit rate: ${(usage.performanceMetrics.cacheHitRate * 100).toFixed(1)}%`);

Health Monitoringโ€‹

// Check system health
const health = await cortex.monitoring.health();

if (health.status === 'healthy') {
console.log('All systems operational');
} else {
console.log('System issues detected:');
Object.entries(health.services).forEach(([service, status]) => {
if (status.status !== 'healthy') {
console.log(` ${service}: ${status.status}`);
}
});
}

Audit Logsโ€‹

// Get recent audit logs
const logs = await cortex.monitoring.audit({ limit: 100 });

logs.entries.forEach(entry => {
console.log(`${entry.timestamp}: ${entry.endpoint} - ${entry.status}`);
if (entry.status !== 200) {
console.log(` Error: ${entry.error}`);
}
});

๐Ÿšจ Error Handlingโ€‹

Error Typesโ€‹

import Cortex, {
CortexError, // Base error
AuthenticationError, // 401 errors
RateLimitError, // 429 errors
ValidationError, // 400 errors
ServerError // 5xx errors
} from '@cortex/sdk';

try {
const result = await cortex.search('test query');
} catch (error) {
if (error instanceof AuthenticationError) {
console.log(`Auth error: ${error.message}`);
// Handle invalid API key
} else if (error instanceof RateLimitError) {
console.log(`Rate limited: ${error.retryAfter}s`);
// Implement backoff
} else if (error instanceof ValidationError) {
console.log(`Invalid request: ${error.message}`);
// Fix request parameters
} else if (error instanceof ServerError) {
console.log(`Server error: ${error.message}`);
// Retry or report issue
} else if (error instanceof CortexError) {
console.log(`General error: ${error.code} - ${error.message}`);
}
}

Retry Logicโ€‹

async function searchWithRetry(cortex, query, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await cortex.search(query);
} catch (error) {
if (error instanceof RateLimitError) {
if (attempt < maxRetries - 1) {
const delay = error.retryAfter * 1000 || Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
} else if (error instanceof ServerError) {
if (attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
}
throw error;
}
}

throw new Error('Max retries exceeded');
}

// Usage
const result = await searchWithRetry(cortex, 'AI developments');

๐Ÿ”ง Advanced Featuresโ€‹

Request Interceptorsโ€‹

// Add request interceptor
cortex.interceptors.request.use(
(config) => {
console.log(`Making request to ${config.url}`);
config.headers['X-Request-ID'] = Math.random().toString(36);
return config;
},
(error) => {
console.error('Request error:', error);
return Promise.reject(error);
}
);

// Add response interceptor
cortex.interceptors.response.use(
(response) => {
console.log(`Response: ${response.status} in ${response.duration}ms`);
return response;
},
(error) => {
console.error('Response error:', error);
return Promise.reject(error);
}
);

AbortController Supportโ€‹

// Abort long-running requests
const controller = new AbortController();

// Set timeout to abort after 10 seconds
setTimeout(() => controller.abort(), 10000);

try {
const result = await cortex.search({
query: 'complex search query',
signal: controller.signal
});
console.log(result.summary);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request was aborted');
} else {
console.error('Search failed:', error);
}
}

Custom Fetch Implementationโ€‹

// Use custom fetch (e.g., for Deno, Bun, or custom proxy)
import customFetch from './my-fetch-implementation.js';

const cortex = new Cortex({
apiKey: 'your_key',
fetch: customFetch
});

Middlewareโ€‹

// Add custom middleware
cortex.use((req, next) => {
console.log(`Request: ${req.method} ${req.url}`);
const start = Date.now();

return next(req).then(response => {
console.log(`Response: ${response.status} in ${Date.now() - start}ms`);
return response;
});
});

๐Ÿงช Testingโ€‹

Mock Clientโ€‹

import { MockCortex } from '@cortex/sdk/testing';

// Create mock client
const mockCortex = new MockCortex();

// Add mock responses
mockCortex.addSearchResponse({
query: 'test query',
response: {
summary: 'Test summary',
sources: [],
confidenceScore: 0.9
}
});

// Use in tests
const result = await mockCortex.search('test query');
expect(result.summary).toBe('Test summary');

Jest Integrationโ€‹

// __mocks__/@cortex/sdk.js
export default class MockCortex {
async search(query) {
return {
summary: 'Mocked summary',
sources: [],
confidenceScore: 0.9
};
}

async extract(url) {
return {
text: 'Mocked content',
metadata: { title: 'Mocked title' }
};
}
}

// test.js
import Cortex from '@cortex/sdk';

jest.mock('@cortex/sdk');

test('search returns results', async () => {
const cortex = new Cortex({ apiKey: 'test' });
const result = await cortex.search('test query');

expect(result.summary).toBe('Mocked summary');
});

Vitest Integrationโ€‹

// vitest.config.js
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
environment: 'node',
setupFiles: ['./test/setup.js']
}
});

// test/setup.js
import { vi } from 'vitest';

vi.mock('@cortex/sdk', () => ({
default: vi.fn().mockImplementation(() => ({
search: vi.fn().mockResolvedValue({
summary: 'Mocked summary',
sources: []
})
}))
}));

๐Ÿ“š Framework Integrationโ€‹

React Hookโ€‹

// hooks/useCortex.js
import { useState, useEffect } from 'react';
import Cortex from '@cortex/sdk';

const cortex = new Cortex({
apiKey: process.env.REACT_APP_CORTEX_API_KEY
});

export function useCortexSearch(query) {
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);

useEffect(() => {
if (!query) return;

let cancelled = false;

const performSearch = async () => {
setLoading(true);
setError(null);

try {
const searchResult = await cortex.search(query);
if (!cancelled) {
setResult(searchResult);
}
} catch (err) {
if (!cancelled) {
setError(err);
}
} finally {
if (!cancelled) {
setLoading(false);
}
}
};

performSearch();

return () => {
cancelled = true;
};
}, [query]);

return { result, loading, error };
}

// Component usage
import { useCortexSearch } from './hooks/useCortex';

function SearchComponent() {
const [query, setQuery] = useState('');
const { result, loading, error } = useCortexSearch(query);

return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>

{loading && <div>Searching...</div>}
{error && <div>Error: {error.message}</div>}
{result && (
<div>
<h3>Summary:</h3>
<p>{result.summary}</p>
</div>
)}
</div>
);
}

Next.js API Routeโ€‹

// pages/api/search.js
import Cortex from '@cortex/sdk';

const cortex = new Cortex({
apiKey: process.env.CORTEX_API_KEY
});

export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}

const { query } = req.body;

if (!query) {
return res.status(400).json({ error: 'Query is required' });
}

try {
const result = await cortex.search(query);
res.status(200).json(result);
} catch (error) {
console.error('Search error:', error);
res.status(500).json({ error: 'Search failed' });
}
}

Express.js Middlewareโ€‹

// middleware/cortex.js
import Cortex from '@cortex/sdk';

const cortex = new Cortex({
apiKey: process.env.CORTEX_API_KEY
});

export function addCortexToRequest(req, res, next) {
req.cortex = cortex;
next();
}

// routes/search.js
import express from 'express';
const router = express.Router();

router.post('/search', async (req, res) => {
try {
const result = await req.cortex.search(req.body.query);
res.json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
});

export default router;

Vue.js Pluginโ€‹

// plugins/cortex.js
import Cortex from '@cortex/sdk';

export default {
install(app, options) {
const cortex = new Cortex(options);

app.config.globalProperties.$cortex = cortex;
app.provide('cortex', cortex);
}
};

// main.js
import { createApp } from 'vue';
import CortexPlugin from './plugins/cortex';

const app = createApp(App);

app.use(CortexPlugin, {
apiKey: process.env.VUE_APP_CORTEX_API_KEY
});

// Component usage
<template>
<div>
<input v-model="query" @input="search" />
<div v-if="loading">Searching...</div>
<div v-else-if="result">{{ result.summary }}</div>
</div>
</template>

<script>
import { inject, ref } from 'vue';

export default {
setup() {
const cortex = inject('cortex');
const query = ref('');
const result = ref(null);
const loading = ref(false);

const search = async () => {
if (!query.value) return;

loading.value = true;
try {
result.value = await cortex.search(query.value);
} catch (error) {
console.error('Search failed:', error);
} finally {
loading.value = false;
}
};

return { query, result, loading, search };
}
};
</script>

๐Ÿ“‹ TypeScript Supportโ€‹

Type Definitionsโ€‹

// Import with types
import Cortex, {
SearchResult,
ExtractionResult,
ValidationResult,
CortexConfig,
SearchOptions,
ExtractOptions,
ValidateOptions
} from '@cortex/sdk';

// Configure with types
const config: CortexConfig = {
apiKey: 'cortex_sk_your_api_key_here',
baseURL: 'https://api.usecortex.co/v1',
timeout: 30000
};

const cortex = new Cortex(config);

// Typed search
const searchOptions: SearchOptions = {
query: 'AI developments',
maxResults: 10,
language: 'en',
includeSources: true
};

const result: SearchResult = await cortex.search(searchOptions);

// Type guards
if (result.success) {
console.log(result.summary); // TypeScript knows this exists
result.sources.forEach(source => {
console.log(source.title); // Fully typed
});
}

Generic Typesโ€‹

// Custom result processing
async function processSearchResult<T>(
cortex: Cortex,
query: string,
processor: (result: SearchResult) => T
): Promise<T> {
const result = await cortex.search({ query });
return processor(result);
}

// Usage
const summary = await processSearchResult(
cortex,
'AI news',
(result) => result.summary
);

Next: REST API โ†’ - Direct HTTP API usage without SDK