API Documentation - sebiboga/testlink-upgraded GitHub Wiki
TestLink Upgraded provides comprehensive APIs for programmatic access to test management functionality.
TestLink offers three API versions:
- REST API v3 (Latest, recommended)
- REST API v2 (Legacy)
- REST API v1 (Legacy)
- XMLRPC API v1 (Legacy)
https://your-testlink-instance/api/rest/v3
All REST API v3 requests require authentication. Supports:
- Bearer Token (Recommended)
- Basic Auth (User/Password)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://your-testlink-instance/api/rest/v3/whoamicurl -u username:password \
https://your-testlink-instance/api/rest/v3/whoami- GET /whoami - Get current user information
- POST /login - Authenticate and get token
- POST /logout - Revoke current session
- GET /projects - List all test projects
- GET /projects/{id} - Get project details
- POST /projects - Create new test project
- PUT /projects/{id} - Update project
- DELETE /projects/{id} - Delete project
- GET /projects/{id}/testcases - List test cases in project
- GET /testcases/{id} - Get test case details
- POST /testcases - Create test case
- PUT /testcases/{id} - Update test case
- DELETE /testcases/{id} - Delete test case
- GET /projects/{id}/plans - List test plans
- GET /plans/{id} - Get plan details
- POST /plans - Create test plan
- PUT /plans/{id} - Update plan
- DELETE /plans/{id} - Delete plan
- POST /execution/create - Record test execution result
- GET /execution/{id} - Get execution details
- GET /execution/history - Get execution history
- GET /projects/{id}/builds - List builds
- POST /builds - Create build
- PUT /builds/{id} - Update build
- GET /requirements - List requirements
- GET /requirements/{id} - Get requirement details
- POST /requirements - Create requirement
- PUT /requirements/{id} - Update requirement
- GET /keywords - List keywords
- POST /keywords - Create keyword
- DELETE /keywords/{id} - Delete keyword
Content-Type: application/json
Authorization: Bearer TOKEN
{
"status": "success|error",
"data": { ... },
"message": "Status message",
"code": 200
}Request:
curl -X POST https://your-testlink-instance/api/rest/v3/testcases \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Login Test",
"project_id": 1,
"suite_id": 5,
"description": "Test user login functionality",
"steps": [
{
"actions": "Navigate to login page",
"expected_results": "Login form is displayed"
}
]
}'Response:
{
"status": "success",
"data": {
"id": 123,
"name": "Login Test",
"external_id": "TC-001",
"created_at": "2024-01-15T10:30:00Z"
}
}Request:
curl -X POST https://your-testlink-instance/api/rest/v3/execution/create \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"testcase_id": 123,
"plan_id": 45,
"build_id": 10,
"platform_id": 2,
"status": "passed",
"notes": "Test executed successfully",
"duration": 120
}'Response:
{
"status": "success",
"data": {
"execution_id": 456,
"testcase_id": 123,
"status": "passed",
"executed_at": "2024-01-15T11:00:00Z"
}
}For full parameter-by-parameter documentation of every method (required vs optional params, return shape, known quirks), see XMLRPC-Method-Reference.
https://your-testlink-instance/lib/api/xmlrpc/v1/xmlrpc.php
Every XMLRPC method call takes a devKey parameter rather than an HTTP
auth header - the whole request, including the key, is the XML body of a
single POST.
- Log in to TestLink.
- Click your username in the top right corner (opens "My Settings").
- Scroll to the API interface section.
- Click Generate a new key. The key appears next to "Personal API access key". Copy it - generating a new one invalidates the old one.
There is no separate login call: every method call authenticates itself via
devKey.
XMLRPC requests are plain XML, not JSON - there is no REST-style URL
routing. Every call POSTs to the same endpoint with Content-Type: text/xml,
and the method name and parameters travel inside the body:
<?xml version="1.0"?>
<methodCall>
<methodName>tl.someMethod</methodName>
<params>
<param>
<value>
<struct>
<member><name>devKey</name><value><string>YOUR_KEY</string></value></member>
<!-- other parameters as struct members -->
</struct>
</value>
</param>
</params>
</methodCall>No XMLRPC library is required to call it - any HTTP client that can POST a literal XML body works, as in the examples below.
This list is pulled directly from the callback registry in
lib/api/xmlrpc/v1/xmlrpc.class.php (89 registered method names / 87
distinct behaviors - tl.ping/tl.sayHello and tl.reportTCResult/
tl.setTestCaseExecutionResult are aliases of the same implementation).
There is no tl.whoami or tl.getBuilds method in this codebase, despite
those names appearing in some generic TestLink documentation elsewhere -
use tl.checkDevKey/tl.getUserByLogin and tl.getBuildsForTestPlan
instead.
Utility / Auth - checkDevKey, about, testLinkVersion,
setTestMode, ping/sayHello, repeat
Users - doesUserExist, createUser, setUserRoleOnProject,
getUserByLogin, getUserByID
Projects - getProjects, createTestProject, deleteTestProject,
getTestProjectByName, getProjectKeywords, getProjectPlatforms,
getProjectTestPlans, createPlatform
Test Suites - createTestSuite, getTestSuite, getTestSuiteByID,
updateTestSuite, getTestSuitesForTestPlan, getTestSuitesForTestSuite,
getFirstLevelTestSuitesForTestProject, getTestSuiteAttachments,
uploadTestSuiteAttachment, getTestSuiteCustomFieldDesignValue,
updateTestSuiteCustomFieldDesignValue
Test Cases - createTestCase, updateTestCase,
createTestCaseSteps, deleteTestCaseSteps, getTestCase,
getTestCaseIDByName, getTestCasesForTestSuite,
getTestCasesForTestPlan, getFullPath, setTestCaseExecutionType,
setTestCaseTestSuite, getTestCaseAttachments,
uploadTestCaseAttachment, getTestCaseCustomFieldDesignValue,
updateTestCaseCustomFieldDesignValue,
getTestCaseCustomFieldExecutionValue,
getTestCaseCustomFieldTestPlanDesignValue
Keywords - getTestCaseKeywords, addTestCaseKeywords,
removeTestCaseKeywords
Test Plans - createTestPlan, deleteTestPlan, getTestPlanByName,
getTestPlanPlatforms, getTotalsForTestPlan, addTestCaseToTestPlan,
addPlatformToTestPlan, removePlatformFromTestPlan,
getTestPlanCustomFieldDesignValue
Builds - createBuild, closeBuild, getBuildsForTestPlan,
getLatestBuildForTestPlan, updateBuildCustomFieldsValues,
getExecCountersByBuild
Execution / Results - reportTCResult (alias:
setTestCaseExecutionResult), getLastExecutionResult,
deleteExecution, getExecutionSet, getAllExecutionsResults,
assignTestCaseExecutionTask, unassignTestCaseExecutionTask,
getTestCaseAssignedTester
Requirements - getRequirements, getRequirement, getReqCoverage,
assignRequirements, getTestCaseRequirements,
getReqSpecCustomFieldDesignValue, getRequirementCustomFieldDesignValue,
uploadRequirementAttachment, uploadRequirementSpecificationAttachment
Bugs / generic attachments - getTestCaseBugs,
getIssueTrackerSystem, uploadAttachment, uploadExecutionAttachment,
uploadTestProjectAttachment
Build the request body in a file (create_suite.xml):
<?xml version="1.0"?>
<methodCall>
<methodName>tl.createTestSuite</methodName>
<params>
<param>
<value>
<struct>
<member><name>devKey</name><value><string>YOUR_KEY</string></value></member>
<member><name>testprojectid</name><value><int>13</int></value></member>
<member><name>testsuitename</name><value><string>Aside Menu</string></value></member>
<member><name>details</name><value><string>Test cases exercising the left side navigation menu.</string></value></member>
</struct>
</value>
</param>
</params>
</methodCall>Send it with curl:
curl -s -X POST -H "Content-Type: text/xml" \
--data-binary @create_suite.xml \
https://your-testlink-instance/lib/api/xmlrpc/v1/xmlrpc.phpResponse:
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value>
<array><data>
<value><struct>
<member><name>id</name><value><int>53</int></value></member>
<member><name>name</name><value><string></string></value></member>
<member><name>name_changed</name><value><boolean>0</boolean></value></member>
<member><name>status</name><value><boolean>1</boolean></value></member>
<member><name>operation</name><value><string>createTestSuite</string></value></member>
<member><name>additionalInfo</name><value><string></string></value></member>
<member><name>message</name><value><string>ok</string></value></member>
</struct></value>
</data></array>
</value>
</param>
</params>
</methodResponse>name is only populated when a duplicate-name collision forced TestLink to
generate a different name than the one requested - an empty string there is
normal, not an error, as long as status is true.
parentid is optional; omit it to create a top-level suite under the test
project root, or pass an existing test suite's id to nest it.
Test case creation requires steps as an array of structs, one per step:
<?xml version="1.0"?>
<methodCall>
<methodName>tl.createTestCase</methodName>
<params>
<param>
<value>
<struct>
<member><name>devKey</name><value><string>YOUR_KEY</string></value></member>
<member><name>testsuiteid</name><value><int>54</int></value></member>
<member><name>testcasename</name><value><string>Create a test case via the XML-RPC API</string></value></member>
<member><name>testprojectid</name><value><int>13</int></value></member>
<member><name>authorlogin</name><value><string>admin</string></value></member>
<member><name>summary</name><value><string>Verify that a test case can be created programmatically via tl.createTestCase.</string></value></member>
<member><name>preconditions</name><value><string>A valid API key exists for a user with rights to create test cases.</string></value></member>
<member><name>steps</name>
<value><array><data>
<value><struct>
<member><name>step_number</name><value><int>1</int></value></member>
<member><name>actions</name><value><string>Call tl.createTestCase with a valid devKey, testsuiteid, testprojectid and testcasename.</string></value></member>
<member><name>expected_results</name><value><string>The call returns status true and a new test case id.</string></value></member>
<member><name>execution_type</name><value><int>1</int></value></member>
</struct></value>
</data></array></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>authorlogin, summary and steps are required - the call fails with a
Missing required parameter error without them. execution_type is 1 for
manual, 2 for automated.
These versions are maintained for backward compatibility but should not be used for new integrations. Migrate to v3.
- Login to TestLink
- Go to: Admin → User Management
- Select user → API Token section
- Generate new token
- Copy and store securely
- Treat tokens like passwords
- Rotate tokens regularly
- Use HTTPS only
- Implement token expiration policy
- Revoke unused tokens
- 200 - Success
- 201 - Created
- 400 - Bad Request
- 401 - Unauthorized
- 403 - Forbidden
- 404 - Not Found
- 500 - Server Error
- Use REST API v3 - Latest, most stable version
- Bearer Token Auth - More secure than Basic Auth
- Error Handling - Always check response status
- Pagination - Use limit/offset for large results
- Caching - Cache static data
- Rate Limiting - Implement client-side throttling
- HTTPS Only - Never use HTTP for API calls
- Logging - Log all API interactions for debugging
- GitHub Issues: https://github.com/sebiboga/testlink-upgraded/issues
- Code Examples: lib/api/xmlrpc/v1/poc/