Skip to main content
The Task API enables programmatic creation of AI-powered tasks with webhook delivery. Tasks are processed asynchronously by Context’s background agents, with results delivered to your configured webhook endpoint.
To get access to Task APIs, contact [email protected]

Base URL and Authentication

The base URL is dependent on your environment. For our public application, the Base URL is
https://api.context.ai/api/v1
All API requests require an API key provided via the Authorization header or x-api-key header:
// Using Authorization header (preferred)
const response = await fetch('https://api.context.ai/api/v1/tasks', {
  headers: {
    'Authorization': 'Bearer ctx_your_api_key',
    'Content-Type': 'application/json'
  }
});

// Using x-api-key header (alternative)
const response = await fetch('https://api.context.ai/api/v1/tasks', {
  headers: {
    'x-api-key': 'ctx_your_api_key',
    'Content-Type': 'application/json'
  }
});

Create Task

Create a new task for asynchronous AI processing with webhook delivery. Endpoint: POST /api/v1/tasks
const response = await fetch('https://api.context.ai/api/v1/tasks', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ctx_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    namespace: 'financial-analysis',
    delivery: {
      type: 'webhook',
      config: {
        endpoint: 'https://yourcompany.com/webhooks/context',
        frequency: 'on_finish'
      }
    },
    input: {
      type: 'chat',
      prompt: 'Analyze the Q3 financial report and provide key insights',
      fileIds: ['file_abc123'],
      workflowIds: ['workflow_xyz789'],
      rulesetIds: ['ruleset_def456'],
      model: 'claude-sonnet-4-20250514'
    }
  })
});

const result = await response.json();
console.log(result.taskId);

Request Body Parameters

FieldTypeRequiredDescription
namespacestringYesLogical grouping for tasks (e.g., department, project)
delivery.typestringYesMust be "webhook"
delivery.config.endpointstringYesWebhook URL to receive task results
delivery.config.frequencystringNoDelivery frequency: "on_finish" (default)
input.typestringYesMust be "chat"
input.promptstringYesThe prompt/instructions for the AI agent
input.fileIdsstring[]NoArray of file IDs to include as attachments
input.workflowIdsstring[]NoArray of workflow IDs to apply
input.rulesetIdsstring[]NoArray of knowledge ruleset IDs to use
input.modelstringNoModel override (must be in tenant’s available models)

Response (201 Created)

{
  "taskId": "123e4567-e89b-12d3-a456-426614174000"
}

Get Task Status

Retrieve the current status and results of a task. Endpoint: GET /api/v1/tasks/:taskId
const response = await fetch(`https://api.context.ai/api/v1/tasks/${taskId}`, {
  headers: {
    'Authorization': 'Bearer ctx_your_api_key'
  }
});

const task = await response.json();
console.log(task.status);

Task Status Values

StatusDescription
waitingTask is queued and waiting to be processed
activeTask is currently being processed
successTask completed successfully
failureTask failed during processing

Response - Waiting or Active

{
  "taskId": "123e4567-e89b-12d3-a456-426614174000",
  "namespace": "financial-analysis",
  "status": "active",
  "createdAt": "2024-01-15T10:30:00.000Z"
}

Response - Success

When a task completes successfully, the response includes the output with generated text and an optional archive containing all results:
{
  "taskId": "123e4567-e89b-12d3-a456-426614174000",
  "namespace": "financial-analysis",
  "status": "success",
  "createdAt": "2024-01-15T10:30:00.000Z",
  "completedAt": "2024-01-15T10:45:00.000Z",
  "output": {
    "text": "Based on my analysis of the Q3 financial report...",
    "archive": {
      "presignedUrl": "https://storage.context.ai/results/...",
      "expiresAt": "2024-01-15T10:55:00.000Z",
      "sizeBytes": 156432
    }
  }
}

Response - Failure

{
  "taskId": "123e4567-e89b-12d3-a456-426614174000",
  "namespace": "financial-analysis",
  "status": "failure",
  "createdAt": "2024-01-15T10:30:00.000Z",
  "completedAt": "2024-01-15T10:35:00.000Z",
  "error": {
    "message": "Task processing failed",
    "code": "PROCESSING_FAILED"
  }
}

Complete Integration Example

End-to-end example demonstrating file upload and task creation:
class ContextTaskClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api.context.ai/api/v1';
  }

  async uploadFile(fileUrl) {
    const response = await fetch(`${this.baseUrl}/files`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ url: fileUrl })
    });

    if (!response.ok) {
      throw new Error(`File upload failed: ${response.statusText}`);
    }

    return response.json();
  }

  async createTask(options) {
    const { namespace, prompt, fileIds, webhookUrl, model } = options;

    const response = await fetch(`${this.baseUrl}/tasks`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        namespace,
        delivery: {
          type: 'webhook',
          config: { endpoint: webhookUrl }
        },
        input: {
          type: 'chat',
          prompt,
          fileIds,
          model
        }
      })
    });

    if (!response.ok) {
      throw new Error(`Task creation failed: ${response.statusText}`);
    }

    return response.json();
  }

  async getTaskStatus(taskId) {
    const response = await fetch(`${this.baseUrl}/tasks/${taskId}`, {
      headers: {
        'Authorization': `Bearer ${this.apiKey}`
      }
    });

    if (!response.ok) {
      throw new Error(`Failed to get task: ${response.statusText}`);
    }

    return response.json();
  }

  async pollUntilComplete(taskId, intervalMs = 5000, maxAttempts = 60) {
    for (let attempt = 0; attempt < maxAttempts; attempt++) {
      const task = await this.getTaskStatus(taskId);

      if (task.status === 'success' || task.status === 'failure') {
        return task;
      }

      await new Promise(resolve => setTimeout(resolve, intervalMs));
    }

    throw new Error('Task polling timeout');
  }
}

// Usage example
const client = new ContextTaskClient(process.env.CONTEXT_API_KEY);

async function analyzeDocument(documentUrl) {
  // Upload the document
  const { fileId } = await client.uploadFile(documentUrl);
  console.log('File uploaded:', fileId);

  // Create analysis task
  const { taskId } = await client.createTask({
    namespace: 'document-analysis',
    prompt: 'Analyze this document and extract key insights, risks, and action items.',
    fileIds: [fileId],
    webhookUrl: 'https://yourcompany.com/webhooks/context'
  });
  console.log('Task created:', taskId);

  // Poll for completion (or wait for webhook)
  const result = await client.pollUntilComplete(taskId);
  console.log('Task completed:', result.status);

  if (result.status === 'success') {
    console.log('Analysis:', result.output.text);
    
    if (result.output.archive) {
      console.log('Download results:', result.output.archive.presignedUrl);
    }
  }

  return result;
}

analyzeDocument('https://yourbucket.s3.amazonaws.com/reports/q3-report.pdf')
  .catch(console.error);

Webhook Delivery

When a task completes, a webhook is sent to your configured endpoint with the full task result:

Webhook Payload - Success

{
  "taskId": "123e4567-e89b-12d3-a456-426614174000",
  "namespace": "financial-analysis",
  "status": "success",
  "createdAt": "2024-01-15T10:30:00.000Z",
  "completedAt": "2024-01-15T10:45:00.000Z",
  "output": {
    "text": "Based on my analysis of the Q3 financial report...",
    "archive": {
      "presignedUrl": "https://storage.context.ai/results/...",
      "expiresAt": "2024-01-15T10:55:00.000Z",
      "sizeBytes": 156432
    }
  }
}

Webhook Payload - Failure

{
  "taskId": "123e4567-e89b-12d3-a456-426614174000",
  "namespace": "financial-analysis",
  "status": "failure",
  "createdAt": "2024-01-15T10:30:00.000Z",
  "completedAt": "2024-01-15T10:35:00.000Z",
  "error": {
    "message": "Task processing failed",
    "code": "PROCESSING_FAILED"
  }
}

Webhook Handler Example

const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhooks/context', (req, res) => {
  const task = req.body;
  
  console.log(`Received webhook for task ${task.taskId}`);
  console.log(`Status: ${task.status}`);
  
  if (task.status === 'success') {
    // Process successful result
    console.log('Output text:', task.output.text);
    
    if (task.output.archive) {
      // Download and process the archive
      downloadArchive(task.output.archive.presignedUrl);
    }
  } else if (task.status === 'failure') {
    // Handle failure
    console.error('Task failed:', task.error.message);
    notifyTeam(task.taskId, task.error);
  }
  
  // Acknowledge receipt
  res.status(200).send('OK');
});

async function downloadArchive(url) {
  const response = await fetch(url);
  const buffer = await response.arrayBuffer();
  // Process the archive contents
}

function notifyTeam(taskId, error) {
  // Send notification to team about failed task
}

app.listen(3000, () => {
  console.log('Webhook server listening on port 3000');
});

Error Handling

Error Response Format

{
  "error": "Error description message"
}

HTTP Status Codes

CodeDescription
201Task created successfully
400Invalid request body or missing required fields
401Missing or invalid API key
404Task not found
500Internal server error

Validation Errors

ErrorCause
delivery.type must be "webhook"Invalid delivery type specified
delivery.config.endpoint is requiredMissing webhook URL
input.type must be "chat"Invalid input type specified
input.prompt is requiredMissing prompt text
namespace is requiredMissing namespace field
input.model must be a non-empty string if providedEmpty model string provided

Testing

Test your Task API integration with this shell script:
#!/bin/bash

API_URL="https://api.context.ai"
API_KEY="your_api_key"
WEBHOOK_URL="https://yourcompany.com/webhooks/context"

# Create a task
echo "Creating task..."
TASK_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/tasks" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"namespace\": \"test\",
    \"delivery\": {
      \"type\": \"webhook\",
      \"config\": {
        \"endpoint\": \"$WEBHOOK_URL\"
      }
    },
    \"input\": {
      \"type\": \"chat\",
      \"prompt\": \"Hello, please respond with a greeting.\"
    }
  }")

TASK_ID=$(echo $TASK_RESPONSE | jq -r '.taskId')
echo "Task ID: $TASK_ID"

# Poll for status
echo "Polling for completion..."
for i in {1..20}; do
  sleep 3
  STATUS=$(curl -s "$API_URL/api/v1/tasks/$TASK_ID" \
    -H "Authorization: Bearer $API_KEY" | jq -r '.status')
  
  echo "Status: $STATUS"
  
  if [ "$STATUS" = "success" ] || [ "$STATUS" = "failure" ]; then
    break
  fi
done

# Get final result
echo "Final result:"
curl -s "$API_URL/api/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $API_KEY" | jq .

Next Steps