Skip to content
Development
Skill

/api-patterns

API route implementation patterns with RLS, Zod validation, and error handling. Use when creating API routes, implementing endpoints, or adding server-side validation.

From plugin
safe-agentic-workflow
39520 skills11 agents24 commands
Install
$ npx -y skills add bybren-llc/safe-agentic-workflow --skill api-patterns --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/api-patterns

Context preview

The summary Claude sees to decide when to auto-load this skill.

API route implementation patterns with RLS, Zod validation, and error handling. Use when creating API routes, implementing endpoints, or adding server-side validation.

SKILL.md

api-patterns.SKILL.md
name: api-patterns
description: API route implementation patterns with RLS, Zod validation, and error handling. Use when creating API routes, implementing endpoints, or adding server-side validation.
user-invocable: false
allowed-tools: Read, Grep, Glob

API Patterns Skill

Purpose

Route to existing API patterns and provide checklists for safe, validated API route implementation. All API routes MUST use RLS context helpers—see `rls-patterns` skill.

When This Skill Applies

Invoke this skill when:

  • Creating new API routes
  • Implementing CRUD endpoints
  • Adding request/response validation
  • Handling webhooks
  • Implementing error handling patterns

Authoritative References (MUST READ)

| Pattern | Location | Purpose | | ----------------- | --------------------------------------------- | --------------------------- | | User Context API | `patterns_library/api/user-context-api.md` | User-scoped operations | | Admin Context API | `patterns_library/api/admin-context-api.md` | Admin-scoped operations | | Zod Validation | `patterns_library/api/zod-validation-api.md` | Request/response validation | | Webhook Handler | `patterns_library/api/webhook-handler.md` | Webhook processing | | Bonus Content | `patterns_library/api/bonus-content-delivery.md` | Protected content delivery |

Stop-the-Line Conditions

FORBIDDEN Patterns

// FORBIDDEN: Direct Prisma calls (bypass RLS)
const users = await prisma.user.findMany();
// Must use: withUserContext, withAdminContext, or withSystemContext

// FORBIDDEN: Missing authentication check
export async function GET(req: Request) {
  return getUserData(); // No auth check!
}

// FORBIDDEN: Unvalidated user input
const { userId } = await req.json();
// Must validate with Zod schema

// FORBIDDEN: Generic error responses
return new Response("Error", { status: 500 });
// Must use structured error response

CORRECT Patterns

// CORRECT: RLS context + auth check
export async function GET(req: Request) {
  const { userId } = await auth();
  if (!userId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const data = await withUserContext(prisma, userId, async (client) => {
    return client.user.findUnique({ where: { user_id: userId } });
  });

  return NextResponse.json(data);
}

// CORRECT: Zod validation
const schema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
});

const result = schema.safeParse(body);
if (!result.success) {
  return NextResponse.json(
    { error: "Validation failed", details: result.error.flatten() },
    { status: 400 },
  );
}

API Route Checklist

Before ANY API route:

  • [ ] Authentication check with `await auth()` from Clerk
  • [ ] Proper 401 response for unauthenticated
  • [ ] Request validation with Zod schema
  • [ ] RLS context wrapper (`withUserContext`/`withAdminContext`/`withSystemContext`)
  • [ ] Structured error responses with appropriate status codes
  • [ ] TypeScript types for request/response

Standard Response Patterns

Success Response

return NextResponse.json({ data, success: true }, { status: 200 });

Error Response

return NextResponse.json(
  {
    error: "Human-readable error message",
    code: "ERROR_CODE",
    details: optional_details,
  },
  { status: 400 | 401 | 403 | 404 | 500 },
);

Status Codes

| Code | When to Use | | ---- | -------------------------------------------- | | 200 | Success | | 201 | Created (POST) | | 400 | Bad request / validation error | | 401 | Not authenticated | | 403 | Forbidden (authenticated but not authorized) | | 404 | Resource not found | | 500 | Server error |

API Route Template

import { auth } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import { z } from "zod";
import { withUserContext } from "@/lib/rls-helpers";
import { prisma } from "@/lib/prisma";

// Request validation schema
const RequestSchema = z.object({
  // Define expected fields
});

export async function POST(req: Request) {
  try {
    // 1. Authenticate
    const { userId } = await auth();
    if (!userId) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    // 2. Parse and validate request
    const body = await req.json();
    const result = RequestSchema.safeParse(body);
    if (!result.success) {
      return NextResponse.json(
        { error: "Validation failed", details: result.error.flatten() },
        { status: 400 },
      );
    }

    // 3. Execute with RLS context
    const data = await withUserContext(prisma, userId, async (client) => {
      return client.resource.create({ data: result.data });
    });

    // 4. Return success response
    return NextResponse.json({ data, success: true }, { status: 201 });
  } catch (error) {
    console.error("API error:", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 },
    );
  }
}

API Documentation Template

For documenting new endpoints:

## Endpoint: POST /api/resource

### Description

Creates a new resource for the authenticated user.

### Authentication

Required: Clerk session

### Request Body

| Field | Type   | Required | Description   |
| ----- | ------ | -------- | ------------- |
| name  | string | Yes      | Resource name |
| type  | string | No       | Resource type |

### Response

**Success (201)**:
\`\`\`json
{ "data": { "id": 1, "name": "..." }, "success": true }
\`\`\`

**Error (400)**:
\`\`\`json
{ "error": "Validation failed", "details": {...} }
\`\`\`

### RLS Context

Uses `withUserContext` - user c
Read more
Ships withsafe-agentic-workflow

SAW — SAFe Agentic Workflow AI Agent Harness for Multi-Agent Team Workflows Built on SAFe methodology (Scaled Agile Framework), adapted for AI agent teams (Now With AI-DLC!) Works for any team with repeatable processes: Software, Marketing, Research, Legal, Operations.

Get the whole plugin