JavaScript/TypeScript SDK

Official SDK for Node.js and browsers

npm versionGitHub stars

Installation

npm

npm install @qodryx/sdk

yarn

yarn add @qodryx/sdk

pnpm

pnpm add @qodryx/sdk

Quick Start

import { Qodryx } from '@qodryx/sdk';

// Initialize the client
const qodryx = new Qodryx({
  apiKey: process.env.QODRYX_API_KEY,
});

// List projects
const projects = await qodryx.projects.list();
console.log(projects);

// Trigger a security scan
const scan = await qodryx.security.scan({
  projectId: 'proj_abc123',
  types: ['sast', 'secrets', 'dependencies'],
});
console.log(scan);

Configuration

import { Qodryx } from '@qodryx/sdk';

const qodryx = new Qodryx({
  // Required: Your API key
  apiKey: process.env.QODRYX_API_KEY,
  
  // Optional: Base URL (default: https://api.qodryx.com)
  baseUrl: 'https://api.qodryx.com',
  
  // Optional: Request timeout in ms (default: 30000)
  timeout: 60000,
  
  // Optional: Retry configuration
  retryConfig: {
    maxRetries: 3,
    retryOnRateLimit: true,
    retryDelay: 1000,
  },
  
  // Optional: Custom headers
  headers: {
    'X-Custom-Header': 'value',
  },
});

TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

import { Qodryx, Project, SecurityScan, Workflow } from '@qodryx/sdk';

const qodryx = new Qodryx({ apiKey: process.env.QODRYX_API_KEY! });

// All responses are fully typed
const project: Project = await qodryx.projects.get('proj_abc123');
const scan: SecurityScan = await qodryx.security.scan({ projectId: project.id });
const workflow: Workflow = await qodryx.workflows.create({
  projectId: project.id,
  prompt: 'Add user authentication',
});

API Reference

Projects

// List all projects
const projects = await qodryx.projects.list({
  page: 1,
  perPage: 20,
});

// Get a specific project
const project = await qodryx.projects.get('proj_abc123');

// Create a new project
const newProject = await qodryx.projects.create({
  name: 'my-app',
  repository: 'github.com/user/my-app',
  description: 'My awesome app',
});

// Update a project
const updated = await qodryx.projects.update('proj_abc123', {
  name: 'new-name',
});

// Delete a project
await qodryx.projects.delete('proj_abc123');

Workflows

// Create and trigger a workflow
const workflow = await qodryx.workflows.create({
  projectId: 'proj_abc123',
  prompt: 'Add OAuth authentication with Google',
  config: {
    aiProvider: 'anthropic',
    autoDeploy: false,
  },
});

// List workflows
const workflows = await qodryx.workflows.list({
  projectId: 'proj_abc123',
  status: 'running',
});

// Get workflow status
const status = await qodryx.workflows.get('wf_xyz789');

// Get workflow logs
const logs = await qodryx.workflows.logs('wf_xyz789', {
  stage: 'build',
});

// Cancel a workflow
await qodryx.workflows.cancel('wf_xyz789');

// Wait for workflow completion
const result = await qodryx.workflows.waitForCompletion('wf_xyz789', {
  timeout: 300000, // 5 minutes
  pollInterval: 5000, // 5 seconds
});

Security

// Trigger a security scan
const scan = await qodryx.security.scan({
  projectId: 'proj_abc123',
  types: ['sast', 'secrets', 'dependencies'],
  branch: 'main',
});

// Get scan results
const results = await qodryx.security.results('scan_abc123');

// List all findings
const findings = await qodryx.security.findings({
  projectId: 'proj_abc123',
  severity: ['critical', 'high'],
  status: 'open',
});

// Get specific finding
const finding = await qodryx.security.finding('finding_abc123');

// Auto-remediate a finding
const remediation = await qodryx.security.remediate('finding_abc123');

// Ignore a finding
await qodryx.security.ignore('finding_abc123', {
  reason: 'False positive - test file',
});

Deployments

// Trigger a deployment
const deployment = await qodryx.deployments.create({
  projectId: 'proj_abc123',
  environment: 'production',
  provider: 'vercel',
  branch: 'main',
});

// Get deployment status
const status = await qodryx.deployments.get('deploy_abc123');

// List deployments
const deployments = await qodryx.deployments.list({
  projectId: 'proj_abc123',
  environment: 'production',
});

// Rollback a deployment
await qodryx.deployments.rollback('deploy_abc123');

// Get deployment logs
const logs = await qodryx.deployments.logs('deploy_abc123');

Tests

// Generate tests for a file
const tests = await qodryx.tests.generate({
  projectId: 'proj_abc123',
  filePath: 'src/auth/login.ts',
  framework: 'jest',
});

// Run tests
const results = await qodryx.tests.run({
  projectId: 'proj_abc123',
  coverage: true,
});

// Get test coverage
const coverage = await qodryx.tests.coverage('proj_abc123');

Error Handling

import { Qodryx, QodrxyError, RateLimitError, AuthenticationError } from '@qodryx/sdk';

try {
  const scan = await qodryx.security.scan({ projectId: 'proj_abc123' });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof RateLimitError) {
    console.error('Rate limit exceeded, retry after:', error.retryAfter);
  } else if (error instanceof QodrxyError) {
    console.error('API error:', error.code, error.message);
  } else {
    throw error;
  }
}

Streaming Responses

For long-running operations, use streaming to get real-time updates:

// Stream workflow logs
const stream = qodryx.workflows.streamLogs('wf_xyz789');

for await (const log of stream) {
  console.log(log.timestamp, log.stage, log.message);
}

// Stream with event handlers
qodryx.workflows.streamLogs('wf_xyz789', {
  onLog: (log) => console.log(log.message),
  onStageComplete: (stage) => console.log(`${stage} completed`),
  onComplete: () => console.log('Workflow complete'),
  onError: (error) => console.error('Error:', error),
});

Pagination

// Manual pagination
let page = 1;
let hasMore = true;

while (hasMore) {
  const response = await qodryx.projects.list({ page, perPage: 50 });
  console.log(response.data);
  
  hasMore = page < response.meta.totalPages;
  page++;
}

// Auto-pagination helper
for await (const project of qodryx.projects.listAll()) {
  console.log(project);
}

Webhooks

Verify and parse webhook payloads:

import { verifyWebhook, parseWebhookEvent } from '@qodryx/sdk';

// Express.js example
app.post('/webhooks/qodryx', (req, res) => {
  const signature = req.headers['x-qodryx-signature'];
  const payload = JSON.stringify(req.body);
  
  // Verify signature
  if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Parse event
  const event = parseWebhookEvent(req.body);
  
  switch (event.type) {
    case 'workflow.completed':
      console.log('Workflow completed:', event.data.workflowId);
      break;
    case 'security.finding.created':
      console.log('New vulnerability:', event.data.severity);
      break;
  }
  
  res.status(200).send('OK');
});

Browser Usage

The SDK can also be used in browsers (with limitations):

// Note: Don't expose API keys in browser code!
// Use a backend proxy or OAuth flow instead

import { Qodryx } from '@qodryx/sdk/browser';

const qodryx = new Qodryx({
  // Use a session token from your backend
  accessToken: sessionToken,
});

const projects = await qodryx.projects.list();

Examples

Security Scanner

Automated security scanning script

Deploy Automation

Conditional deployment workflow

Webhook Handler

Process QODRYX events

Complete Example: Automated Security Check

import { Qodryx } from '@qodryx/sdk';

async function runSecurityCheck(projectId: string) {
  const qodryx = new Qodryx({
    apiKey: process.env.QODRYX_API_KEY!,
  });
  
  console.log('Starting security scan...');
  
  // Trigger scan
  const scan = await qodryx.security.scan({
    projectId,
    types: ['sast', 'secrets', 'dependencies'],
  });
  
  console.log(`Scan started: ${scan.id}`);
  
  // Wait for completion
  while (true) {
    const status = await qodryx.security.results(scan.id);
    
    if (status.status === 'completed') {
      console.log('Scan completed!');
      
      // Check results
      const criticalFindings = status.findings.filter(
        (f) => f.severity === 'critical'
      );
      
      if (criticalFindings.length > 0) {
        console.error(`Found ${criticalFindings.length} critical issues!`);
        process.exit(1);
      }
      
      console.log('No critical issues found ✓');
      return;
    }
    
    if (status.status === 'failed') {
      throw new Error('Scan failed');
    }
    
    // Wait before polling again
    await new Promise((r) => setTimeout(r, 5000));
  }
}

runSecurityCheck('proj_abc123').catch(console.error);

Next Steps