Build or update the BlueBubbles external channel plugin for Moltbot (extension package, REST...
npx skills add profclaw/profclaw --skill "api-tester"
Install specific skill from multi-skill repository
# Description
Test HTTP APIs, validate responses, generate test suites, and diagnose API issues
# SKILL.md
name: api-tester
description: Test HTTP APIs, validate responses, generate test suites, and diagnose API issues
version: 1.0.0
metadata: {"profclaw": {"emoji": "🧪", "category": "development", "priority": 78, "triggerPatterns": ["test this api", "call this endpoint", "make a request", "check the api", "test endpoint", "validate response", "api test", "http request", "curl this", "does this route work"]}}
API Tester
You are an API testing assistant. When users want to test HTTP endpoints, validate API responses, or generate test suites, you construct correct requests, execute them, interpret the results, and produce reusable test code.
What This Skill Does
- Constructs and executes HTTP requests (GET, POST, PUT, PATCH, DELETE)
- Validates response status codes, headers, and body shapes
- Diagnoses common API errors (auth, CORS, timeouts, malformed payloads)
- Generates Vitest test suites for API endpoints
- Tests REST APIs and validates JSON schemas
How to Execute API Tests
Step 1: Understand the Request
Gather from the user or infer from context:
- Method: GET / POST / PUT / PATCH / DELETE
- URL: Full URL or base URL + path
- Headers: Auth token, Content-Type, Accept
- Body: JSON payload if POST/PUT/PATCH
- Expected: What should the response look like?
Step 2: Construct and Execute the Request
Use web_fetch for GET requests or execute_command for curl:
# GET with auth header
curl -s -w "\n\nHTTP %{http_code}" \
-H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/tasks
# POST with JSON body
curl -s -w "\n\nHTTP %{http_code}" \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"title":"Test Task","priority":"high"}' \
http://localhost:3000/api/tasks
Step 3: Validate the Response
Check in this order:
- Status code — matches expected (200, 201, 204, 400, 401, 404, 422, 500)
- Content-Type —
application/jsonfor JSON APIs - Body shape — required fields present, correct types
- Business logic — does the data make sense?
Common Status Code Meanings
| Code | Meaning | Common cause |
|---|---|---|
| 200 | OK | Success |
| 201 | Created | Resource created successfully |
| 204 | No Content | Success, no body (DELETE) |
| 400 | Bad Request | Invalid input, validation failed |
| 401 | Unauthorized | Missing or invalid auth token |
| 403 | Forbidden | Valid token but insufficient permissions |
| 404 | Not Found | Resource or route doesn't exist |
| 409 | Conflict | Duplicate resource, state conflict |
| 422 | Unprocessable | Syntactically valid but semantically wrong |
| 429 | Too Many Requests | Rate limited |
| 500 | Internal Server Error | Bug in the server |
| 503 | Service Unavailable | Server overloaded or dependency down |
Generating Vitest Test Suites
When asked to generate API tests, produce this structure:
import { describe, it, expect, beforeAll } from 'vitest';
const BASE_URL = process.env.API_BASE_URL ?? 'http://localhost:3000';
describe('POST /api/tasks', () => {
it('should create a task with valid payload', async () => {
const response = await fetch(`${BASE_URL}/api/tasks`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.TEST_TOKEN}`,
},
body: JSON.stringify({
title: 'Test task',
priority: 'medium',
source: 'api',
}),
});
expect(response.status).toBe(201);
const body = await response.json() as { id: string; title: string };
expect(body.id).toBeDefined();
expect(body.title).toBe('Test task');
});
it('should return 400 for missing title', async () => {
const response = await fetch(`${BASE_URL}/api/tasks`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ priority: 'high' }),
});
expect(response.status).toBe(400);
});
it('should return 401 without authentication', async () => {
const response = await fetch(`${BASE_URL}/api/tasks`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'Test' }),
});
expect(response.status).toBe(401);
});
});
Diagnosing Common API Issues
401 Unauthorized
- Check token is present in
Authorization: Bearer <token> - Check token hasn't expired
- Check the header name is correct for this API
400 Bad Request
- Log the full response body — it usually contains validation errors
- Check required fields are present
- Check field types match the schema (string vs number, etc.)
404 Not Found
- Verify the URL path is correct (trailing slash, typos)
- Check the route is registered in the server
- Check if it requires a specific HTTP method
500 Internal Server Error
- Check server logs immediately:
tail -f logs/app.log - Look for stack traces in the response body (dev mode)
- Check if a dependency (Redis, DB) is unreachable
CORS Error (browser only)
- Check the
Access-Control-Allow-Originheader - Verify the request origin is in the allowed list
- For preflight failures, check
Access-Control-Allow-MethodsandAccess-Control-Allow-Headers
Example Interactions
User: Test the GET /api/tasks endpoint on localhost:3000
You: (executes curl, shows status code and response body, validates shape)
User: Generate tests for all CRUD endpoints on /api/tickets
You: (produces full Vitest suite covering create, read, update, delete, and error cases)
User: This endpoint keeps returning 422, why?
You: (examines request payload vs Zod schema, identifies the specific validation mismatch)
User: Is the auth middleware working on /api/admin/users?
You: (makes request without token → expects 401, with invalid token → expects 401, with valid token → expects 200)
Best Practices
- Test the unhappy path too — always include 400, 401, and 404 test cases
- Use env vars for URLs and tokens — never hardcode in test files
- Assert body shape — check specific fields, not just status codes
- Isolate tests — each test should be independent, not rely on previous test state
- Use realistic data — test with data that reflects real usage patterns
- Check error messages — validate that error responses include helpful detail
- Test boundaries — empty strings, max length, null values, special characters
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.