openapi-endpoints

OpenAPI Endpoint Documentation

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "openapi-endpoints" with this command: npx skills add timelessco/recollect/timelessco-recollect-openapi-endpoints

OpenAPI Endpoint Documentation

The spec is generated in two passes: (1) a filesystem scanner auto-infers schemas from handler factories, (2) a merge script overlays human-authored metadata from supplement files. The full human-readable guide is at docs/OPENAPI_GUIDE.md .

Quick Start

New App Router endpoint

  • Create src/app/api/<path>/route.ts using a handler factory

  • Create src/app/api/<path>/schema.ts with InputSchema

  • OutputSchema
  • Create src/lib/openapi/endpoints/<domain>/<endpoint-name>.ts (supplement)

  • Export supplement from src/lib/openapi/endpoints/<domain>/index.ts

  • Run npx tsx scripts/generate-openapi.ts

  • Verify at http://localhost:3000/api-docs

Update existing endpoint

  • Modify schema in schema.ts — auto-captured by scanner

  • Update supplement metadata/examples in src/lib/openapi/endpoints/<domain>/

  • Run npx tsx scripts/generate-openapi.ts

New edge function endpoint

  • Create registration function in src/lib/openapi/endpoints/<domain>/edge-process-imports.ts

  • Use registry.registerPath() with raw SchemaObject (not Zod)

  • Import and call from scripts/generate-openapi.ts

  • Run npx tsx scripts/generate-openapi.ts

  • Verify at http://localhost:3000/api-docs

For edge function details, see reference.md.

New App Router Endpoint

Step 1: Create route handler

Use one of the 4 handler factories from src/lib/api-helpers/create-handler.ts :

  • createGetApiHandlerWithAuth — GET with auth

  • createPostApiHandlerWithAuth — POST with auth

  • createGetApiHandler — GET without auth

  • createPostApiHandler — POST without auth

// src/app/api/<domain>/<endpoint>/route.ts import { createGetApiHandlerWithAuth } from "@/lib/api-helpers/create-handler"; import { MyInputSchema, MyOutputSchema } from "./schema";

const ROUTE = "domain-endpoint-name";

export const GET = createGetApiHandlerWithAuth({ route: ROUTE, inputSchema: MyInputSchema, outputSchema: MyOutputSchema, handler: async ({ data, supabase, user, route }) => { // business logic return { result: "value" }; }, });

Step 2: Create schema file

Colocate Zod schemas next to route.ts :

// src/app/api/<domain>/<endpoint>/schema.ts import { z } from "zod";

export const MyInputSchema = z.object({ url: z.string(), });

export const MyOutputSchema = z.object({ result: z.string(), });

Step 3: Create supplement file

Supplements provide metadata the scanner can't infer: tags, summary, description, examples.

// src/lib/openapi/endpoints/<domain>/<endpoint-name>.ts import { type EndpointSupplement } from "@/lib/openapi/supplement-types"; import { bearerAuth } from "@/lib/openapi/registry";

export const myEndpointSupplement = { path: "/<domain>/<endpoint-name>", method: "get", tags: ["<Domain>"], summary: "Short description for Scalar heading", description: "Detailed explanation of what the endpoint does.", security: [{ [bearerAuth.name]: [] }, {}], responseExample: { data: { result: "value" }, error: null, }, } satisfies EndpointSupplement;

Rules:

  • path is relative to /api (e.g., /bookmarks/check-url not /api/bookmarks/check-url )

  • method is lowercase: "get" or "post"

  • Tags are capitalized: "Bookmarks" , "Categories" , "Twitter"

  • Security [{ [bearerAuth.name]: [] }, {}] — empty {} means cookie auth also accepted

  • Export name: <camelCaseName>Supplement

Step 4: Export from barrel

// src/lib/openapi/endpoints/<domain>/index.ts export { myEndpointSupplement } from "./<endpoint-name>";

Step 5: Regenerate and verify

npx tsx scripts/generate-openapi.ts

Open http://localhost:3000/api-docs and verify the endpoint appears.

Updating an Existing Endpoint

Schema changes

Modify the Zod schema in schema.ts — the scanner picks it up automatically. The GitHub Actions changelog workflow runs oasdiff on every push to dev and appends changes to docs/API_CHANGELOG.md .

Updating supplement metadata

Edit the supplement file directly: summary , description , tags , additionalResponses .

Adding examples

Single example (simple endpoints):

responseExample: { data: { id: 1, name: "Example" }, error: null, },

Named examples (multiple scenarios — creates a dropdown in Scalar):

responseExamples: { "happy-path": { summary: "Successful response", description: "Returns the created resource.", value: { data: { id: 1 }, error: null }, }, "duplicate-detected": { summary: "Duplicate skipped", description: "URL already bookmarked.", value: { data: { inserted: 0, skipped: 1 }, error: null }, }, },

400 error examples:

response400Examples: { "empty-array": { summary: "Empty bookmarks array", description: "Fails when bookmarks array has no elements.", value: { data: null, error: "bookmarks: Array must contain at least 1 element(s)" }, }, }, additionalResponses: { 400: { description: "Invalid request body or bookmark data" }, },

When the supplement file exceeds 250 lines, extract examples to <endpoint-name>-examples.ts .

Parameter examples (GET query param dropdown in Scalar):

parameterExamples: { email: { "valid-user": { summary: "Valid user email", description: "Returns user data for this email.", value: "user@example.com", }, "unknown-email": { summary: "Nonexistent email", description: "Returns null/empty result.", value: "nobody@example.com", }, }, },

Outer key = parameter name (must match name in the generated spec). Inner map = standard named examples. Creates a dropdown per query param in Scalar's "Try It" panel.

Supplement Reference

EndpointSupplement fields

Field Type Purpose

path

string

Route path relative to /api (required)

method

string

"get" or "post" lowercase (required)

tags

string[]

Scalar sidebar grouping

summary

string

Short heading (one line)

description

string

Detailed explanation (supports markdown)

security

Array<Record<string, string[]>>

Auth requirements

requestExample

Record<string, unknown>

Single request body example

requestExamples

Named examples object Multiple request examples

responseExample

Record<string, unknown>

Single 200 response example

responseExamples

Named examples object Multiple 200 response examples

response400Example

Record<string, unknown>

Single 400 error example

response400Examples

Named examples object Multiple 400 error examples

additionalResponses

Record<number, { description }>

Extra response codes (400, 403, 404)

parameterExamples

Record<string, NamedExamples>

Per-param named examples (GET dropdown)

Naming conventions

  • Export name: <camelCaseName>Supplement (e.g., checkUrlSupplement )

  • Named example keys: kebab-case ("single-tweet" , "validation-error" )

  • Example files: <endpoint-name>-examples.ts (e.g., sync-examples.ts )

  • Tags: capitalized ("Bookmarks" , "iPhone" )

  • All named examples require both summary and description

  • Happy paths first, then validation errors

Response components

The scanner registers 3 $ref response components for every endpoint:

  • ValidationError (400) — { data: null, error: string }

  • Unauthorized (401) — { data: null, error: "Not authenticated" }

  • InternalError (500) — { data: null, error: "Failed to process request" }

additionalResponses overrides the 400 description while preserving the schema.

Agent Prompt Templates

Create supplement for a new endpoint

I just created a new App Router endpoint at src/app/api/<path>/route.ts with schema at src/app/api/<path>/schema.ts . Create the OpenAPI supplement file, export it from the barrel, regenerate the spec, and verify at /api-docs .

Domain: <bookmarks|categories|tags|twitter|instagram|raindrop|profiles|iphone>

Update examples for an existing endpoint

Update the OpenAPI examples for the <endpoint-name> endpoint. Read the current supplement at src/lib/openapi/endpoints/<domain>/<endpoint-name>.ts , add named examples for these scenarios: [describe scenarios]. Regenerate the spec and verify.

Add 400 error examples

Add response400Examples to the <endpoint-name> supplement. Include examples for: [list validation errors]. Also add additionalResponses: { 400: { description: "<custom description>" } } . Regenerate and verify.

Add parameter examples for a GET endpoint

Add parameterExamples to the <endpoint-name> supplement for each query parameter. Include examples for: [list test scenarios per param]. Regenerate the spec and verify the dropdown appears in Scalar's "Try It" panel.

Document a new edge function

I created a new Supabase Edge Function at supabase/functions/<name>/ . Register it in the OpenAPI spec following the pattern in src/lib/openapi/endpoints/instagram/edge-process-imports.ts . Use serviceRoleAuth , edgeFunctionServers , and raw SchemaObject . Wire it into scripts/generate-openapi.ts .

Troubleshooting

Supplement not appearing in spec

  • Is the supplement exported from the domain's index.ts barrel?

  • Does path match the route path exactly (relative to /api , no trailing slash)?

  • Does method match the exported handler ("get" for GET , "post" for POST )?

  • Check console output — mergeSupplements prints warnings for unmatched supplements

400 examples not showing

  • Does the supplement have additionalResponses: { 400: { description: "..." } } ?

  • Are named examples using response400Examples (not responseExamples )?

  • The merge script initializes 400 content automatically when examples are provided

Common mistakes

  • Using /api/bookmarks/check-url instead of /bookmarks/check-url for the path

  • Forgetting as const on example data objects in -examples.ts files

  • Using responseExample (singular) when you need responseExamples (named/plural)

  • Missing summary or description on named examples — both are required

For edge function patterns and complex examples, see reference.md.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

postgresql-psql

No summary provided by upstream source.

Repository SourceNeeds Review
General

nextjs

No summary provided by upstream source.

Repository SourceNeeds Review
General

tailwindcss

No summary provided by upstream source.

Repository SourceNeeds Review