yapi
CLI-first API testing for HTTP, GraphQL, gRPC, and TCP.
About this skill
yapi is a command-line interface tool engineered for robust API testing across diverse protocols, including HTTP, GraphQL, gRPC, and raw TCP. It empowers users and AI agents to adopt a test-driven development (TDD) methodology by defining API expectations in `.yapi.yml` files, executing these tests, and iteratively refining the API implementation until all assertions pass. This approach guarantees the development of resilient and reliable API endpoints. The skill provides extensive environment configuration capabilities through `yapi.config.yml`, allowing for distinct settings for local, staging, and production environments. This includes defining base URLs, environment-specific variables, and loading secrets from `.env` files, ensuring that the same test definitions can be run consistently across various deployment stages without modification. The flexible variable resolution order prioritizes shell environment variables for ultimate control. Key applications range from quick health checks and smoke testing of API endpoints to thorough validation of data structures and status codes. Its inherently automatable, CLI-first nature makes it an ideal candidate for integration into continuous integration/continuous deployment (CI/CD) pipelines, enabling AI agents to autonomously validate API behavior during development, deployment, or regular health monitoring.
Best use case
The primary use case for yapi is facilitating test-driven API development (TDD) and automated validation of API endpoints. Developers, QA engineers, and AI agents benefit significantly by being able to write tests for various API protocols (HTTP, GraphQL, gRPC, TCP) *before* the API code is fully implemented, ensuring correctness and adherence to specifications from the initial stages of development.
CLI-first API testing for HTTP, GraphQL, gRPC, and TCP.
Users should expect a clear pass/fail status and detailed results for API tests, confirming the functionality and adherence of the API endpoint to its specified behavior.
Practical example
Example input
Run the `get-users.yapi.yml` test file against the staging environment and report the results.
Example output
``` Running tests from get-users.yapi.yml (env: staging) GET https://staging.example.com/users ... PASSED (35ms) Status 200 ... PASSED Response body is array ... PASSED All 1 test passed. ```
When to use this skill
- To implement new APIs using a test-driven development (TDD) approach.
- For performing automated smoke tests and health checks on API endpoints.
- To validate API behavior and data consistency across local, staging, and production environments.
- To integrate comprehensive API testing seamlessly into CI/CD pipelines for automated regression.
When not to use this skill
- When only a simple, one-off API request is needed without defining formal tests or assertions.
- For conducting extensive UI-based end-to-end testing, as yapi is exclusively focused on API interactions.
- If the primary requirement is large-scale performance or load testing, rather than functional validation of API behavior.
How yapi Compares
| Feature / Agent | yapi | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | easy | N/A |
Frequently Asked Questions
What does this skill do?
CLI-first API testing for HTTP, GraphQL, gRPC, and TCP.
How difficult is it to install?
The installation complexity is rated as easy. You can find the installation instructions above.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
AI Agents for Coding
Browse AI agent skills for coding, debugging, testing, refactoring, code review, and developer workflows across Claude, Cursor, and Codex.
AI Agents for Startups
Explore AI agent skills for startup validation, product research, growth experiments, documentation, and fast execution with small teams.
Cursor vs Codex for AI Workflows
Compare Cursor and Codex for AI coding workflows, repository assistance, debugging, refactoring, and reusable developer skills.
SKILL.md Source
# yapi
CLI-first API testing for HTTP, GraphQL, gRPC, and TCP.
## The Workflow
yapi enables test-driven API development. Write the test first, then implement until it passes:
1. **Write the test** - Create a `.yapi.yml` file with the expected behavior
2. **Run it** - `yapi run file.yapi.yml` (it will fail)
3. **Implement/fix** - Build the API endpoint
4. **Iterate** - Refine assertions, add edge cases
This loop is the core of agentic API development with yapi.
---
## Environment Setup (Do This First)
Before writing any tests, set up your environments. Create `yapi.config.yml` in your project root:
```yaml
yapi: v1
default_environment: local
environments:
local:
url: http://localhost:3000
vars:
API_KEY: dev_key_123
staging:
url: https://staging.example.com
vars:
API_KEY: ${STAGING_API_KEY} # from shell env
prod:
url: https://api.example.com
vars:
API_KEY: ${PROD_API_KEY}
env_files:
- .env.prod # load secrets from file
```
Now your tests use `${url}` and `${API_KEY}` - same test, any environment:
```bash
yapi run get-users.yapi.yml # uses local (default)
yapi run get-users.yapi.yml --env staging
yapi run get-users.yapi.yml --env prod
```
**Variable resolution order** (highest priority first):
1. Shell environment variables
2. Environment-specific `vars`
3. Environment-specific `env_files`
4. Default `vars`
5. Default `env_files`
---
## A) Smoke Testing
Quick health checks to verify endpoints are alive.
### HTTP
```yaml
yapi: v1
url: ${url}/health
method: GET
expect:
status: 200
```
### GraphQL
```yaml
yapi: v1
url: ${url}/graphql
graphql: |
query { __typename }
expect:
status: 200
assert:
- .data.__typename != null
```
### gRPC
```yaml
yapi: v1
url: grpc://${host}:${port}
service: grpc.health.v1.Health
rpc: Check
plaintext: true
body:
service: ""
expect:
status: 200
```
### TCP
```yaml
yapi: v1
url: tcp://${host}:${port}
data: "PING\n"
encoding: text
expect:
status: 200
```
---
## B) Integration Testing
Multi-step workflows with data passing between requests. Use chains when steps depend on each other.
### Authentication Flow
```yaml
yapi: v1
chain:
- name: login
url: ${url}/auth/login
method: POST
body:
email: test@example.com
password: ${TEST_PASSWORD}
expect:
status: 200
assert:
- .token != null
- name: get_profile
url: ${url}/users/me
method: GET
headers:
Authorization: Bearer ${login.token}
expect:
status: 200
assert:
- .email == "test@example.com"
```
### CRUD Flow
```yaml
yapi: v1
chain:
- name: create
url: ${url}/posts
method: POST
body:
title: "Test Post"
content: "Hello World"
expect:
status: 201
assert:
- .id != null
- name: read
url: ${url}/posts/${create.id}
method: GET
expect:
status: 200
assert:
- .title == "Test Post"
- name: update
url: ${url}/posts/${create.id}
method: PATCH
body:
title: "Updated Post"
expect:
status: 200
- name: delete
url: ${url}/posts/${create.id}
method: DELETE
expect:
status: 204
```
### Running Integration Tests
Name test files with `.test.yapi.yml` suffix:
```
tests/
auth.test.yapi.yml
posts.test.yapi.yml
users.test.yapi.yml
```
Run all tests:
```bash
yapi test ./tests # sequential
yapi test ./tests --parallel 4 # concurrent
yapi test ./tests --env staging # against staging
yapi test ./tests --verbose # detailed output
```
---
## C) Uptime Monitoring
Create test suites for monitoring your services in production.
### Monitor Suite Structure
```
monitors/
api-health.test.yapi.yml
auth-service.test.yapi.yml
database-check.test.yapi.yml
graphql-schema.test.yapi.yml
```
### Health Check with Timeout
```yaml
yapi: v1
url: ${url}/health
method: GET
timeout: 5s # fail if response takes longer
expect:
status: 200
assert:
- .status == "healthy"
- .database == "connected"
```
### Run Monitoring Suite
```bash
# Check all monitors in parallel
yapi test ./monitors --parallel 10 --env prod
# With verbose output for debugging
yapi test ./monitors --parallel 10 --env prod --verbose
```
### CI/CD Integration (GitHub Actions)
```yaml
name: API Health Check
on:
schedule:
- cron: '*/5 * * * *' # every 5 minutes
workflow_dispatch:
jobs:
monitor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install yapi
run: curl -fsSL https://yapi.run/install/linux.sh | bash
- name: Run health checks
env:
PROD_API_KEY: ${{ secrets.PROD_API_KEY }}
run: yapi test ./monitors --env prod --parallel 5
```
### Load Testing
Stress test endpoints or entire workflows:
```bash
# 1000 requests, 50 concurrent
yapi stress api-flow.yapi.yml -n 1000 -p 50
# Run for 30 seconds
yapi stress api-flow.yapi.yml -d 30s -p 25
# Against production (with confirmation)
yapi stress api-flow.yapi.yml -e prod -n 500 -p 10
```
---
## D) Async Job Polling with `wait_for`
For endpoints that process data asynchronously, use `wait_for` to poll until conditions are met.
### Fixed Period Polling
```yaml
yapi: v1
url: ${url}/jobs/${job_id}
method: GET
wait_for:
until:
- .status == "completed" or .status == "failed"
period: 2s
timeout: 60s
expect:
assert:
- .status == "completed"
```
### Exponential Backoff
Better for rate-limited APIs or long-running jobs:
```yaml
yapi: v1
url: ${url}/jobs/${job_id}
method: GET
wait_for:
until:
- .status == "completed"
backoff:
seed: 1s # Initial wait
multiplier: 2 # 1s -> 2s -> 4s -> 8s...
timeout: 300s
```
### Async Workflow Chain
Complete example: create job, poll until done, download result:
```yaml
yapi: v1
chain:
- name: create_job
url: ${url}/jobs
method: POST
body:
type: "data_export"
filters:
date_range: "last_30_days"
expect:
status: 202
assert:
- .job_id != null
- name: wait_for_job
url: ${url}/jobs/${create_job.job_id}
method: GET
wait_for:
until:
- .status == "completed" or .status == "failed"
period: 2s
timeout: 300s
expect:
assert:
- .status == "completed"
- .download_url != null
- name: download_result
url: ${wait_for_job.download_url}
method: GET
output_file: ./export.csv
```
### Webhook/Callback Waiting
Wait for a webhook to be received:
```yaml
yapi: v1
chain:
- name: trigger_action
url: ${url}/payments/initiate
method: POST
body:
amount: 100
expect:
status: 202
- name: wait_for_webhook
url: ${url}/webhooks/received
method: GET
wait_for:
until:
- . | length > 0
- .[0].event == "payment.completed"
period: 1s
timeout: 30s
```
---
## E) Integrated Test Server
Automatically start your dev server, wait for health checks, run tests, and clean up. Configure in `yapi.config.yml`:
```yaml
yapi: v1
test:
start: "npm run dev"
wait_on:
- "http://localhost:3000/healthz"
- "grpc://localhost:50051"
timeout: 60s
parallel: 8
directory: "./tests"
environments:
local:
url: http://localhost:3000
```
### Running with Integrated Server
```bash
# Automatically starts server, waits for health, runs tests, kills server
yapi test
# Skip server startup (server already running)
yapi test --no-start
# Override config from CLI
yapi test --start "npm start" --wait-on "http://localhost:4000/health"
# See server stdout/stderr
yapi test --verbose
```
### Health Check Protocols
| Protocol | URL Format | Behavior |
|----------|------------|----------|
| HTTP/HTTPS | `http://localhost:3000/healthz` | Poll until 2xx response |
| gRPC | `grpc://localhost:50051` | Uses `grpc.health.v1.Health/Check` |
| TCP | `tcp://localhost:5432` | Poll until connection succeeds |
### Local vs CI Parity
The same workflow works locally and in CI:
**Local development:**
```bash
yapi test # starts server, runs tests, cleans up
```
**GitHub Actions:**
```yaml
- uses: jamierpond/yapi/action@main
with:
start: npm run dev
wait-on: http://localhost:3000/healthz
command: yapi test -a
```
---
## Commands Reference
| Command | Description |
|---------|-------------|
| `yapi run file.yapi.yml` | Execute a request |
| `yapi run file.yapi.yml --env prod` | Execute against specific environment |
| `yapi test ./dir` | Run all `*.test.yapi.yml` files |
| `yapi test ./dir --all` | Run all `*.yapi.yml` files (not just tests) |
| `yapi test ./dir --parallel 4` | Run tests concurrently |
| `yapi validate file.yapi.yml` | Check syntax without executing |
| `yapi watch file.yapi.yml` | Re-run on every file save |
| `yapi stress file.yapi.yml` | Load test with concurrency |
| `yapi list` | List all yapi files in directory |
---
## Assertion Syntax
Assertions use JQ expressions that must evaluate to true.
### Body Assertions
```yaml
expect:
status: 200
assert:
- .id != null # field exists
- .name == "John" # exact match
- .age > 18 # comparison
- . | length > 0 # array not empty
- .[0].email != null # first item has email
- .users | length == 10 # exactly 10 users
- .type == "admin" or .type == "user" # alternatives
- .tags | contains(["api"]) # array contains value
```
### Header Assertions
```yaml
expect:
status: 200
assert:
headers:
- .["Content-Type"] | contains("application/json")
- .["X-Request-Id"] != null
- .["Cache-Control"] == "no-cache"
body:
- .data != null
```
### Status Code Options
```yaml
expect:
status: 200 # exact match
status: [200, 201] # any of these
```
---
## Protocol Examples
### HTTP with Query Params and Headers
```yaml
yapi: v1
url: ${url}/api/users
method: GET
headers:
Authorization: Bearer ${API_KEY}
Accept: application/json
query:
limit: "10"
offset: "0"
sort: "created_at"
expect:
status: 200
```
### HTTP POST with JSON Body
```yaml
yapi: v1
url: ${url}/api/users
method: POST
body:
name: "John Doe"
email: "john@example.com"
roles:
- admin
- user
expect:
status: 201
assert:
- .id != null
```
### HTTP Form Data
```yaml
yapi: v1
url: ${url}/upload
method: POST
content_type: multipart/form-data
form:
name: "document.pdf"
description: "Q4 Report"
expect:
status: 200
```
### GraphQL with Variables
```yaml
yapi: v1
url: ${url}/graphql
graphql: |
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
variables:
id: "123"
expect:
status: 200
assert:
- .data.user.id == "123"
```
### gRPC with Metadata
```yaml
yapi: v1
url: grpc://${host}:${port}
service: users.UserService
rpc: GetUser
plaintext: true
headers:
authorization: Bearer ${API_KEY}
body:
user_id: "123"
expect:
status: 200
assert:
- .user.id == "123"
```
### TCP Raw Connection
```yaml
yapi: v1
url: tcp://${host}:${port}
data: |
GET / HTTP/1.1
Host: example.com
encoding: text
read_timeout: 5
expect:
status: 200
```
---
## File Organization
Recommended project structure:
```
project/
yapi.config.yml # environments
.env # local secrets (gitignored)
.env.example # template for secrets
tests/
auth/
login.test.yapi.yml
logout.test.yapi.yml
users/
create-user.test.yapi.yml
get-user.test.yapi.yml
monitors/
health.test.yapi.yml
critical-endpoints.test.yapi.yml
```
---
## Tips
- **Start simple**: Begin with status code checks, add body assertions as needed
- **Use watch mode**: `yapi watch file.yapi.yml` for rapid iteration
- **Validate before running**: `yapi validate file.yapi.yml` catches syntax errors
- **Keep tests focused**: One logical flow per file
- **Name steps clearly**: In chains, use descriptive names like `create_user`, `verify_email`
- **Reference previous steps**: Use `${step_name.field}` to pass data between chain stepsRelated Skills
laravel-expert
Senior Laravel Engineer role for production-grade, maintainable, and idiomatic Laravel solutions. Focuses on clean architecture, security, performance, and modern standards (Laravel 10/11+).
debug-nw
Debug a Nativewind v5 setup issue. Walks through common configuration problems with metro, babel, postcss, and dependencies.
Go Production Engineering
You are a Go production engineering expert. Follow this system for every Go project — from architecture decisions through production deployment. Apply phases sequentially for new projects; use individual phases as needed for existing codebases.
Database Engineering Mastery
> Complete database design, optimization, migration, and operations system. From schema design to production monitoring — covers PostgreSQL, MySQL, SQLite, and general SQL patterns.
afrexai-code-reviewer
Enterprise-grade code review agent. Reviews PRs, diffs, or code files for security vulnerabilities, performance issues, error handling gaps, architecture smells, and test coverage. Works with any language, any repo, no dependencies required.
API Documentation Generator
Generate production-ready API documentation from endpoint descriptions. Outputs OpenAPI 3.0, markdown reference docs, and SDK quickstart guides.
bili-rs
Development skill for bili-rs, a Rust CLI tool for Bilibili (B站). Use when implementing features, fixing bugs, or extending the bilibili-cli-rust codebase. Provides architecture conventions, API endpoints, coding patterns, and project-specific constraints. Triggers on tasks involving adding CLI commands, calling Bilibili APIs, handling authentication, implementing output formatting, or working with the layered cli/commands/client/payloads architecture.
Puppeteer
Automate Chrome and Chromium with Puppeteer for scraping, testing, screenshots, and browser workflows.
pharaoh
Codebase knowledge graph with 23 development workflow skills. Query architecture, dependencies, blast radius, dead code, and test coverage via MCP. Requires GitHub App installation (read-only repo access) and OAuth authentication. Connects to external MCP server at mcp.pharaoh.so.
git-commit-helper
Generate standardized git commit messages following Conventional Commits format. Use this skill when the user asks to commit code, write a commit message, or create a git commit. Enforces team conventions for type prefixes, scope naming, message length, and breaking change documentation.
ask-claude
Delegate a task to Claude Code CLI and immediately report the result back in chat. Supports persistent sessions with full context memory. Safe execution: no data exfiltration, no external calls, file operations confined to workspace. Use when the user asks to run Claude, delegate a coding task, continue a previous Claude session, or any task benefiting from Claude Code's tools (file editing, code analysis, bash, etc.).
bnbchain-mcp
Interact with the BNB Chain Model Context Protocol (MCP) server. Blocks, contracts, tokens, NFTs, wallet, Greenfield, and ERC-8004 agent tools. Use npx @bnb-chain/mcp@latest or read the official skill page.