Agent skill

Write API Route

by ryokun6 in ryokun6/ryos

Create or modify ryOS backend API routes under api/ using the shared apiHandler wrapper, request-auth, Redis, rate limiting, and CORS conventions.

AGPL-3.0Auto-check passedBackend & APIs

Install Write API Route

skills CLI
$ npx skills add ryokun6/ryos --skill write-api-route -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ryokun6/ryos write-api-route --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ryokun6/ryos.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.cursor/skills/write-api-route .claude/skills/write-api-route && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
write-api-route
GitHub stars
1.3k
Token cost
~2.1k tokens
SKILL.md length
492 words
Files
1
Skills in repo
10
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Create or modify ryOS backend API routes under api/ using the shared apiHandler wrapper, request-auth, Redis, rate limiting, and CORS conventions.

  • Works in 7 steps: Prefer apiHandler; keep auth semantics… → Validate ALL user input before use (Zod… → Rate-limit public/expensive routes. → …
  • Adding an endpoint
  • SKILL.md covers Quick Start Checklist, File & Naming Conventions, Primary Pattern: apiHandler and Auth, plus 6 more sections
  • Calls bun

What it does

Write API Route is an agent skill from ryokun6/ryos. Create or modify ryOS backend API routes under api/ using the shared apiHandler wrapper, request-auth, Redis, rate limiting, and CORS conventions. Use when adding an endpoint, writing a serverless/Bun API handler, wiring auth or rate limits, or working with anything under the api/ directory.

Its SKILL.md is about 2.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Rate limiting and Serverless. It works with Redis. The repository describes itself as: ryOS, made with Cursor. The licence is AGPL-3.0.

When your agent uses it

  • Adding an endpoint
  • Writing a serverless/Bun API handler
  • Working with anything under the api/ directory

Example prompts

  • “/write-api-route”

Workflow steps

7 steps, taken from the first numbered list in SKILL.md.

  1. Prefer apiHandler; keep auth semantics via request-auth.
  2. Validate ALL user input before use (Zod bodySchema is preferred).
  3. Rate-limit public/expensive routes.
  4. Keep response shapes stable, explicit, and backward-compatible.
  5. Use SSRF-safe fetch for untrusted URLs.
  6. Log request/response and key branch decisions.
  7. Update docs/8.*.md whenever a request/response contract changes.

What it can do on your machine

Read from SKILL.md and the folder at commit 4a6e61e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • bun

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Write API Route loads about 2.1k tokens when it runs. Until then it costs about 77 tokens; SKILL.md has 492 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~77
When it runs · the whole SKILL.md, loaded when a task matches
~2.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from ryokun6/ryos at commit 4a6e61e, republished under its AGPL-3.0 licence (© ryokun6). 492 words, ~2,057 tokens.

Download SKILL.mdSave it as .claude/skills/write-api-route/SKILL.md (or your agent's skills folder).
name
write-api-route
description
Create or modify ryOS backend API routes under api/ using the shared apiHandler wrapper, request-auth, Redis, rate limiting, and CORS conventions. Use when adding an endpoint, writing a serverless/Bun API handler, wiring auth or rate limits, or working with anything under the api/ directory.

Writing ryOS API Routes

ryOS API routes are Node-style handlers under api/, served by the standalone Bun server (scripts/api-standalone-server.ts). The canonical reference is docs/8.10-api-design-guide.md — read it for the full contract. This skill is the practical checklist.

Quick Start Checklist

- [ ] 1. Pick the path: api/<feature>/index.ts (collection) or api/<feature>/[id].ts (item)
- [ ] 2. Wrap the handler in apiHandler({ methods, auth, ... })
- [ ] 3. Validate input (Zod via bodySchema, or _utils/_validation.ts helpers)
- [ ] 4. Rate-limit public / expensive routes (_utils/_rate-limit.ts)
- [ ] 5. Use shared constants/keys (_utils/constants.ts, REDIS_PREFIXES)
- [ ] 6. Return explicit JSON; errors as { error: "..." }
- [ ] 7. Add structured logs (logger.info / branch decisions)
- [ ] 8. Write/extend an integration test in tests/ (requires `bun run dev:api`)
- [ ] 9. Update the matching docs/8.*.md if the contract changed

File & Naming Conventions

text
api/
├── _utils/                 # globally shared helpers (api-handler, redis, request-auth, ...)
├── <feature>/
│   ├── index.ts            # collection route (GET list / POST create)
│   ├── [id].ts             # item route (path param :id)
│   ├── [id]/messages.ts    # nested dynamic routes
│   └── _helpers/           # feature-private helpers (_constants.ts, _types.ts, ...)
  • _utils/ = global utilities; feature _helpers/ = domain-specific internals.
  • _*.ts / _helpers/ are private modules (not routes).
  • Use index.ts for collections, [id].ts and nested folders for path params.
  • Import shared modules with the .js extension (e.g. from "../_utils/api-handler.js") — required for Node-style ESM resolution even though the source is .ts.

Primary Pattern: apiHandler

Prefer apiHandler for all new JSON endpoints. It centralizes CORS/preflight, origin allowlisting, method checks, Redis injection, auth resolution, body parsing/validation, analytics, and a 500 fallback.

typescript
import { apiHandler } from "../_utils/api-handler.js";
import { z } from "zod";

const bodySchema = z.object({
  name: z.string().min(1).max(100),
});

export default apiHandler(
  {
    methods: ["POST"],
    auth: "required",        // "none" | "optional" | "required" | "admin"
    parseJsonBody: true,     // implied when bodySchema is set
    bodySchema,              // 400 { error: "validation_error", issues } on failure
    // allowExpiredAuth: false,
    // contentType: "application/json", // pass null to disable the default header
    // analytics: true,
  },
  async ({ req, res, redis, logger, startTime, origin, user, body }) => {
    // `user` is the authenticated user (never null when auth: "required"/"admin")
    // `body` is the parsed + validated payload (typed from bodySchema)
    logger.info("creating thing", { username: user!.username });

    // ...business logic against redis...

    logger.response(201, Date.now() - startTime);
    res.status(201).json({ success: true });
  }
);
Handler context

apiHandler passes { req, res, redis, logger, startTime, origin, user, body }:

  • redis — client from createRedis() (Upstash REST or standard Redis backend).
  • logger — request-scoped logger; request() is already called for you.
  • user — null unless authenticated; guaranteed non-null for auth: "required"/"admin".
  • body — null unless parseJsonBody/bodySchema; typed when bodySchema is set.

Auth

Auth is unified through _utils/request-auth.ts (resolveRequestAuth). Set auth on apiHandler:

  • "none" — public.
  • "optional" — anonymous allowed, but credentials are validated if present.
  • "required" — needs both Authorization: Bearer <token> and X-Username: <username>. Partial creds → 400; bad pair → 401.
  • "admin" — required auth AND username === "ryo", else 403.

For non-apiHandler routes (e.g. multipart uploads), call resolveRequestAuth() directly to keep behavior aligned.

Rate Limiting

Apply to public and expensive routes using _utils/_rate-limit.ts:

typescript
import * as RateLimit from "../_utils/_rate-limit.js";
import { getClientIp } from "../_utils/_rate-limit.js";

const ip = getClientIp(req);
const key = RateLimit.makeKey(["rl", "feature", "burst", "ip", ip]);
const result = await RateLimit.checkCounterLimit({ key, windowSeconds: 60, limit: 30 });

if (!result.allowed) {
  res.setHeader("Retry-After", String(result.resetSeconds));
  return res.status(429).json({
    error: "rate_limit_exceeded",
    limit: result.limit,
    retryAfter: result.resetSeconds,
  });
}

getClientIp respects TRUSTED_PROXY_COUNT when the API sits behind a reverse proxy. Prefer tiers from RATE_LIMIT_TIERS in _utils/constants.ts over magic numbers.

Response & Error Shape

  • Success: explicit payloads ({ success: true }, { data: ... }).
  • Client errors: 400/401/403/404/405/429 with JSON { error: "..." } (extra fields ok if additive).
  • Server errors: 500 { error: "..." } — apiHandler provides this automatically for thrown errors.
  • Streaming: use SSE helpers in _utils/_sse.ts; set stream headers and emit structured events (start, line, complete, error).
Show full SKILL.md (194 more words)Show less

Shared Utilities (use before hand-rolling)

ModuleUse
_utils/_validation.tsusername/room/message validation, profanity filter, HTML escaping
_utils/_ssrf.tsvalidatePublicUrl(), safeFetchWithRedirects() for untrusted URLs
_utils/_sse.tsSSE streaming helpers
_utils/redis.tscreateRedis() client factory
_utils/storage.tsS3-compatible object storage adapter
_utils/constants.tsREDIS_PREFIXES, TTL, RATE_LIMIT_TIERS, PASSWORD, VALIDATION, TOKEN
_utils/_logging.tsinitLogger() (only needed for manual handlers)

Always key Redis entries with REDIS_PREFIXES + shared TTL rather than hardcoding strings.

Manual Handlers (when apiHandler doesn't fit)

Some endpoints (e.g. multipart /api/audio-transcribe) keep explicit handlers. Mirror the shared behavior manually:

typescript
import { getEffectiveOrigin, isAllowedOrigin, setCorsHeaders } from "../_utils/_cors.js";
import { initLogger } from "../_utils/_logging.js";
import { resolveRequestAuth } from "../_utils/request-auth.js";

const origin = getEffectiveOrigin(req);
setCorsHeaders(res, origin, { methods: ["POST", "OPTIONS"] });
if (req.method === "OPTIONS") return res.status(204).end();
if (!isAllowedOrigin(origin)) return res.status(403).json({ error: "Unauthorized" });
// method checks → initLogger() + timing logs → resolveRequestAuth() for auth routes

Testing

API integration tests require the standalone server running:

bash
# Terminal 1
bun run dev:api          # exports TRUSTED_PROXY_COUNT=1 for spoofed-IP rate-limit tests
# Terminal 2
bun run test:api         # or: bun test tests/integration/api/test-<feature>.test.ts

Use helpers from tests/helpers/test-utils.ts: fetchWithOrigin, fetchWithAuth, ensureUserAuth, makeRateLimitBypassHeaders (random IP to dodge rate limits). Place new API suites under tests/integration/api/ and append them to API_TEST_FILES in scripts/test-groups.ts, then run bun run test:registration. For pure schema/validation logic, a no-server unit test under tests/unit/ (see the write-tests skill) is often enough.

Best Practices

  1. Prefer apiHandler; keep auth semantics via request-auth.
  2. Validate ALL user input before use (Zod bodySchema is preferred).
  3. Rate-limit public/expensive routes.
  4. Keep response shapes stable, explicit, and backward-compatible.
  5. Use SSRF-safe fetch for untrusted URLs.
  6. Log request/response and key branch decisions.
  7. Update docs/8.*.md whenever a request/response contract changes.

© ryokun6, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .cursor/skills/write-api-route of ryokun6/ryos.

Open the folder on GitHubat commit 4a6e61e

Compare with similar skills

Write API Route next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Write API Route compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Write API Route this skillryokun6/ryos1.3k—~2.1kAutomated safety check: PassAGPL-3.0
Amazon Elasticacheaws/agent-toolkit-for-aws2.8k—~4.5kAutomated safety check: PassApache-2.0
Upstash Ratelimitsickn33/agentic-awesome-skills47k1 repos~1.7kAutomated safety check: PassMIT
Upstash Redisgithub/awesome-copilot40k—~1.7kAutomated safety check: PassMIT
Upstash Ratelimit TSupstash/ratelimit-js2k1 repos~313Automated safety check: PassMIT
Apikerhodgef/apiker127—~1.4kAutomated safety check: PassMIT

Similar skills

  • Amazon Elasticache

    aws/agent-toolkit-for-aws

    Official

    Activate when developers have latent caching needs: slow API responses, database read bottlenecks, DynamoDB throttling or cost, RDS/Aurora scaling pressure, Bedrock latency or cost, or adding a…

    2.8k GitHub stars~4.5k tokensUpdated today
    Backend & APIsAuto-check passed
  • Upstash Ratelimit

    sickn33/agentic-awesome-skills

    Add rate limiting to API routes, middleware, and edge functions with @upstash/ratelimit: sliding window, fixed window, and token bucket backed by Upstash Redis.

    47k GitHub starsUsed in 1 repo~1.7k tokens
    Backend & APIsAuto-check passed
  • Upstash Redis

    github/awesome-copilot

    Official

    Use Redis over HTTP from serverless and edge runtimes with @upstash/redis, and add rate limiting with @upstash/ratelimit.

    40k GitHub stars~1.7k tokensUpdated today
    Backend & APIsAuto-check passed
  • Upstash Ratelimit TS

    upstash/ratelimit-js

    Official

    Lightweight guidance for using the Redis Rate Limit TypeScript SDK, including setup steps, basic usage, and pointers to advanced algorithm, features, pricing, and traffic‑protection docs.

    2k GitHub starsUsed in 1 repo~313 tokens
    Backend & APIsAuto-check passed
  • Apiker

    hodgef/apiker

    Develop, review, and extend the Apiker library — a framework for building serverless REST APIs on Cloudflare Workers + Durable Objects.

    127 GitHub stars~1.4k tokensUpdated 1 mo ago
    Backend & APIsAuto-check passed
  • Neon Functions

    neondatabase/agent-skills

    Official

    Long-running, serverless Node.js HTTP functions deployed onto your Neon branch, with DATABASEURL injected automatically and compute that runs next to your data.

    100 GitHub stars~12k tokensUpdated yesterday
    Backend & APIsAuto-check: notes

More from ryokun6/ryos

All 10 skills in this repo
  • Add AI Chat Tool

    ryokun6/ryos

    Add or modify an AI chat tool ("Ask Ryo" capability) in ryOS.

    1.3k GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Create Ryos App

    ryokun6/ryos

    Create new applications for ryOS following established patterns and conventions.

    1.3k GitHub stars~3.7k tokensUpdated today
    Auto-check passed
  • Create Store

    ryokun6/ryos

    Create or modify ryOS Zustand stores following repo conventions — persist middleware, partialize, versioned migrations, the debounced write-behind storage adapter for large slices, and cloud-sync…

    1.3k GitHub stars~2.1k tokensUpdated today
    Auto-check passed
  • Desktop Release

    ryokun6/ryos

    Cut and publish ryOS Electron desktop releases on GitHub. An agent skill from ryokun6/ryos.

    1.3k GitHub stars~1k tokensUpdated today
    Auto-check: notes
  • Localize

    ryokun6/ryos

    Localize ryOS apps and components by extracting hardcoded strings, replacing with translation keys, and syncing across languages.

    1.3k GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • React performance optimization guidelines from Vercel Engineering (vercel-labs/agent-skills).

    1.3k GitHub stars~2k tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Write API Route

What does Write API Route do?

Create or modify ryOS backend API routes under api/ using the shared apiHandler wrapper, request-auth, Redis, rate limiting, and CORS conventions. Write API Route is an agent skill from ryokun6/ryos. Create or modify ryOS backend API routes under api/ using the shared apiHandler wrapper, request-auth, Redis, rate limiting, and CORS conventions.

When should I use Write API Route?

Write API Route fits situations like: adding an endpoint; writing a serverless/Bun API handler; working with anything under the api/ directory.

How do I install Write API Route in Claude Code?

Run `npx skills add ryokun6/ryos --skill write-api-route -a claude-code`. Or copy the skill folder (.cursor/skills/write-api-route in ryokun6/ryos) into .claude/skills/write-api-route in your project. Claude Code loads it when a task matches its description.

How do I install Write API Route in Codex?

Run `npx skills add ryokun6/ryos --skill write-api-route -a codex`. Or copy the skill folder (.cursor/skills/write-api-route in ryokun6/ryos) into .agents/skills/write-api-route in your project. Codex loads it when a task matches its description.

Can I use Write API Route in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ryokun6/ryos --skill write-api-route -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/write-api-route, .gemini/skills/write-api-route, .github/skills/write-api-route and .opencode/skills/write-api-route in your project.

What does Write API Route need to run?

Going by SKILL.md and its folder, Write API Route needs the command-line tools its instructions call (bun).

Does Write API Route access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Write API Route safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Write API Route use?

Write API Route is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Write API Route use?

About 2.1k tokens (SKILL.md is roughly 8.2k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Write API Route?

Skills that share tags, products or a category with Write API Route: Amazon Elasticache (aws/agent-toolkit-for-aws, 2.8k stars), Upstash Ratelimit (sickn33/agentic-awesome-skills, 47k stars), Upstash Redis (github/awesome-copilot, 40k stars) and Upstash Ratelimit TS (upstash/ratelimit-js, 2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Write API Route?

ryokun6 (a GitHub user) maintains it in ryokun6/ryos, which has 1,264 GitHub stars. The repository holds 10 skills in this directory. The repository was last updated on October 7, 2026.

Source: ryokun6/ryos on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.