{"name":"zTester Integration API","apiVersion":"1.2.0","baseUrl":"https://ztester.zavecoder.com/api/v1","docsUrl":"https://ztester.zavecoder.com/docs","auth":{"type":"api_key","header":"Authorization","format":"Bearer <api_key>","scopes":["read","write","admin"],"obtainAt":"https://ztester.zavecoder.com/dashboard/settings/api-keys"},"capabilities":{"projectAutoDiscovery":true,"recordLogin":true,"testDiscovery":true,"journeyGeneration":true,"selfHealing":true,"batchExecution":true,"autopilot":true},"endpoints":[{"id":"projects.by_repo","method":"GET","path":"/projects","query":{"repoUrl":"string — GitHub/Bitbucket clone URL"},"description":"Look up a zTester project by its linked git repo URL. Use this to auto-map without hardcoding a projectId.","auth":"required","example":{"request":"GET /api/v1/projects?repoUrl=https://github.com/org/repo","response":{"id":"<projectId>","name":"My App","baseUrl":"https://myapp.com"}}},{"id":"projects.run_config","method":"GET","path":"/projects/:projectId/run-config","query":{"environmentId":"string? — defaults to the project default environment"},"description":"Single call that returns everything needed to execute the test suite: active test cases + environment config including auth strategy (recorded sessions, cookies, etc). The primary integration call.","auth":"required","example":{"request":"GET /api/v1/projects/:projectId/run-config","response":{"projectId":"<id>","projectName":"My App","testCount":42,"testCases":[{"id":"<id>","name":"Login flow","steps":[]}],"environment":{"id":"<id>","baseUrl":"https://myapp.com","authStrategy":{"type":"recorded_session","snapshot":"…","capturedAt":"2026-06-01T00:00:00Z"}}}}},{"id":"runs.trigger","method":"POST","path":"/projects/:projectId/runs/trigger","body":{"scope":"\"failed_only\" | \"all\" | \"test_ids\"","testIds":"string[]? — required when scope=test_ids","environmentId":"string? — defaults to project default"},"description":"Trigger a test run. Returns a runId to poll for results. Designed for CI/CD and autonomous fix loops.","auth":"required","example":{"request":"POST /api/v1/projects/:projectId/runs/trigger","body":{"scope":"all"},"response":{"runId":"<id>","status":"running","testCount":42}}},{"id":"runs.get","method":"GET","path":"/test-runs/:runId","description":"Poll run status and results. Poll every 5s until status is passed, failed, or error.","auth":"required","terminalStatuses":["passed","failed","error","cancelled"],"example":{"request":"GET /api/v1/test-runs/:runId","response":{"id":"<id>","status":"passed","passed":38,"failed":4,"total":42,"completedAt":"2026-06-01T00:05:00Z"}}},{"id":"environments.capture_session","method":"POST","path":"/environments/:environmentId/capture-session","body":{"credentials":{"email":"string","password":"string"}},"description":"Record Login — opens a real browser, logs in, captures the session snapshot. Credentials are used once by the runner and immediately discarded. Only the session cookies/localStorage are stored. Re-run when the session expires (typically 1–7 days).","auth":"required","notes":"Works with email+password apps. Does not work with magic-link or SSO — use the cookies auth type instead.","example":{"request":"POST /api/v1/environments/:environmentId/capture-session","body":{"credentials":{"email":"test@example.com","password":"secret"}},"response":{"ok":true,"capturedAt":"2026-06-01T00:00:00Z","cookieCount":6,"hasLocalStorage":true}}},{"id":"test_cases.list","method":"GET","path":"/test-cases","query":{"projectId":"string","status":"\"active\" | \"draft\" | \"archived\" — defaults to all","limit":"number — max 100","offset":"number"},"description":"List test cases for a project with optional status filter.","auth":"required","example":{"request":"GET /api/v1/test-cases?projectId=<id>&status=active","response":{"testCases":[],"total":0}}},{"id":"discovery.trigger","method":"POST","path":"/projects/:projectId/discover-tests","body":{"environmentId":"string?","sourcePaths":"string[]? — repo-relative paths to crawl","maxTests":"number? — default 200"},"description":"Kick off AI test discovery from source code + live URL crawl. Async — poll /discoveries/:discoveryId for progress.","auth":"required","example":{"request":"POST /api/v1/projects/:projectId/discover-tests","body":{"maxTests":50},"response":{"discoveryId":"<id>","status":"running"}}},{"id":"environments.list","method":"GET","path":"/environments","query":{"projectId":"string","id":"string? — fetch a single environment"},"description":"List environments for a project, including full authStrategy (auth type, snapshot age, etc).","auth":"required","example":{"request":"GET /api/v1/environments?projectId=<id>","response":{"environments":[{"id":"<id>","name":"Production","baseUrl":"https://myapp.com","isDefault":true,"authStrategy":{"type":"recorded_session","capturedAt":"…"}}]}}}],"integration":{"minimalFlow":["1. GET /projects?repoUrl=<git_remote>  →  projectId","2. GET /projects/:projectId/run-config  →  { testCases, environment }","3. Pass testCases + environment to your runner, OR:","3. POST /projects/:projectId/runs/trigger  →  runId","4. Poll GET /test-runs/:runId until terminal status"],"authSetup":["1. POST /environments/:envId/capture-session with { credentials }","2. Auth type becomes recorded_session — run-config returns snapshot automatically","3. Re-capture when expired (check environment.authStrategy.capturedAt)"],"sdkNotes":"No SDK required — plain HTTP with an Authorization: Bearer header. Compatible with any language or platform."}}