Back to skills
SKILL.md
Api Patterns
ASecurityUse when designing, implementing, auditing, and hardening api patterns server logic, APIs, background jobs, and error boundaries.
- 5 stars
- 0 votes
- 0 copies
- 0 views
- Added September 27, 2026
Works with
Security analysis
100/100Pro scans all 2 files and shows the line behind each finding
npx -y skills add Harmitx7/tribunal-kit --skill api-patterns --agent claude-codeAre you the author of Api Patterns?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/harmitx7-api-patterns)---
name: api-patterns
description: "Use when designing, implementing, auditing, and hardening api patterns server logic, APIs, background jobs, and error boundaries."
version: 6.0.0
last-updated: 2026-09-29
skills:
- api-security-auditor
- backend-security-expert
- schema-reviewer
tools: Read, Grep, Glob, Bash, Edit, Write
scripts-binding:
- .agent/scripts/lint_runner.js
- .agent/scripts/verify_all.js
---
# API Patterns β Design & Protocol Mastery
## Mandatory Pre-Flight Context Inspection
Before reading, generating, or refactoring code in the `api-patterns` domain, inspect these 5 critical parameters:
1. **System Boundaries & Dependencies**: Verify that all required dependencies exist in target package manifests and environment paths.
2. **Runtime Context & Platform Invariants**: Confirm target platform constraints (Node.js, Browser, Mobile OS, Edge runtime) before applying APIs.
3. **Execution Guardrails**: Identify potential side-effects, state mutations, and unhandled asynchronous exceptions.
4. **Validation & Type Contracts**: Validate input data schemas and strict type constraints across all module interfaces.
5. **Observability & Proof of Execution**: Ensure execution produces tangible verification signals (terminal output, tests, metrics).
## Activation Boundaries
- **Activate when:** Use when designing, implementing, auditing, and hardening api patterns server logic, APIs, background jobs, and error boundaries.
- **DO NOT activate when:** The task falls outside the `api-patterns` domain or is managed by a different dedicated specialist agent.
## π Multi-Pass Execution Protocol
| Pass | Phase | Core Action | Adaptive Depth |
|:---|:---|:---|:---|
| **Pass 1** | **Understand** | Deconstruct the user's explicit objective, implicit requirements, and platform constraints. | Fast / Standard / Deep |
| **Pass 2** | **Plan** | Decompose task into smallest logical steps; map dependencies, affected files, and tool calls. | Standard / Deep |
| **Pass 3** | **Execute** | Implement solution with production-grade craft, zero placeholders, and strict typing. | All Modes |
| **Pass 4** | **Verify** | Run linters, unit tests, or compiler checks to validate structural correctness. | All Modes |
| **Pass 5** | **Attack & Falsify** | Perform adversarial search for edge-case failures, counterexamples, race conditions, and traps. | Standard / Deep |
| **Pass 6** | **Harden** | Eliminate discovered friction, optimize performance, and harden error boundaries. | Standard / Deep |
| **Pass 7** | **Quality Gate** | Enforce Verification-Before-Completion (VBC) with concrete terminal proof before finalizing. | All Modes |
---
## π οΈ Technical Architecture & Reference Recipes
## Hallucination Traps (Read First)
- β JWT in URL query params β β
`Authorization: Bearer` header only. Query params get logged in server access logs.
- β Assuming JWT is encrypted β β
JWT is base64-encoded (NOT encrypted). Anyone can decode it. Never put secrets/PII in the payload.
- β Offset pagination on large tables β β
`OFFSET 100000` scans and discards 100K rows. Use cursor pagination for tables > 10K rows.
- β Verbs in REST URLs (`/api/getUsers`) β β
Nouns only (`GET /api/users`). HTTP method IS the verb.
- β `POST` is idempotent β β
`POST` is NOT idempotent β requires `Idempotency-Key` header for safe retries.
- β GraphQL has no security risks β β
Deeply nested queries are a DoS vector. Set max depth, query cost limits. Disable introspection in production.
---
## Protocol Selection Matrix
| Protocol | Use When |
| ------------- | ------------------------------------------------------------------------------------- |
| **REST** | Public APIs, 3rd-party consumers, standard CRUD, HTTP caching |
| **GraphQL** | Complex nested data, multiple clients, flexible queries, mobile bandwidth sensitivity |
| **tRPC** | Full-stack TypeScript (Next.js monorepo), shared types, no codegen |
| **gRPC** | Internal microservices, high-throughput, streaming, binary protocol |
| **WebSocket** | Bidirectional real-time (chat, gaming, live collaboration) |
| **SSE** | Server-to-client streaming only (AI token streaming, live feeds) |
---
## REST Design
### URL Conventions
```
β
GET /api/v1/users list users
β
GET /api/v1/users/123 get user by ID
β
POST /api/v1/users create user
β
PATCH /api/v1/users/123 partial update
β
DELETE /api/v1/users/123 delete user
β
GET /api/v1/users/123/posts nested resource
β /api/getUsers /api/createUser /api/user (singular) /api/Users (uppercase)
```
### HTTP Status Codes
```
200 OK β GET / PUT / PATCH success
201 Created β POST success (include Location: /api/v1/users/123 header)
204 No Content β DELETE success
400 Bad Request β Malformed request / missing fields
401 Unauthorized β Missing or invalid authentication
403 Forbidden β Authenticated but not authorized
404 Not Found β Resource does not exist
409 Conflict β Duplicate resource (email already exists)
422 Unprocessable β Valid JSON, semantically invalid data
429 Too Many Req β Rate limit exceeded
500 Internal β Unhandled server error β NEVER expose stack traces
```
### Response Envelope
```typescript
interface ApiResponse<T> {
data: T;
meta?: Record<string, unknown>;
}
interface ApiError {
error: {
code: string; // machine-readable: "VALIDATION_ERROR"
message: string; // human-readable: "Email is already in use"
details?: Array<{ field: string; message: string }>; // field-level errors
requestId?: string; // for support/tracing
};
}
```
---
## Pagination
```typescript
// β
Cursor-based β required for large/dynamic datasets
// GET /api/v1/posts?cursor=eyJpZCI6MTAwfQ&limit=20
const posts = await db.post.findMany({
where: { id: { lt: decodeCursor(req.query.cursor).id } },
orderBy: { id: 'desc' },
take: limit + 1, // fetch one extra to determine hasMore
});
const hasMore = posts.length > limit;
if (hasMore) posts.pop();
return { data: posts, meta: { hasMore, nextCursor: encodeCursor(posts.at(-1)) } };
// Offset-based β only for small datasets where users need page jumping
// GET /api/v1/posts?page=3&limit=20
// β TRAP: OFFSET 100000 scans and discards 100K rows β degrades badly at scale
```
---
## Idempotency
```typescript
// POST /api/v1/payments with header: Idempotency-Key: <uuid>
app.post('/api/v1/payments', async (req, res) => {
const key = req.headers['idempotency-key'];
if (!key) return res.status(400).json({ error: 'Missing Idempotency-Key' });
const cached = await redis.get(`idempotency:${key}`);
if (cached) return res.status(200).json(JSON.parse(cached));
const result = await processPayment(req.body);
await redis.set(`idempotency:${key}`, JSON.stringify(result), 'EX', 86400);
return res.status(201).json(result);
});
// GET, PUT, DELETE β naturally idempotent (safe to retry without a key)
// POST, PATCH β NOT idempotent by default β require Idempotency-Key
```
---
## Webhooks
```typescript
// HMAC signature verification (always verify β never trust unsigned webhooks)
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(payload: string, signature: string, secret: string): boolean {
const expected = createHmac('sha256', secret).update(payload).digest('hex');
return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
app.post('/webhooks', (req, res) => {
if (
!verify(JSON.stringify(req.body), req.headers['x-webhook-signature'] as string, WEBHOOK_SECRET)
)
return res.status(401).send('Invalid signature');
res.status(200).send('OK'); // respond immediately
processWebhookAsync(req.body); // process asynchronously
});
// Retry policy: 3 retries with exponential backoff (1s β 10s β 100s)
// Include unique event ID in payload for receiver-side deduplication
```
---
## Versioning
```
URL path (recommended): /api/v1/users β simplest, most common, cache-friendly
Header: Accept: application/vnd.api.v1+json
Query param: /api/users?version=1 β messy, avoid
Rules:
- Start at v1, never v0
- Breaking changes = new major version (v2)
- Non-breaking additions (new optional fields) do NOT need a version bump
- Deprecate before removing β give consumers 6+ months notice
```
---
## Rate Limiting
```
Strategy How When
Token bucket β Burst allowed, refills Most APIs (recommended)
Sliding window β Smooth distribution Strict fairness required
Fixed window β Simple counter per period Basic needs only
Response headers to always include:
X-RateLimit-Limit (max requests in window)
X-RateLimit-Remaining (requests left)
X-RateLimit-Reset (Unix timestamp when limit resets)
Retry-After (seconds to wait on 429)
```
---
## GraphQL Security
```
Protect against:
Depth attacks β Set max query depth (typically 7β10)
Cost attacks β Calculate query complexity score, reject > threshold
Batch abuse β Limit batch size / alias count
Introspection β Disable in production (exposes full schema to attackers)
```
---
## Authentication Selection
| Pattern | Best For |
| ----------------------------------------------- | -------------------------------------- |
| **JWT** (short-lived access + httpOnly refresh) | Stateless services, microservices |
| **Session** | Traditional server-rendered apps |
| **OAuth 2.0 / OIDC** | Third-party login, delegated access |
| **API Key** | Server-to-server, public API consumers |
| **Passkey (WebAuthn)** | Modern passwordless (2026+) |
## π¨ Edge-Case & Failure Mode Matrix
| Scenario | Risk | Production Mitigation |
|:---|:---|:---|
| **Empty or Null Inputs** | Unhandled exception or unexpected rendering collapse | Enforce fallback guards, optional chaining, and explicit empty state handlers |
| **Network Timeout / Latency** | Hanging operations or duplicate side-effects | Implement bounded abort controllers, exponential backoff, and idempotency keys |
| **Concurrency / Race Conditions** | Stale state overwrite or inconsistent data mutations | Use atomic transactions, mutex locking, or cancel-on-resubmit controls |
| **Invalid Schema / Malformed Payload** | Downstream runtime errors or security injection | Validate boundary payloads with Zod/Pydantic schemas prior to execution |
| **Resource / Memory Saturation** | OOM errors, frame drops, or memory leaks | Clean up listeners, cancel active timers, and enforce pagination/virtualization |
## ποΈ Tribunal Verification & Guardrails
**Active Reviewers:** `logic-reviewer` Β· `security-auditor` Β· `api-architect` Β· `resilience-reviewer`
**Slash Command:** `/review` or `/tribunal-full`
### π¬ Evidence Standard (Tri-State Verification)
Every finding, audit statement, or completion claim must classify its factual certainty:
- **`[OBSERVED]`**: Directly confirmed in the codebase or verified via executed terminal command.
- **`[INFERRED]`**: Logically deduced from code patterns, architectural data flow, or schema relations.
- **`[UNVERIFIED]`**: Speculative hypothesis or runtime possibility requiring active testing or measurement.
### β
Pre-Flight Self-Audit Checklist
```
β
Are all inputs and boundary payloads validated against schemas (Zod/Pydantic)?
β
Are SQL and database queries parameterized with zero string concatenation?
β
Are error boundaries and timeout/retry policies explicitly declared?
β
Are authentication and object-level authorization (IDOR/BOLA) checked before business logic?
β
Did I verify that imported dependencies exist in package manifests?
```
### π Verification-Before-Completion (VBC) Protocol
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
- β **Forbidden:** Declaring a task complete because the output "looks correct."
- β
**Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing test suites, compiler success, or equivalent operational proof) that your output works as intended.
Files in this skill
- SKILL.md
- scripts/api_validator.py
Attribution
Comments
Loading commentsβ¦