Install
$ agentstack add skill-param087-saas-starter-skills-api-routes-and-validation ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
API Routes & Validation
Overview
Every endpoint is an attack surface. The rule: never trust input. Validate the body, query, and params with zod at the boundary, parse into typed data, then run auth → authorization → data access. Return a consistent error shape with correct HTTP status codes so clients can handle failures predictably. This applies equally to App Router route handlers and Server Actions.
When to use
- Building a route handler (
app/api/.../route.ts) or a Server Action. - Accepting any user/client input.
- You need predictable, typed error responses.
Validated route handler
// src/app/api/projects/route.ts
import { z } from "zod";
import { requireOrg } from "@/server/auth/active-org";
import { authorize } from "@/server/auth/permissions";
import { createProject } from "@/server/services/projects";
const Body = z.object({ name: z.string().min(1).max(100) });
export async function POST(req: Request) {
const json = await req.json().catch(() => null);
const parsed = Body.safeParse(json);
if (!parsed.success) {
return Response.json(
{ error: { code: "invalid_input", fields: parsed.error.flatten().fieldErrors } },
{ status: 422 },
);
}
const slug = new URL(req.url).searchParams.get("org")!;
const { org, role } = await requireOrg(slug); // 401/404 inside
authorize(role, "project:create"); // 403 inside
const project = await createProject(org.id, parsed.data);
return Response.json({ data: project }, { status: 201 });
}
Consistent contract
- Success:
{ data }. Error:{ error: { code, message?, fields? } }. Pick one shape and keep it everywhere. - Status codes: 400/422 invalid input, 401 unauthenticated, 403 forbidden, 404 not found, 402 needs upgrade, 409 conflict, 429 rate-limited, 500 unexpected.
- Server Actions: validate with the same zod schema and return typed
{ ok: false, error }for the form to render.
Pitfalls
ascasting instead of parsing —body as CreateInputtrusts the client; useschema.parse/safeParse.- Validating on the client only — re-validate server-side; the client check is UX.
- Leaking internals in errors — return a code/message, log the stack server-side; never echo SQL or stack traces.
- Wrong status codes — returning 200 with an error body breaks client handling and retries.
- Auth after the work — check session/permission/limits before mutating, not after.
- Reusing the same zod schema you forgot to bound — cap string lengths and array sizes to prevent abuse.
Hand-off
Typed, validated, authorized endpoints. They call data-access-layer for persistence and subscription-billing for limits; long work hands off to background-jobs.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: param087
- Source: param087/saas-starter-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.