
Api Tools
- 64 installs
- 19 repo stars
- Updated January 20, 2026
- miles990/claude-software-skills
Helps with backend & apis tasks.
About
api-tools is a Claude Code skill for backend & apis. It helps solo builders move faster with AI-assisted development.
- api-tools
- Backend & APIs
- AI-coding skill
Api Tools by the numbers
- 64 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #3,123 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/miles990/claude-software-skills --skill api-toolsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 64 |
|---|---|
| repo stars | ★ 19 |
| Last updated | January 20, 2026 |
| Repository | miles990/claude-software-skills ↗ |
What it does
Helps with backend & apis tasks.
Files
API Tools
Overview
Tools and techniques for API development, testing, documentation, and debugging.
---
HTTP Clients
cURL
# Basic GET
curl https://api.example.com/users
# GET with headers
curl -H "Authorization: Bearer TOKEN" \
-H "Accept: application/json" \
https://api.example.com/users
# POST with JSON body
curl -X POST \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}' \
https://api.example.com/users
# POST with form data
curl -X POST \
-F "file=@document.pdf" \
-F "name=My Document" \
https://api.example.com/upload
# PUT request
curl -X PUT \
-H "Content-Type: application/json" \
-d '{"name": "Updated Name"}' \
https://api.example.com/users/123
# DELETE request
curl -X DELETE https://api.example.com/users/123
# Show response headers
curl -i https://api.example.com/users
# Verbose output (debugging)
curl -v https://api.example.com/users
# Follow redirects
curl -L https://example.com/redirect
# Save response to file
curl -o response.json https://api.example.com/users
# With authentication
curl -u username:password https://api.example.com/protected
curl --oauth2-bearer TOKEN https://api.example.com/protected
# Measure timing
curl -w "@curl-format.txt" -o /dev/null -s https://api.example.com# curl-format.txt
time_namelookup: %{time_namelookup}s\n
time_connect: %{time_connect}s\n
time_appconnect: %{time_appconnect}s\n
time_pretransfer: %{time_pretransfer}s\n
time_redirect: %{time_redirect}s\n
time_starttransfer: %{time_starttransfer}s\n
----------\n
time_total: %{time_total}s\nHTTPie
# GET request (more readable output)
http https://api.example.com/users
# With headers
http https://api.example.com/users \
Authorization:"Bearer TOKEN" \
Accept:application/json
# POST with JSON (default)
http POST https://api.example.com/users \
name=John \
email=john@example.com
# POST with raw JSON
http POST https://api.example.com/users \
< user.json
# Form data
http -f POST https://api.example.com/login \
username=john \
password=secret
# File upload
http -f POST https://api.example.com/upload \
file@document.pdf
# Download file
http --download https://api.example.com/files/document.pdf
# Session persistence
http --session=user-session POST https://api.example.com/login
http --session=user-session GET https://api.example.com/profile
# Only headers
http --headers https://api.example.com/users
# Only body
http --body https://api.example.com/users---
API Testing
Postman Collections
{
"info": {
"name": "User API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"variable": [
{
"key": "baseUrl",
"value": "https://api.example.com"
},
{
"key": "token",
"value": ""
}
],
"item": [
{
"name": "Auth",
"item": [
{
"name": "Login",
"request": {
"method": "POST",
"url": "{{baseUrl}}/auth/login",
"header": [
{ "key": "Content-Type", "value": "application/json" }
],
"body": {
"mode": "raw",
"raw": "{\"email\": \"{{email}}\", \"password\": \"{{password}}\"}"
}
},
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test('Status code is 200', function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test('Response has token', function () {",
" var jsonData = pm.response.json();",
" pm.expect(jsonData.token).to.be.a('string');",
" pm.collectionVariables.set('token', jsonData.token);",
"});"
]
}
}
]
}
]
},
{
"name": "Users",
"item": [
{
"name": "List Users",
"request": {
"method": "GET",
"url": {
"raw": "{{baseUrl}}/users?page=1&limit=10",
"query": [
{ "key": "page", "value": "1" },
{ "key": "limit", "value": "10" }
]
},
"header": [
{ "key": "Authorization", "value": "Bearer {{token}}" }
]
},
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test('Status code is 200', function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test('Response is an array', function () {",
" var jsonData = pm.response.json();",
" pm.expect(jsonData.data).to.be.an('array');",
"});",
"",
"pm.test('Response time is less than 500ms', function () {",
" pm.expect(pm.response.responseTime).to.be.below(500);",
"});"
]
}
}
]
}
]
}
]
}Newman CLI
# Run Postman collection
newman run collection.json
# With environment
newman run collection.json -e environment.json
# Generate HTML report
newman run collection.json \
--reporters cli,html \
--reporter-html-export report.html
# Run specific folder
newman run collection.json --folder "Users"
# With iteration data
newman run collection.json -d data.json -n 10
# Set environment variables
newman run collection.json \
--env-var "baseUrl=https://staging.api.example.com" \
--env-var "token=xxx"---
OpenAPI / Swagger
OpenAPI Specification
# openapi.yaml
openapi: 3.0.3
info:
title: User API
description: API for managing users
version: 1.0.0
contact:
email: api@example.com
license:
name: MIT
servers:
- url: https://api.example.com/v1
description: Production
- url: https://staging-api.example.com/v1
description: Staging
tags:
- name: Users
description: User management operations
- name: Auth
description: Authentication operations
paths:
/users:
get:
summary: List users
description: Returns a paginated list of users
operationId: listUsers
tags:
- Users
security:
- bearerAuth: []
parameters:
- name: page
in: query
description: Page number
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
description: Items per page
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: search
in: query
description: Search term
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
'401':
$ref: '#/components/responses/Unauthorized'
post:
summary: Create user
operationId: createUser
tags:
- Users
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUser'
responses:
'201':
description: User created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/users/{id}:
get:
summary: Get user by ID
operationId: getUserById
tags:
- Users
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFound'
components:
schemas:
User:
type: object
required:
- id
- email
- createdAt
properties:
id:
type: string
format: uuid
example: "123e4567-e89b-12d3-a456-426614174000"
email:
type: string
format: email
example: "user@example.com"
name:
type: string
example: "John Doe"
role:
type: string
enum: [user, admin]
default: user
createdAt:
type: string
format: date-time
CreateUser:
type: object
required:
- email
- password
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
name:
type: string
UserList:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
meta:
$ref: '#/components/schemas/PaginationMeta'
PaginationMeta:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
totalPages:
type: integer
Error:
type: object
properties:
code:
type: string
message:
type: string
responses:
BadRequest:
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWTGenerate Client SDK
# Generate TypeScript client
npx openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-fetch \
-o ./generated/client
# Generate Python client
openapi-generator generate \
-i openapi.yaml \
-g python \
-o ./generated/python-client---
Mock Servers
Prism (OpenAPI Mock Server)
# Start mock server
npx @stoplight/prism-cli mock openapi.yaml
# With dynamic responses
npx @stoplight/prism-cli mock openapi.yaml --dynamic
# Custom port
npx @stoplight/prism-cli mock openapi.yaml -p 4010JSON Server (Quick REST API)
// db.json
{
"users": [
{ "id": 1, "name": "John", "email": "john@example.com" },
{ "id": 2, "name": "Jane", "email": "jane@example.com" }
],
"posts": [
{ "id": 1, "title": "Hello World", "userId": 1 }
]
}# Start server
npx json-server --watch db.json --port 3001
# Routes automatically created:
# GET /users
# GET /users/1
# POST /users
# PUT /users/1
# DELETE /users/1
# GET /posts?userId=1---
API Debugging
Request/Response Logging
import axios from 'axios';
// Request interceptor
axios.interceptors.request.use((config) => {
console.log('Request:', {
method: config.method?.toUpperCase(),
url: config.url,
params: config.params,
data: config.data,
headers: config.headers,
});
return config;
});
// Response interceptor
axios.interceptors.response.use(
(response) => {
console.log('Response:', {
status: response.status,
headers: response.headers,
data: response.data,
});
return response;
},
(error) => {
console.log('Error:', {
status: error.response?.status,
data: error.response?.data,
});
return Promise.reject(error);
}
);---
Related Skills
- [[api-design]] - API design patterns
- [[testing-strategies]] - API testing
- [[backend]] - Backend development
#!/bin/bash
# ===========================================
# cURL API Examples Template
# Usage: Adapt these examples for your API testing
# ===========================================
# Configuration
BASE_URL="${API_BASE_URL:-http://localhost:3000/api}"
AUTH_TOKEN="${API_TOKEN:-your-token-here}"
# Common headers
HEADERS=(
-H "Content-Type: application/json"
-H "Authorization: Bearer $AUTH_TOKEN"
-H "Accept: application/json"
)
# ===========================================
# GET Requests
# ===========================================
# Simple GET
curl -s "$BASE_URL/users" "${HEADERS[@]}" | jq
# GET with query parameters
curl -s "$BASE_URL/users?page=1&limit=10&sort=name" "${HEADERS[@]}" | jq
# GET single resource
curl -s "$BASE_URL/users/123" "${HEADERS[@]}" | jq
# GET with custom headers
curl -s "$BASE_URL/users" \
"${HEADERS[@]}" \
-H "X-Request-ID: $(uuidgen)" \
| jq
# ===========================================
# POST Requests
# ===========================================
# Create resource (inline JSON)
curl -s -X POST "$BASE_URL/users" \
"${HEADERS[@]}" \
-d '{"name": "John Doe", "email": "john@example.com"}' \
| jq
# Create resource (from file)
curl -s -X POST "$BASE_URL/users" \
"${HEADERS[@]}" \
-d @user.json \
| jq
# Create with heredoc
curl -s -X POST "$BASE_URL/users" \
"${HEADERS[@]}" \
-d @- <<'EOF' | jq
{
"name": "Jane Doe",
"email": "jane@example.com",
"role": "admin"
}
EOF
# ===========================================
# PUT/PATCH Requests
# ===========================================
# Full update (PUT)
curl -s -X PUT "$BASE_URL/users/123" \
"${HEADERS[@]}" \
-d '{"name": "John Updated", "email": "john.new@example.com"}' \
| jq
# Partial update (PATCH)
curl -s -X PATCH "$BASE_URL/users/123" \
"${HEADERS[@]}" \
-d '{"name": "John Patched"}' \
| jq
# ===========================================
# DELETE Requests
# ===========================================
# Delete resource
curl -s -X DELETE "$BASE_URL/users/123" \
"${HEADERS[@]}" \
| jq
# Delete with confirmation body
curl -s -X DELETE "$BASE_URL/users/123" \
"${HEADERS[@]}" \
-d '{"confirm": true}' \
| jq
# ===========================================
# File Upload
# ===========================================
# Single file upload
curl -s -X POST "$BASE_URL/upload" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-F "file=@./document.pdf" \
-F "description=My document" \
| jq
# Multiple files
curl -s -X POST "$BASE_URL/upload" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-F "files[]=@./file1.jpg" \
-F "files[]=@./file2.jpg" \
| jq
# ===========================================
# Authentication
# ===========================================
# Login (get token)
curl -s -X POST "$BASE_URL/auth/login" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "secret"}' \
| jq
# Refresh token
curl -s -X POST "$BASE_URL/auth/refresh" \
-H "Content-Type: application/json" \
-d '{"refreshToken": "your-refresh-token"}' \
| jq
# OAuth2 token exchange
curl -s -X POST "$BASE_URL/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
| jq
# ===========================================
# Advanced Options
# ===========================================
# Verbose mode (see headers)
curl -v "$BASE_URL/users" "${HEADERS[@]}"
# Include response headers
curl -i "$BASE_URL/users" "${HEADERS[@]}"
# Only headers (HEAD request)
curl -I "$BASE_URL/users" "${HEADERS[@]}"
# Follow redirects
curl -L "$BASE_URL/redirect" "${HEADERS[@]}"
# Set timeout
curl -s --connect-timeout 5 --max-time 30 "$BASE_URL/slow-endpoint" "${HEADERS[@]}"
# Retry on failure
curl -s --retry 3 --retry-delay 1 "$BASE_URL/flaky-endpoint" "${HEADERS[@]}"
# ===========================================
# Testing & Debugging
# ===========================================
# Time the request
curl -s -w "\n\nTime: %{time_total}s\nStatus: %{http_code}\n" \
-o /dev/null \
"$BASE_URL/users" "${HEADERS[@]}"
# Save response to file
curl -s "$BASE_URL/users" "${HEADERS[@]}" -o response.json
# Test with different HTTP versions
curl -s --http2 "$BASE_URL/users" "${HEADERS[@]}" | jq
# Ignore SSL certificate (dev only!)
# curl -k "$BASE_URL/users" "${HEADERS[@]}"
# ===========================================
# Batch Operations
# ===========================================
# Loop through IDs
for id in 1 2 3 4 5; do
echo "Fetching user $id..."
curl -s "$BASE_URL/users/$id" "${HEADERS[@]}" | jq '.name'
done
# Parallel requests (requires GNU parallel)
# seq 1 10 | parallel -j 5 "curl -s '$BASE_URL/users/{}' ${HEADERS[*]} | jq '.name'"
{
"_comment": "Postman Collection Template - Export as Postman Collection v2.1",
"info": {
"_postman_id": "template-collection-id",
"name": "API Template Collection",
"description": "Template collection for API testing. Adapt endpoints and variables for your API.",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"variable": [
{
"key": "baseUrl",
"value": "http://localhost:3000/api",
"type": "string"
},
{
"key": "authToken",
"value": "",
"type": "string"
}
],
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{authToken}}",
"type": "string"
}
]
},
"item": [
{
"name": "Auth",
"item": [
{
"name": "Login",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"",
"pm.test('Status is 200', () => {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test('Has access token', () => {",
" pm.expect(response).to.have.property('accessToken');",
"});",
"",
"// Save token for subsequent requests",
"if (response.accessToken) {",
" pm.collectionVariables.set('authToken', response.accessToken);",
"}"
],
"type": "text/javascript"
}
}
],
"request": {
"auth": {
"type": "noauth"
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"email\": \"user@example.com\",\n \"password\": \"password123\"\n}"
},
"url": {
"raw": "{{baseUrl}}/auth/login",
"host": ["{{baseUrl}}"],
"path": ["auth", "login"]
}
}
},
{
"name": "Refresh Token",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"refreshToken\": \"{{refreshToken}}\"\n}"
},
"url": {
"raw": "{{baseUrl}}/auth/refresh",
"host": ["{{baseUrl}}"],
"path": ["auth", "refresh"]
}
}
}
]
},
{
"name": "Users",
"item": [
{
"name": "List Users",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test('Status is 200', () => {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test('Response is array', () => {",
" const response = pm.response.json();",
" pm.expect(response.data).to.be.an('array');",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/users?page=1&limit=10",
"host": ["{{baseUrl}}"],
"path": ["users"],
"query": [
{
"key": "page",
"value": "1"
},
{
"key": "limit",
"value": "10"
}
]
}
}
},
{
"name": "Get User",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test('Status is 200', () => {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test('Has user data', () => {",
" const response = pm.response.json();",
" pm.expect(response).to.have.property('id');",
" pm.expect(response).to.have.property('email');",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/users/:userId",
"host": ["{{baseUrl}}"],
"path": ["users", ":userId"],
"variable": [
{
"key": "userId",
"value": "1"
}
]
}
}
},
{
"name": "Create User",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test('Status is 201', () => {",
" pm.response.to.have.status(201);",
"});",
"",
"pm.test('User created', () => {",
" const response = pm.response.json();",
" pm.expect(response).to.have.property('id');",
" pm.collectionVariables.set('createdUserId', response.id);",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"John Doe\",\n \"email\": \"john@example.com\",\n \"role\": \"user\"\n}"
},
"url": {
"raw": "{{baseUrl}}/users",
"host": ["{{baseUrl}}"],
"path": ["users"]
}
}
},
{
"name": "Update User",
"request": {
"method": "PUT",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"John Updated\",\n \"email\": \"john.updated@example.com\"\n}"
},
"url": {
"raw": "{{baseUrl}}/users/:userId",
"host": ["{{baseUrl}}"],
"path": ["users", ":userId"],
"variable": [
{
"key": "userId",
"value": "{{createdUserId}}"
}
]
}
}
},
{
"name": "Delete User",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test('Status is 204 or 200', () => {",
" pm.expect(pm.response.code).to.be.oneOf([200, 204]);",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "{{baseUrl}}/users/:userId",
"host": ["{{baseUrl}}"],
"path": ["users", ":userId"],
"variable": [
{
"key": "userId",
"value": "{{createdUserId}}"
}
]
}
}
}
]
},
{
"name": "File Upload",
"item": [
{
"name": "Upload File",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": ""
},
{
"key": "description",
"value": "Test file upload",
"type": "text"
}
]
},
"url": {
"raw": "{{baseUrl}}/upload",
"host": ["{{baseUrl}}"],
"path": ["upload"]
}
}
}
]
},
{
"name": "Health",
"item": [
{
"name": "Health Check",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test('API is healthy', () => {",
" pm.response.to.have.status(200);",
" const response = pm.response.json();",
" pm.expect(response.status).to.equal('ok');",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"auth": {
"type": "noauth"
},
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/health",
"host": ["{{baseUrl}}"],
"path": ["health"]
}
}
}
]
}
]
}
API Tools Templates
Scripts and templates for API testing and development.
Files
| File | Purpose |
|---|---|
../scripts/curl-examples.sh | cURL command examples |
postman-collection.json | Postman collection template |
Usage
cURL Examples
# Set environment variables
export API_BASE_URL="http://localhost:3000/api"
export API_TOKEN="your-jwt-token"
# Make executable
chmod +x scripts/curl-examples.sh
# Run examples (copy and modify as needed)
source scripts/curl-examples.shCommon patterns:
# GET with auth
curl -s "$BASE_URL/users" \
-H "Authorization: Bearer $AUTH_TOKEN" \
| jq
# POST JSON
curl -s -X POST "$BASE_URL/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-d '{"name": "John"}' \
| jq
# Upload file
curl -s -X POST "$BASE_URL/upload" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-F "file=@./doc.pdf" \
| jqPostman Collection
1. Import postman-collection.json into Postman 2. Update collection variables:
baseUrl: Your API base URLauthToken: Will be set automatically after login
3. Run "Login" request first to set auth token 4. Run other requests
Collection features:
- Auto-saves auth token from login response
- Test scripts for response validation
- Path variables for resource IDs
- Query parameters for pagination
Environment Setup
Using Postman Environments
Create environment with variables:
{
"baseUrl": "http://localhost:3000/api",
"authToken": "",
"refreshToken": ""
}Using cURL with .env
# .env.api
API_BASE_URL=http://localhost:3000/api
API_TOKEN=your-token
# Load and use
source .env.api
curl "$API_BASE_URL/users" -H "Authorization: Bearer $API_TOKEN"Tips
jq Filtering
# Get specific field
curl -s "$BASE_URL/users" | jq '.[].name'
# Filter results
curl -s "$BASE_URL/users" | jq '.[] | select(.role == "admin")'
# Format output
curl -s "$BASE_URL/users" | jq -r '.[] | "\(.id): \(.name)"'Timing Requests
curl -s -w "\nTime: %{time_total}s\n" "$BASE_URL/users" -o /dev/nullSaving Responses
curl -s "$BASE_URL/users" | tee response.json | jqRelated skills
Backend & APIsbackend