apipilot-cli
v1.2.1
Published
Library for API Testing
Readme
🚀 ApiPilot
🧪 Lightweight & Type-Safe API Testing Framework for TypeScript
ApiPilot is a lightweight, fully type-safe API testing framework built with TypeScript.
It helps you define reusable API services, create tests with dynamic data dependencies, build end-to-end test flows, and generate execution reports with Markdown and Mermaid diagrams.
🎯 Write your API tests once, connect them into flows, and let ApiPilot handle the data between requests.
✨ Features
- 🧩 Reusable API Services — Define your endpoints once and reuse them across multiple tests.
- 🧪 Powerful Test Cases — Add assertions and validate API responses.
- 🔗 Dynamic Data Flow — Use values from previous tests in subsequent requests.
- 🔀 Test Flows — Combine multiple test cases into complete end-to-end scenarios.
- 📝 Markdown Reports — Automatically generate detailed execution reports.
- 📊 Mermaid Diagrams — Visualize your test execution flow.
- 🔐 Type Safety — Fully typed request, response, and parameter definitions.
- ⚡ Dynamic Parameters — Inject values into paths, bodies, and headers.
- ♻️ Service Reusability — Keep your API definitions centralized and maintainable.
📦 Installation
Install ApiPilot using npm:
npm install apipilot⚠️ The CLI is planned and will be available in a future release.
npm install -g apipilot⚡ Quick Start
1️⃣ Define your API services
Create reusable service definitions for your API endpoints:
export const serviceSignUp =
ApiPilot.createService<SignUpRequest, SignUpResponse>({
id: "SIGN_UP",
endpoint: "http://localhost:4000/auth/sign-up",
method: HttpMethod.POST,
});
export const serviceVerifyEmail = ApiPilot.createService<
void,
void,
{ tokenVerification: string }
>({
id: "VERIFY_EMAIL",
endpoint:
"http://localhost:4000/auth/verify-user-email/{tokenVerification}",
method: HttpMethod.GET,
});Each service defines:
- 🆔 A unique identifier
- 🌐 The API endpoint
- 📡 The HTTP method
- 📥 Request type
- 📤 Response type
- 🔧 Optional dynamic parameters
2️⃣ Create your test cases
Create tests using the services defined above:
export const signUpTestService = ApiPilot.createTest({
id: "SIGN_UP",
service: serviceSignUp,
body: {
email,
password,
username,
},
expects: (res) => {
expect(res).toHaveProperty("tokenVerification");
expect(res).toHaveProperty("id");
},
});
export const verifyEmailTestService = ApiPilot.createTest({
id: "VERIFY_EMAIL",
service: serviceVerifyEmail,
params: {
tokenVerification: () =>
signUpTestService.response?.tokenVerification || "",
},
expects: () => {},
});This allows you to build realistic API workflows without manually passing values between tests.
3️⃣ Create and execute a flow
Combine multiple tests into an end-to-end flow:
const flow = ApiPilot.createFlow("FULL_FLOW", [
signUpTestService,
verifyEmailTestService,
]);
ApiPilot.add(flow);
await ApiPilot.run();
await ApiPilot.generateReportMermaid();Your flow will execute the tests in the defined order and generate the corresponding reports.
🔄 Dynamic Data
One of ApiPilot's main features is the ability to use values generated by previous tests.
🔐 Dynamic path parameters
export const verifyEmailTestService = ApiPilot.createTest({
id: "VERIFY_EMAIL",
service: serviceVerifyEmail,
params: {
tokenVerification: () =>
signUpTestService.response?.tokenVerification || "",
},
expects: () => {},
});With the service:
endpoint:
"http://localhost:4000/auth/verify-user-email/{tokenVerification}"ApiPilot resolves:
{tokenVerification}
↓
actual value📨 Dynamic headers
You can also inject values into request headers:
headers: {
Authorization: "Bearer {token}",
},
params: {
token: () =>
signInTestService.response?.credentials.token || "",
},This is useful for authentication flows where one request generates a token used by subsequent requests.
📦 Dynamic request body
Values can also be injected into request bodies:
export const signInTestService = ApiPilot.createTest({
id: "SIGN_IN",
service: serviceSignIn,
body: {
email,
password,
mfaCode: "{mfaCode}",
},
params: {
mfaCode: () =>
getMfaCodeTestService.response?.tokenMfa || "",
},
expects: (result) => {
expect(result).toHaveProperty("credentials");
expect(result.credentials).toHaveProperty("token");
},
});🔢 Values from arrays
Dynamic parameters can also reference values inside arrays:
params: {
id: () =>
getListItems.response?.[0].id || "",
},
endpoint: "http://localhost:4000/items/{id}",This makes it possible to chain complex API scenarios together.
🏥 Health Check Example
Requests without a body are also supported.
export const healthCheck = ApiPilot.createTest({
id: "HEALTH_CHECK",
service: ApiPilot.createService<void, { status: string }>({
id: "HEALTH",
endpoint: "http://localhost:4000/health",
method: HttpMethod.GET,
}),
expects: (res) => {
expect(res.status).toBe("ok");
},
});🔀 End-to-End Flows
Flows allow you to combine multiple API tests into a single scenario.
📊 Reports
After executing your flows, ApiPilot can generate reports containing information about the execution.
📝 Markdown report
test-report.mdContains execution information such as:
- Requests
- Responses
- Test results
- Execution details
📈 Mermaid report
mermaid-test-report.mdContains a Mermaid representation of the test flow.
Example:
graph LR
SIGN_UP --> VERIFY_EMAIL
style SIGN_UP fill:#389B35,color:#fff
style VERIFY_EMAIL fill:#389B35,color:#fffThe generated diagram makes it easy to understand how your API tests are connected.
📁 Recommended Project Structure
A typical ApiPilot project can be organized like this:
ApiPilot-tests/
├── 📁 src/
│ └── 📄 services.ts
│
├── 📁 tests/
│ ├── 📄 specs.ts
│ └── 📄 flows.ts
│
└── 📄 test-report.md🧠 Architecture
ApiPilot separates your API testing logic into three main concepts:
🌐 Services
Describe how to communicate with your API.
🧪 Tests
Describe what you want to validate.
🔀 Flows
Describe how multiple tests interact with each other.
📊 Reports
Describe what happened during execution.
This separation keeps your test suite clean and reusable.
💡 Why ApiPilot?
ApiPilot is designed for developers who want API tests to remain:
- 🧹 Clean — Separate API definitions from test logic.
- 🔐 Type-safe — Take advantage of TypeScript throughout the framework.
- ♻️ Reusable — Define services once and reuse them.
- 🔗 Composable — Build complex scenarios from simple tests.
- ⚡ Dynamic — Pass values between dependent requests.
- 📊 Observable — Generate readable execution reports.
- 🧩 Maintainable — Keep large API test suites organized.
🛠️ CLI
🚧 Coming soon
The ApiPilot CLI is planned to simplify project initialization and test execution.
Initialize a project
apitcli startCreate the initial ApiPilot project structure.
Run tests
apitcli runRun all configured test flows.
🗺️ Roadmap
Potential future improvements include:
- 🖥️ CLI support
- 📊 Improved HTML reports
- 🔁 Retry failed requests
- ⏱️ Request timeout configuration
- 🔌 Custom HTTP clients
- 🧩 More assertion helpers
- 📦 Test fixtures
- 🚀 CI/CD integrations
🤝 Contributing
Contributions, ideas, bug reports, and feature requests are welcome.
If you find a problem or have an idea for improving ApiPilot, feel free to open an issue or submit a pull request.
📄 License
ApiPilot is released under the MIT License.
MIT © 2026 h530code