yapi
CLI-first API testing for HTTP, GraphQL, gRPC, and TCP. 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
Free to install — no account needed
Copy the command below and paste into your agent.
Instant access • No coding needed • No account needed
What you get in 5 minutes
- Full skill code ready to install
- Works with 4 AI agents
- Lifetime updates included
Description
# 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: [email protected] 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 == "[email protected]" ``` ### 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: "[email protected]" 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 steps
Security Status
Unvetted
Not yet security scanned
Related AI Tools
More Make Money tools you might like
Insert instructions below
FreeReplace with description of the skill and when Claude should use it.
Marketing Skills Division
Free"42 marketing agent skills and plugins for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw, and 6 more coding agents. 7 pods: content, SEO, CRO, channels, growth, intelligence, sales. Foundation context + orchestration router. 27 Python tools (stdli
Engineering Team Skills
Free"23 engineering agent skills and plugins for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw, and 6 more tools. Architecture, frontend, backend, QA, DevOps, security, AI/ML, data engineering, Playwright, Stripe, AWS, MS365. 30+ Python tools (stdlib-
Business & Growth Skills
Free"4 business growth agent skills and plugins for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw. Customer success (health scoring, churn), sales engineer (RFP), revenue operations (pipeline, GTM), contract & proposal writer. Python tools (stdlib-onl
C-Level Advisory Ecosystem
Free"10 C-level advisory agent skills and plugins for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw. CEO, CTO, COO, CPO, CMO, CFO, CRO, CISO, CHRO, Executive Mentor. Multi-role board meetings, strategy routing, structured recommendations. For founders
NotebookLM Automation
FreeComplete API for Google NotebookLM - full programmatic access including features not in the web UI. Create notebooks, add sources, generate all artifact types, download in multiple formats. Activates on explicit /notebooklm or intent like "create a p