Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sigmic.ai/llms.txt

Use this file to discover all available pages before exploring further.

Node.js Examples

Complete working examples for integrating the Sigmic AI API into your Node.js applications.

Setup

No additional dependencies required - uses built-in fetch (Node.js 18+).
const API_KEY = process.env.SIGMIC_API_KEY || 'sigmic_your_key_here';
const BASE_URL = 'https://api.sigmic.ai';

SSE Stream Parser

Reusable function to parse Server-Sent Events from the stream endpoint:
async function processSSEStream(taskId, handlers = {}) {
  const response = await fetch(`${BASE_URL}/api/v1/tasks/${taskId}/stream`, {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';
  let finalResponse = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    buffer += decoder.decode(value, { stream: true });
    const events = buffer.split('\n\n');
    buffer = events.pop() || '';

    for (const event of events) {
      if (!event.trim() || event.startsWith(':')) continue;

      const lines = event.split('\n');
      const eventType = lines[0]?.replace('event: ', '');
      const dataLine = lines[1]?.replace('data: ', '');

      if (!dataLine) continue;

      try {
        const data = JSON.parse(dataLine);

        // Call appropriate handler
        if (handlers[eventType]) {
          handlers[eventType](data);
        }

        // Capture final response
        if (eventType === 'done') {
          finalResponse = data.finalResponse;
        }
      } catch (e) {
        // Skip malformed JSON
      }
    }
  }

  return { finalResponse };
}

Create Task

async function createTask(message, options = {}) {
  const { systemPrompt, autoExecute = true, files = [] } = options;

  const formData = new FormData();
  formData.append('message', message);
  formData.append('autoExecute', String(autoExecute));

  if (systemPrompt) {
    formData.append('systemPrompt', systemPrompt);
  }

  for (const file of files) {
    formData.append('files', file);
  }

  const response = await fetch(`${BASE_URL}/api/v1/tasks`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}` },
    body: formData
  });

  const { data } = await response.json();
  const taskId = data.id;
  console.log(`Task created: ${taskId}`);

  // Stream the execution
  const result = await processSSEStream(taskId, {
    history_message: (data) => console.log(`[History] ${data.role}: ${data.content?.substring(0, 50)}...`),
    history_done: (data) => console.log(`[History] ${data.messageCount} messages, streaming: ${data.isStreaming}`),
    status: (data) => console.log(`[Status] ${data.message || data.status}`),
    thought: (data) => console.log(`[Thought] ${data.subject}`),
    content: (data) => process.stdout.write(data.text),
    tool_call: (data) => console.log(`[Tool] ${data.toolName}: ${data.status}`),
    error: (data) => console.error(`[Error] ${data.message}`),
    done: () => console.log('\n[Done]')
  });

  return { taskId, ...result };
}

Send Follow-up Message

async function sendFollowUp(taskId, message) {
  // Send the follow-up (fire-and-forget)
  await fetch(`${BASE_URL}/api/v1/tasks/${taskId}/messages`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ message })
  });

  // Stream the response
  return processSSEStream(taskId, {
    history_done: (data) => console.log(`[History] ${data.messageCount} messages loaded`),
    content: (data) => process.stdout.write(data.text),
    done: () => console.log('\n[Done]')
  });
}

Get Task Status

async function getTask(taskId) {
  const response = await fetch(`${BASE_URL}/api/v1/tasks/${taskId}`, {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });

  const result = await response.json();
  if (!result.success) {
    throw new Error(result.error.message);
  }

  return result.data;
}

List Tasks

async function listTasks(limit = 50) {
  const response = await fetch(`${BASE_URL}/api/v1/tasks?limit=${limit}`, {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });

  const result = await response.json();
  if (!result.success) {
    throw new Error(result.error.message);
  }

  return result.data;
}

Cancel Task

async function cancelTask(taskId) {
  const response = await fetch(`${BASE_URL}/api/v1/tasks/${taskId}`, {
    method: 'DELETE',
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });

  const result = await response.json();
  if (!result.success) {
    throw new Error(result.error.message);
  }

  return result.data;
}

List & Download Artifacts

async function listArtifacts(taskId) {
  const response = await fetch(`${BASE_URL}/api/v1/tasks/${taskId}/artifacts`, {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });

  const result = await response.json();
  if (!result.success) {
    throw new Error(result.error.message);
  }

  return result.data.files;
}

async function downloadArtifact(taskId, filePath) {
  const response = await fetch(
    `${BASE_URL}/api/v1/tasks/${taskId}/artifacts/download?path=${encodeURIComponent(filePath)}`,
    { headers: { 'Authorization': `Bearer ${API_KEY}` } }
  );

  if (!response.ok) {
    throw new Error(`Download failed: ${response.status}`);
  }

  return response.arrayBuffer();
}

Tool Approval Handler

async function createTaskWithApproval(message) {
  const formData = new FormData();
  formData.append('message', message);
  formData.append('autoExecute', 'false');

  // Create the task
  const createResponse = await fetch(`${BASE_URL}/api/v1/tasks`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}` },
    body: formData
  });

  const { data: { id: taskId } } = await createResponse.json();

  // Poll for pending approvals
  async function checkApprovals() {
    const task = await getTask(taskId);

    if (task.pendingApprovals?.length > 0) {
      for (const approval of task.pendingApprovals) {
        console.log(`Tool "${approval.toolName}" requires approval`);
        console.log('Args:', JSON.stringify(approval.args, null, 2));

        // Approve (in a real app, you'd prompt the user)
        await fetch(
          `${BASE_URL}/api/v1/tasks/${taskId}/tools/${approval.callId}/approve`,
          {
            method: 'POST',
            headers: {
              'Authorization': `Bearer ${API_KEY}`,
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({ outcome: 'proceed_once' })
          }
        );
      }
    }

    if (!['completed', 'failed', 'cancelled'].includes(task.status)) {
      setTimeout(checkApprovals, 1000);
    }
  }

  // Start polling for approvals in background
  checkApprovals();

  // Stream the execution
  return processSSEStream(taskId, {
    content: (data) => process.stdout.write(data.text),
    done: () => console.log('\n[Done]')
  });
}

Complete Workflow Example

async function main() {
  console.log('=== Sigmic AI API Demo ===\n');

  // 1. Create a task
  console.log('1. Creating task...');
  const { taskId, finalResponse } = await createTask(
    'What are the three laws of robotics?'
  );
  console.log('Task ID:', taskId);
  console.log('Response:', finalResponse);

  // 2. Send follow-up (auto-restores session if expired)
  console.log('\n2. Sending follow-up...');
  const followUp = await sendFollowUp(taskId, 'Who created these laws?');
  console.log('Follow-up response:', followUp.finalResponse);

  // 3. Check task status
  console.log('\n3. Checking task status...');
  const task = await getTask(taskId);
  console.log('Status:', task.status);
  console.log('Created:', task.createdAt);
  console.log('Completed:', task.completedAt);

  // 4. List artifacts
  console.log('\n4. Listing artifacts...');
  const artifacts = await listArtifacts(taskId);
  console.log(`Found ${artifacts.length} files`);
  artifacts.forEach(f => console.log(`  - ${f.name} (${f.size} bytes)`));

  // 5. List recent tasks
  console.log('\n5. Listing recent tasks...');
  const tasks = await listTasks(5);
  console.log(`Found ${tasks.length} tasks:`);
  tasks.forEach(t => console.log(`  - ${t.id}: ${t.status}`));
}

main().catch(console.error);

File Upload Example

import { readFileSync } from 'fs';
import { Blob } from 'buffer';

async function analyzeFile(filePath, question) {
  const fileContent = readFileSync(filePath);
  const fileName = filePath.split('/').pop();
  const file = new Blob([fileContent]);

  const formData = new FormData();
  formData.append('message', question);
  formData.append('files', file, fileName);

  const response = await fetch(`${BASE_URL}/api/v1/tasks`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}` },
    body: formData
  });

  const { data: { id: taskId } } = await response.json();

  return processSSEStream(taskId, {
    content: (data) => process.stdout.write(data.text),
    done: () => console.log('\n')
  });
}

// Usage
await analyzeFile('./data.csv', 'Summarize the data in this CSV file');

Error Handling

class APIError extends Error {
  constructor(code, message) {
    super(message);
    this.code = code;
  }
}

async function makeRequest(url, options = {}) {
  const response = await fetch(url, {
    ...options,
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      ...options.headers
    }
  });

  const data = await response.json();

  if (!data.success) {
    throw new APIError(data.error.code, data.error.message);
  }

  return data;
}

// Usage with error handling
try {
  const task = await getTask('invalid-id');
} catch (error) {
  if (error.code === 'NOT_FOUND') {
    console.log('Task not found');
  } else if (error.code === 'INVALID_API_KEY') {
    console.log('Check your API key');
  } else {
    throw error;
  }
}