Integrations API
Connect ProvaLab.io to your existing tools. Set up webhooks to push events to your systems, and configure Jira, Slack, and GitHub integrations to keep everything in sync.
Webhooks
Webhooks send HTTP POST requests to your server when events happen in ProvaLab.io. Use them to trigger CI/CD pipelines, update dashboards, or send custom notifications.
Create a webhook
POST /api/v1/organizations/{organization_id}/webhooks
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | A descriptive name |
url | string | Yes | The URL to receive webhook payloads |
events | array | Yes | Which events to subscribe to |
secret | string | No | Shared secret for signature verification |
active | boolean | No | Whether the webhook is enabled (default: true) |
curl -X POST https://your-tms-instance.com/api/v1/organizations/1/webhooks \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "CI/CD Pipeline Trigger",
"url": "https://ci.yourcompany.com/webhooks/tms",
"events": ["test_run.completed", "test_case.failed"],
"secret": "whsec_your-secret-key",
"active": true
}'
Response 201 Created
{
"id": 1,
"name": "CI/CD Pipeline Trigger",
"url": "https://ci.yourcompany.com/webhooks/tms",
"events": ["test_run.completed", "test_case.failed"],
"active": true,
"created_at": "2025-11-15T10:00:00Z"
}
Available webhook events
| Event | Triggered when |
|---|---|
test_run.started | A test run begins execution |
test_run.completed | A test run finishes (pass or fail) |
test_run.failed | A test run completes with failures |
test_result.created | An individual test result is recorded |
test_case.created | A new test case is added |
test_case.updated | A test case is modified |
test_case.failed | A test case fails during execution |
test_plan.completed | A test plan is marked complete |
Webhook payload format
Every webhook delivery includes these fields:
{
"event": "test_run.completed",
"timestamp": "2025-11-15T11:00:00Z",
"organization_id": 1,
"data": {
// Event-specific data (see examples below)
}
}
Payload example: test run completed
{
"event": "test_run.completed",
"timestamp": "2025-11-15T11:00:00Z",
"organization_id": 1,
"data": {
"test_run": {
"id": 1,
"name": "Sprint 10 Regression",
"status": "completed",
"total_test_cases": 5,
"passed": 4,
"failed": 1,
"skipped": 0,
"pass_rate": 80.0,
"duration": 300,
"started_at": "2025-11-15T10:00:00Z",
"completed_at": "2025-11-15T11:00:00Z"
}
}
}
Payload example: test case failed
{
"event": "test_case.failed",
"timestamp": "2025-11-15T10:30:00Z",
"organization_id": 1,
"data": {
"test_case": {
"id": 2,
"title": "Login with invalid credentials"
},
"test_run": {
"id": 1,
"name": "Sprint 10 Regression"
},
"result": {
"status": "failed",
"error_message": "Expected 'Invalid credentials' but got 'System error'",
"duration": 3.2
}
}
}
Verifying webhook signatures
If you set a secret when creating the webhook, every delivery includes a signature header:
X-TMS-Signature: sha256=a1b2c3d4e5f6...
Verify the signature on your server to confirm the request came from ProvaLab.io:
Python
import hmac
import hashlib
def verify_webhook(payload_body: str, signature_header: str, secret: str) -> bool:
computed = hmac.new(
secret.encode(),
payload_body.encode(),
hashlib.sha256
).hexdigest()
return f"sha256={computed}" == signature_header
Node.js
const crypto = require('crypto');
function verifyWebhook(payloadBody, signatureHeader, secret) {
const computed = crypto
.createHmac('sha256', secret)
.update(payloadBody)
.digest('hex');
return `sha256=${computed}` === signatureHeader;
}
Always verify webhook signatures in production. Without verification, anyone who knows your webhook URL could send fake events.
Integration settings
List available integrations
GET /api/v1/organizations/{organization_id}/integrations
curl https://your-tms-instance.com/api/v1/organizations/1/integrations \
-H "Authorization: Bearer YOUR_TOKEN"
Response 200 OK
{
"integrations": [
{
"type": "jira",
"name": "Jira",
"description": "Link test cases to Jira issues",
"enabled": true,
"configured": true
},
{
"type": "slack",
"name": "Slack",
"description": "Send notifications to Slack",
"enabled": true,
"configured": false
},
{
"type": "github",
"name": "GitHub",
"description": "Sync with GitHub issues and PRs",
"enabled": true,
"configured": false
}
]
}
Configure Jira
POST /api/v1/organizations/{organization_id}/integrations/jira/configure
| Field | Type | Required | Description |
|---|---|---|---|
base_url | string | Yes | Your Jira instance URL |
username | string | Yes | Jira email address |
api_token | string | Yes | Jira API token |
project_key | string | Yes | Default Jira project key |
settings | object | No | Auto-create issues, sync status, etc. |
curl -X POST https://your-tms-instance.com/api/v1/organizations/1/integrations/jira/configure \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"base_url": "https://yourcompany.atlassian.net",
"username": "[email protected]",
"api_token": "your-jira-api-token",
"project_key": "QA",
"settings": {
"auto_create_issues": true,
"sync_status": true
}
}'
Response 200 OK
{
"integration_type": "jira",
"configured": true,
"last_tested": "2025-11-15T10:00:00Z",
"status": "connected"
}
Configure Slack
POST /api/v1/organizations/{organization_id}/integrations/slack/configure
| Field | Type | Required | Description |
|---|---|---|---|
webhook_url | string | Yes | Slack incoming webhook URL |
channel | string | Yes | Target Slack channel |
settings | object | No | Notification preferences |
curl -X POST https://your-tms-instance.com/api/v1/organizations/1/integrations/slack/configure \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://hooks.slack.com/services/T00/B00/xxxx",
"channel": "#qa-alerts",
"settings": {
"notify_on_failure": true,
"notify_on_completion": true
}
}'
Configure GitHub
POST /api/v1/organizations/{organization_id}/integrations/github/configure
| Field | Type | Required | Description |
|---|---|---|---|
access_token | string | Yes | GitHub personal access token or app token |
repository | string | Yes | Repository in owner/repo format |
settings | object | No | Sync preferences |
curl -X POST https://your-tms-instance.com/api/v1/organizations/1/integrations/github/configure \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"access_token": "ghp_xxxxxxxxxxxxxxxxxxxx",
"repository": "acme-corp/web-app",
"settings": {
"sync_issues": true,
"link_pull_requests": true
}
}'
Test an integration connection
Verify that your integration is properly configured and can connect:
POST /api/v1/organizations/{organization_id}/integrations/{integration_type}/test
curl -X POST https://your-tms-instance.com/api/v1/organizations/1/integrations/jira/test \
-H "Authorization: Bearer YOUR_TOKEN"
Response 200 OK
{
"success": true,
"message": "Connection successful",
"details": {
"jira_version": "9.4.0",
"accessible_projects": ["QA", "DEV", "OPS"]
}
}
If the connection fails:
{
"success": false,
"message": "Authentication failed: Invalid API token",
"details": {}
}
Next steps
- AI API -- Generate test cases and analyze failures using AI
- Test Management API -- Core CRUD endpoints for projects, tests, and runs