Skip to main content

Public REST API

FreeTeamScaleEnterpriseDedicated

The Keploy Public API gives you programmatic access to everything you can do in the Keploy Console—create apps, generate and run test suites, track jobs, and manage API keys. It is designed for CI/CD pipelines, custom automation scripts, and AI agents.

Base URL: https://api.keploy.io/client/v1


Authentication

Every request requires a scoped API key. Send it in one of these headers:

# Option 1: Bearer token
Authorization: Bearer kep_...

# Option 2: Dedicated header
X-API-Key: kep_...

Scopes

API keys are created with one or more scopes that control access:

ScopeWhat it allows
readAll GET endpoints (view apps, suites, runs, jobs)
writeEverything in read + create, update, delete, generate, run
adminEverything in write + API key management + app deletion

Create your first API key

You need an existing admin-scoped key to create keys via the API. To bootstrap your first key, ask your organization admin or create one from the Keploy Console.

Once you have an admin key:

curl -X POST https://api.keploy.io/client/v1/api-keys \
-H "Authorization: Bearer kep_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "CI Pipeline",
"scopes": ["read", "write"],
"ttl_days": 90
}'

The response includes the full key—save it immediately. It is only shown once and cannot be retrieved again.

{
"data": {
"id": "a1b2c3d4-...",
"key": "kep_dGVzdGtleXRl...full-key-here",
"name": "CI Pipeline",
"scopes": ["read", "write"],
"created_at": 1735689600,
"expires_at": 1743465600
},
"meta": {"request_id": "550e8400-...", "timestamp": "2025-01-01T00:00:00Z"}
}

Response format

All endpoints return a consistent JSON envelope:

// Success
{
"data": { ... },
"meta": {
"request_id": "550e8400-...",
"timestamp": "2025-01-01T00:00:00Z",
"pagination": { "has_next_page": true, "next_cursor": "abc123", "total_count": 42 }
}
}

// Error
{
"error": { "code": "VALIDATION_ERROR", "message": "name is required" },
"meta": { "request_id": "550e8400-...", "timestamp": "2025-01-01T00:00:00Z" }
}

On success, error is omitted (not null). On error, data is omitted. The meta object is always present.

Error codes

CodeHTTPWhen it happens
AUTHENTICATION_REQUIRED401Missing, invalid, or expired API key
INSUFFICIENT_SCOPE403Key does not have the required scope
RESOURCE_NOT_FOUND404The resource does not exist or is not in your organization
VALIDATION_ERROR400Bad request body or missing required fields
CONFLICT409Duplicate resource
RATE_LIMITED429Too many requests—check Retry-After header
INTERNAL_ERROR500Unexpected server error—include request_id when reporting

Rate limiting

Each API key is allowed 100 requests per minute with a burst of up to 100.

Every response includes rate-limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 3
  • X-RateLimit-Reset is the number of seconds until at least one token is available again. A value of 0 means you have tokens remaining.
  • When the limit is reached, you receive a 429 response with a Retry-After header (also in seconds).

Quick start: Generate and run tests from the command line

This example generates AI-powered test suites for your API, then runs them—all from curl. The examples use jq to parse JSON responses. Install it with brew install jq (macOS) or apt-get install jq (Linux).

1. Generate test suites

APP_ID="your-app-id"    # from the Keploy Console
API_KEY="kep_your_key"
BASE="https://api.keploy.io/client/v1"

JOB_ID=$(curl -s -X POST "$BASE/apps/$APP_ID/test-suites/generate" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"base_url": "https://api.example.com"}' \
| jq -r '.data.job_id')

echo "Generation job started: $JOB_ID"

2. Stream job progress in real time

curl -N -H "Authorization: Bearer $API_KEY" \
"$BASE/jobs/$JOB_ID/events"

This returns NDJSON—one JSON object per line, streamed as events happen.

3. Run all test suites

RUN_JOB=$(curl -s -X POST "$BASE/apps/$APP_ID/test-suites/run" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"base_url": "https://staging.example.com"}' \
| jq -r '.data.job_id')

echo "Test run job started: $RUN_JOB"

4. Check results

# Get all test runs for the app
curl -s -H "Authorization: Bearer $API_KEY" \
"$BASE/apps/$APP_ID/test-runs" | jq '.data'

Use in CI/CD

Already using the Keploy CLI in CI? See CI/CD Integration for the CLI-based approach. The REST API below is an alternative for environments where installing the CLI is not practical.

GitHub Actions

name: Keploy API Tests
on: [push]

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run Keploy API tests
env:
KEPLOY_API_KEY: ${{ secrets.KEPLOY_API_KEY }}
run: |
APP_ID="your-app-id"
BASE="https://api.keploy.io/client/v1"
AUTH="Authorization: Bearer $KEPLOY_API_KEY"

# Start a test run
JOB_ID=$(curl -s -X POST "$BASE/apps/$APP_ID/test-suites/run" \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{"base_url": "https://staging.example.com"}' \
| jq -r '.data.job_id')

if [ -z "$JOB_ID" ] || [ "$JOB_ID" = "null" ]; then
echo "Failed to start test job. Check APP_ID and API key."
exit 1
fi
echo "Job: $JOB_ID"

# Poll until done (timeout after ~10 minutes)
for i in $(seq 1 60); do
STATUS=$(curl -s "$BASE/jobs/$JOB_ID" -H "$AUTH" | jq -r '.data.job_status')
echo "Attempt $i—Status: $STATUS"
case "$STATUS" in
COMPLETED) echo "Tests passed"; break ;;
FAILED) echo "Tests failed. Inspect: curl -s \"$BASE/apps/$APP_ID/test-runs\" -H \"$AUTH\" | jq"; exit 1 ;;
CANCELLED|STOPPED) echo "Job $STATUS. Check: curl -s \"$BASE/jobs/$JOB_ID\" -H \"$AUTH\" | jq"; exit 1 ;;
*) sleep 10 ;;
esac
done
if [ "$STATUS" != "COMPLETED" ]; then
echo "Timed out waiting for job $JOB_ID"
exit 1
fi

Add KEPLOY_API_KEY as a GitHub Actions secret: Repository Settings → Security → Actions → New Repository Secret.

Python

import requests, json

API_KEY = "kep_your_key"
APP_ID = "your-app-id"
BASE = "https://api.keploy.io/client/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# Trigger test run
resp = requests.post(
f"{BASE}/apps/{APP_ID}/test-suites/run",
headers=HEADERS,
json={"base_url": "https://staging.example.com"},
)
job_id = resp.json()["data"]["job_id"]

# Stream events
with requests.get(f"{BASE}/jobs/{job_id}/events", headers=HEADERS, stream=True) as r:
for line in r.iter_lines():
if line:
event = json.loads(line)
print(event["status"])

Endpoint reference

All paths are relative to https://api.keploy.io/client/v1.

Apps

MethodPathScopeDescription
GET/appsreadList all apps
POST/appswriteCreate an app
GET/apps/{appId}readGet an app
PUT/apps/{appId}writeUpdate an app
DELETE/apps/{appId}adminDelete an app

Create app request:

{"name": "My API", "endpoint": "https://api.example.com"}

Schema coverage

MethodPathScopeDescription
GET/apps/{appId}/schema-coveragereadGet schema coverage report

Returns coverage percentage, covered, uncovered, and partly covered lines, and per-endpoint details. Requires the app to have an OpenAPI schema configured.

Test suites

MethodPathScopeDescription
GET/apps/{appId}/test-suitesreadList test suites (cursor-paginated)
POST/apps/{appId}/test-suiteswriteCreate a test suite
GET/apps/{appId}/test-suites/{suiteId}readGet a test suite
PUT/apps/{appId}/test-suites/{suiteId}writeUpdate a test suite
DELETE/apps/{appId}/test-suites/{suiteId}writeDelete a test suite
POST/apps/{appId}/test-suites/generatewriteGenerate tests using AI
POST/apps/{appId}/test-suites/runwriteRun test suites
POST/apps/{appId}/test-suites/bulk-deletewriteDelete multiple test suites
POST/apps/{appId}/test-suites/{suiteId}/validatewriteValidate a test suite against your API

Generate request:

{
"base_url": "https://api.example.com",
"schema": "openapi: 3.0.0\n...",
"max_test_suites": 30,
"ignore_endpoints": ["/health"],
"timeout": 30
}

Run request:

{
"base_url": "https://staging.example.com",
"test_suite_ids": ["suite-1", "suite-2"]
}

Omit test_suite_ids to run all suites. Both return 202 Accepted with a job_id to track progress.

Jobs

MethodPathScopeDescription
GET/jobsreadList all jobs
GET/jobs/{jobId}readGet a job
POST/jobs/{jobId}/stopwriteStop a running job
GET/jobs/{jobId}/eventsreadStream events (NDJSON)
GET/jobs/{jobId}/validation-resultreadGet validation result for a validate job

The /events endpoint returns newline-delimited JSON. Connect with curl -N or any streaming HTTP client.

Test runs, reports, and normalization

MethodPathScopeDescription
GET/apps/{appId}/test-runsreadList test runs
GET/apps/{appId}/test-runs/{runId}readGet a test run
POST/apps/{appId}/test-runs/{runId}/normalizewriteNormalize a test run (AI)
GET/apps/{appId}/test-runs/{runId}/suite-reportsreadList suite reports (cursor-paginated)
GET/apps/{appId}/test-runs/{runId}/suite-reports/{reportId}readGet a suite report
POST/apps/{appId}/test-runs/{runId}/suite-reports/{reportId}/normalizewriteNormalize a single suite report (AI)

See Test Run Reports for how to interpret report data.

Load tests

MethodPathScopeDescription
POST/apps/{appId}/load-testswriteStart a load test
GET/apps/{appId}/load-testsreadList load test runs
GET/apps/{appId}/load-tests/{runId}readGet load test report
POST/apps/{appId}/load-tests/{runId}/stopwriteStop a running load test
GET/apps/{appId}/load-tests/{runId}/eventsreadStream load test events (NDJSON)

Start load test request:

{
"base_url": "https://staging.example.com",
"virtual_users": 10,
"duration_secs": 60,
"profile": "constant"
}

Generation history

MethodPathScopeDescription
GET/apps/{appId}/generation-historyreadList generation history entries
GET/apps/{appId}/generation-history/{jobId}readGet generation details for a specific job

Subscription and usage

MethodPathScopeDescription
GET/company/subscriptionreadGet current subscription plan and status
GET/company/usagereadGet test generation and run usage counts

Users and API keys

MethodPathScopeDescription
GET/users/mereadGet current authenticated user info
POST/api-keysadminCreate a new API key
GET/api-keysadminList all API keys for your organization
DELETE/api-keys/{keyId}adminRevoke an API key

Create API key request:

{
"name": "Production CI",
"scopes": ["read", "write"],
"ttl_days": 90
}

Valid scopes: read, write, admin. Omit ttl_days for a key that never expires.


Pagination

Set these variables first (same as the quick start section above):

API_KEY="kep_your_key"
APP_ID="your-app-id"
BASE="https://api.keploy.io/client/v1"

Cursor-based (test suites, suite reports):

# First page
curl -H "Authorization: Bearer $API_KEY" "$BASE/apps/$APP_ID/test-suites?page_size=10"

# Next page
curl -H "Authorization: Bearer $API_KEY" "$BASE/apps/$APP_ID/test-suites?page_size=10&after=CURSOR"

Offset-based (apps, test runs, jobs):

curl -H "Authorization: Bearer $API_KEY" "$BASE/apps?offset=0&limit=20"

Maximum limit is 100. Default is 20.