CasePilot API Documentation
Integrate AI-powered test case generation into your CI/CD pipeline, CLI tools, or custom workflows.
Overview
CasePilot generates structured, categorized, automation-ready test cases from user story descriptions using a two-pass AI pipeline (Worker + Judge). The Worker generates initial test cases and the Judge reviews them for coverage gaps, duplicates, and quality — producing significantly higher quality than single-pass approaches.
The REST API lets any tool integrate with CasePilot — CI/CD systems, CLI scripts, test management platforms, or custom dashboards. You get the same two-pass AI quality available in the Azure DevOps extension.
https://api.iklab.dev
Authentication
All API endpoints require authentication via an API key. Pass your key using one of these methods:
| Method | Header | Example |
|---|---|---|
| API Key Header | X-API-Key | X-API-Key: cp_live_abc123... |
| Bearer Token | Authorization | Authorization: Bearer cp_live_abc123... |
API keys are created from the CasePilot extension settings panel in Azure DevOps. All keys are prefixed with cp_live_ for production or cp_test_ for testing.
Generate Test Cases
Generate test cases from a user story description. Uses the two-pass Worker + Judge AI pipeline. Each generated test case counts against your monthly usage quota.
Usage & Credits
Returns current credit usage for your organization in the current billing period.
Response:
{
"used": 42,
"limit": 200,
"remaining": 158,
"planId": "starter",
"periodStart": "2026-04-01T00:00:00Z",
"periodEnd": "2026-04-30T23:59:59Z"
}
API Key Management
Create a new API key for your organization. Returns the full key value only once — store it securely.
Request body:
{
"name": "CI Pipeline Key",
"orgId": "my-organization"
}
Response:
{
"id": "key_abc123",
"name": "CI Pipeline Key",
"key": "cp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"createdAt": "2026-04-03T10:00:00Z"
}
List all active API keys for your organization. Key values are masked — only the last 4 characters are shown.
Revoke an API key. The key will immediately stop working for all requests.
Request body:
{
"keyId": "key_abc123"
}
Request Schema
Request body for POST /api/v1/generate:
| Field | Type | Required | Description |
|---|---|---|---|
title | string | required | User story title. Max 500 characters. |
description | string | optional | User story description. Max 5,000 characters. |
acceptanceCriteria | string | optional | Acceptance criteria text. Max 5,000 characters. |
comments | string[] | optional | Discussion comments for additional context. Max 20 items, 2,000 characters each. |
projectKnowledge | object | optional | Project-specific context to improve generation quality. See sub-fields below. |
settings | object | optional | Generation settings. See sub-fields below. |
projectKnowledge sub-fields
| Field | Type | Description |
|---|---|---|
techStack | string | Technology stack description (e.g., "React + Node.js + PostgreSQL"). Max 2,000 characters. |
uiComponents | string | UI component library or patterns used. Max 2,000 characters. |
businessRules | string | Domain-specific business rules or constraints. Max 2,000 characters. |
testingConventions | string | Testing conventions, naming patterns, or frameworks in use. Max 2,000 characters. |
settings sub-fields
| Field | Type | Default | Description |
|---|---|---|---|
maxTestCases | number | 5 | Number of test cases to generate. Range: 1–20. |
categories | string[] | ["positive", "negative", "edge"] | Test case categories to include. Values: "positive", "negative", "edge". |
includeAutomationHints | boolean | true | Include automation hints (selectors, API calls) in output. |
Response Schema
Successful response from POST /api/v1/generate:
{
"testCases": [
{
"title": "Verify successful login with valid credentials",
"description": "Test that a user can log in with correct email and password",
"category": "positive",
"priority": 1,
"preconditions": [
"User account exists with verified email",
"User is on the login page"
],
"steps": [
{
"stepNumber": 1,
"action": "Enter valid email in the email field",
"expectedResult": "Email is displayed in the field",
"testData": "[email protected]"
},
{
"stepNumber": 2,
"action": "Enter valid password in the password field",
"expectedResult": "Password is masked in the field",
"testData": "SecurePass123!"
},
{
"stepNumber": 3,
"action": "Click the Login button",
"expectedResult": "User is redirected to the dashboard",
"testData": null
}
],
"automationHints": "Locate email input: [data-testid='email-input']"
}
],
"metadata": {
"model": "gpt-4o-mini",
"tokensUsed": 2450,
"generationTimeMs": 3200,
"qualityScore": 8,
"coverageGaps": [],
"judgeNotes": "Good coverage of positive and negative scenarios."
},
"usage": {
"used": 47,
"limit": 200,
"remaining": 153,
"planId": "starter"
}
}
testCases[] fields
| Field | Type | Description |
|---|---|---|
title | string | Test case title |
description | string | Brief test case description |
category | string | "positive", "negative", or "edge" |
priority | number | Priority level: 1 (critical) to 4 (low) |
preconditions | string[] | Required preconditions before executing |
steps | object[] | Ordered test steps with stepNumber, action, expectedResult, and optional testData |
automationHints | string | null | Automation guidance (selectors, API calls). Null if includeAutomationHints is false. |
metadata fields
| Field | Type | Description |
|---|---|---|
model | string | AI model used for generation |
tokensUsed | number | Total tokens consumed (Worker + Judge passes) |
generationTimeMs | number | Total generation time in milliseconds |
qualityScore | number | Judge-assigned quality score (1–10) |
coverageGaps | string[] | Any identified coverage gaps |
judgeNotes | string | Judge review commentary |
Code Examples
curl -X POST https://api.iklab.dev/api/v1/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: cp_live_your_api_key_here" \
-d '{
"title": "User can reset password via email",
"description": "As a user, I want to reset my password so I can regain access to my account.",
"acceptanceCriteria": "- User receives reset email within 2 minutes\n- Reset link expires after 24 hours\n- Password must meet complexity requirements",
"settings": {
"maxTestCases": 5,
"categories": ["positive", "negative", "edge"],
"includeAutomationHints": true
}
}'
import requests
API_KEY = "cp_live_your_api_key_here"
BASE_URL = "https://api.iklab.dev"
response = requests.post(
f"{BASE_URL}/api/v1/generate",
headers={
"Content-Type": "application/json",
"X-API-Key": API_KEY,
},
json={
"title": "User can reset password via email",
"description": "As a user, I want to reset my password so I can regain access.",
"acceptanceCriteria": (
"- User receives reset email within 2 minutes\n"
"- Reset link expires after 24 hours\n"
"- Password must meet complexity requirements"
),
"settings": {
"maxTestCases": 5,
"categories": ["positive", "negative", "edge"],
"includeAutomationHints": True,
},
},
)
data = response.json()
for tc in data["testCases"]:
print(f"[{tc['category']}] {tc['title']}")
const API_KEY = "cp_live_your_api_key_here";
const BASE_URL = "https://api.iklab.dev";
const response = await fetch(`${BASE_URL}/api/v1/generate`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
},
body: JSON.stringify({
title: "User can reset password via email",
description: "As a user, I want to reset my password so I can regain access.",
acceptanceCriteria: [
"- User receives reset email within 2 minutes",
"- Reset link expires after 24 hours",
"- Password must meet complexity requirements",
].join("\n"),
settings: {
maxTestCases: 5,
categories: ["positive", "negative", "edge"],
includeAutomationHints: true,
},
}),
});
const data = await response.json();
for (const tc of data.testCases) {
console.log(`[${tc.category}] ${tc.title}`);
}
using var client = new HttpClient();
client.BaseAddress = new Uri("https://api.iklab.dev");
client.DefaultRequestHeaders.Add("X-API-Key", "cp_live_your_api_key_here");
var request = new
{
title = "User can reset password via email",
description = "As a user, I want to reset my password so I can regain access.",
acceptanceCriteria = string.Join("\n", new[]
{
"- User receives reset email within 2 minutes",
"- Reset link expires after 24 hours",
"- Password must meet complexity requirements"
}),
settings = new
{
maxTestCases = 5,
categories = new[] { "positive", "negative", "edge" },
includeAutomationHints = true
}
};
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("/api/v1/generate", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
Error Codes
| Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Invalid request body. Check required fields, field lengths, and value constraints. The response body includes a message field describing the specific validation failure. |
401 | UNAUTHORIZED | Missing or invalid API key. Verify your X-API-Key header or Authorization: Bearer token. |
429 | RATE_LIMITED | Too many requests. You have exceeded 30 requests per minute. Back off and retry with exponential backoff. |
429 | USAGE_LIMIT_EXCEEDED | Monthly test case quota exhausted. Upgrade your plan or wait for the next billing period. |
500 | INTERNAL_ERROR | Unexpected server error. Retry the request. If the issue persists, contact support. |
503 | SERVICE_UNAVAILABLE | The AI service is temporarily unavailable. Retry after a brief delay. |
All error responses follow this format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Field 'title' is required and must not be empty."
}
}
Rate Limits
API requests are rate-limited using a sliding window per API key:
| Limit | Window | Scope |
|---|---|---|
| 30 requests | 1 minute | Per API key |
Rate limit headers are included in every response:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per window |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
429 response, use the X-RateLimit-Reset header to determine when to retry. Implement exponential backoff for best results.
Usage & Billing
API usage shares the same credit pool as the Azure DevOps extension. Credits are metered per test case generated (not per API request). A single request generating 5 test cases consumes 5 credits.
| Plan | Monthly Credits | API Access |
|---|---|---|
| Free | 20 | No |
| Starter ($35/mo) | 200 | Yes |
| Pro ($79/mo) | 1,000 | Yes |
| Team ($149/mo) | 3,000 | Yes |
| Enterprise | Unlimited | Yes |
Monitor your usage by calling GET /api/v1/usage or checking the usage field in generation responses.