Agent skill

Arandu API

by arandu-io in arandu-io/arandu

Answering a program rather than a person in an Arandu (Go) application -- a JSON Resource, a JSON answer from the same routes the pages use, problem+json errors, bearer-token authentication and…

MITAuto-check passedBackend & APIs

Install Arandu API

skills CLI
$ npx skills add arandu-io/arandu --skill arandu-api -a claude-code

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

GitHub CLI
$ gh skill install arandu-io/arandu arandu-api --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/arandu-io/arandu.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/arandu-api .claude/skills/arandu-api && 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
arandu-api
GitHub stars
281
Token cost
~2.5k tokens
SKILL.md length
1,130 words
Files
1
Skills in repo
12
Repo updated
First seen
Licence
MIT

At a glance

Answering a program rather than a person in an Arandu (Go) application -- a JSON Resource, a JSON answer from the same routes the pages use, problem+json errors, bearer-token authentication and…

  • Works in 4 steps: Generate the Resource: aru make:resource… → Answer from the action. Before… → Let the router write every error. Return… → …
  • The request is to add an API
  • SKILL.md covers When to use, Before you start, Contracts and imports and Procedure, plus 8 more sections
  • Calls go and bash

What it does

Arandu API is an agent skill from arandu-io/arandu. Answering a program rather than a person in an Arandu (Go) application -- a JSON Resource, a JSON answer from the same routes the pages use, problem+json errors, bearer-token authentication and Idempotency-Key replay. Use when the request is to "add an API", "return JSON", "add an endpoint for the mobile app", "API tokens", "make this POST idempotent", "the error format of the API", or when ctx.JSON, ctx.WantsJSON, JsonResource, RequireToken or Idempotent is involved. Covers aru make:resource.

Its SKILL.md is about 2.5k 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. The repository describes itself as: The Arandu project skeleton, which aru new clones. The licence is MIT.

When your agent uses it

  • The request is to add an API
  • Add an endpoint for the mobile app
  • Make this POST idempotent
  • The error format of the API

Example prompts

  • “add an API”
  • “return JSON”
  • “add an endpoint for the mobile app”
  • “/arandu-api”

Workflow steps

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

  1. Generate the Resource: aru make:resource Note writes the Resource, its
  2. Answer from the action. Before rendering, `if ctx.WantsJSON() { return
  3. Let the router write every error. Return the service's error; the JSON
  4. Give a program its own guard when it does not carry the session cookie

What it can do on your machine

Read from SKILL.md and the folder at commit b8a4273. 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:

    • go
    • bash

    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

Arandu API loads about 2.5k tokens when it runs. Until then it costs about 127 tokens; SKILL.md has 1,130 words of instructions outside code blocks.

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

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 arandu-io/arandu at commit b8a4273, republished under its MIT licence (© arandu-io). 1,130 words, ~2,500 tokens.

Download SKILL.mdSave it as .claude/skills/arandu-api/SKILL.md (or your agent's skills folder).
name
arandu-api
description
Answering a program rather than a person in an Arandu (Go) application -- a JSON Resource, a JSON answer from the same routes the pages use, problem+json errors, bearer-token authentication and Idempotency-Key replay. Use when the request is to "add an API", "return JSON", "add an endpoint for the mobile app", "API tokens", "make this POST idempotent", "the error format of the API", or when ctx.JSON, ctx.WantsJSON, JsonResource, RequireToken or Idempotent is involved. Covers aru make:resource.
license
MIT

Answering a program

When to use

A client that sends Accept: application/json -- a mobile app, a script, another service -- reading or changing a record. The routes it calls are the ones arandu-http registers; this skill is about the answer and the guards an API needs. A page is arandu-view.

Before you start

  • Read app/Http/Resources/NoteResource.go and the JSON branches of NoteController.Index, Show, Store and Publish.
  • Read the /api group in the custom block of routes/web.go: POST /api/notes and POST /api/notes/{id}/publish, behind RequireToken and Idempotent, answered by the same two actions the browser's routes use.
  • Read app/Services/PersonalAccessTokenService.go, which issues, revokes and resolves the tokens, and app/Http/Middleware/PersonalAccessTokens.go, the resolver RequireToken is given.
  • There is no routes/api.go. A JSON client is answered by the same routes; a route only a program calls sits in routes/web.go behind the guard a program carries.

Contracts and imports

piececontract
JSON Resourceapp/Http/Resources/<Entity>Resource.go: a type with ToArray() map[string]any (the fields that may leave, by name) and With() map[string]any (what goes beside data), asserted with var _ hhttp.JsonResource
answerctx.JSON(status, resource) writes {"data": ToArray(), ...With()}; ctx.TOON(status, resource) is the same Resource for a payload going to a language model, chosen in code, never from a header
askingctx.WantsJSON() reads Accept; an action that answers both says Vary: Accept
errorswritten by the router through hesape/exception as application/problem+json (RFC 9457): validation.Errors is 422 with an errors member keyed by field, a missing row 404, a refusal 403, a duplicate 409, an error with HTTPStatus() int that status
tokenmiddleware.RequireToken(d.Tokens), with d.Tokens the middleware.TokenResolver bootstrap builds: appmiddleware.NewPersonalAccessTokens(tokens), which answers middleware.ErrUnknownToken for every token the service refuses -- unknown, revoked, expired, its account gone. A route behind it reads who is asking with ctx.User(), exactly as behind RequireAuth
issuingtokens.Issue(ctx, actor, name, lifetime) on *services.PersonalAccessTokenService (App.Tokens) returns the token once, and stores only its SHA-256 as hex -- middleware.DigestToken(token).String(); tokens.Revoke(ctx, actor, id) deletes one. An account issues and revokes its own, and nothing else
CSRFCSRFProtect leaves a request with Authorization: Bearer and no valid session cookie to the route's guard. A browser that reports it cross-site is still refused 403, and a session cookie riding along still needs the CSRF token (419)
idempotencymiddleware.Idempotent(d.Idempotency, ttl), mounted after the guard that puts the subject on the request; d.Idempotency is the cache store CACHE_STORE names, which can lock and is shared across replicas when it is the RESP one

hhttp is github.com/arandu-io/hesape/http; middleware is github.com/arandu-io/framework/http/middleware.

Procedure

  1. Generate the Resource: aru make:resource Note writes the Resource, its collection and the test that holds the answer to the listed fields. It lists every column but the tenant; delete what the answer must not carry, from ToArray and from the test's list.
  2. Answer from the action. Before rendering, if ctx.WantsJSON() { return ctx.JSON(http.StatusOK, resources.NewNoteResource(found)) }, after adding Vary: Accept. A collection takes the page's next link through With.
  3. Let the router write every error. Return the service's error; the JSON client gets the problem document, the browser its page or redirect.
  4. Give a program its own guard when it does not carry the session cookie: a route in the /api group behind RequireToken, pointed at the action the browser's route already uses. Put Idempotent on a write a client may retry. The action answers a JSON client with the Resource -- Store answers 201 with Location -- and the policy decides as it does for the browser, about the account the token acts as.

Commands

  • aru make:resource <Name> writes app/Http/Resources/<Name>Resource.go and tests/Unit/<Name>Resource_test.go
  • aru route:list shows which routes a token group holds

Example

A token for a program, issued as the account it acts as, and the routes it calls -- the same lines as the /api group in routes/web.go:

go
package example

import (
	"context"
	"time"

	fhttp "github.com/arandu-io/framework/http"
	"github.com/arandu-io/framework/http/middleware"
	"github.com/arandu-io/hesape/auth"

	controllers "<module>/app/Http/Controllers"
	services "<module>/app/Services"
)

// IssueForScript gives the signed-in account a token for a script, valid for
// ninety days. The token is in the first value and nowhere else: show it once.
func IssueForScript(ctx context.Context, tokens *services.PersonalAccessTokenService, who auth.Subject) (string, error) {
	token, _, err := tokens.Issue(ctx, who, "deploy script", 90*24*time.Hour)
	return token, err
}

// APIRoutes puts the guard first and Idempotent after it, on the actions the
// browser's routes already answer.
func APIRoutes(r *fhttp.Router, tokens middleware.TokenResolver, store middleware.IdempotencyStore,
	note *controllers.NoteController) {
	api := r.Group("/api", middleware.RequireToken(tokens))
	api.Action("POST", "/notes", note.Store,
		middleware.Idempotent(store, 24*time.Hour)).Name("api.notes.store")
	api.Action("POST", "/notes/{id}/publish", note.Publish,
		middleware.Idempotent(store, 24*time.Hour)).Name("api.notes.publish")
}

The client sends Authorization: Bearer <token> and Accept: application/json, and Idempotency-Key on a write it may retry. No cookie, no CSRF token.

Show full SKILL.md (503 more words)Show less

Do not

  • Encode JSON onto the response writer or write a status by hand: json-written-by-hand. Every domain answer passes through a Resource.
  • Hand ctx.JSON the entity, or a map: the entity answers every field it will ever have, the tenant and the next secret column included.
  • Write an error format of your own. Two formats are two things every client parses.
  • Read a token from a query string or a cookie, or fall back to the session on an API route: a cookie is what CSRF reaches.
  • Mount Idempotent before the guard: it panics without a subject rather than keep one caller's answer where another could replay it.

Extending it

A computed field, or one only some readers see, goes in the custom block of ToArray. Metadata about the answer -- the next page, a total -- goes in With. A second representation of the same record is a second Resource, not a flag on the first.

Wiring

aru make:resource needs no wiring: the controller imports the Resource. A token route needs nothing new either: bootstrap/app.go already builds the token service (App.Tokens), its resolver and the idempotency store, and hands the last two to the routes as Deps.Tokens and Deps.Idempotency. The store is the cache store CACHE_STORE names -- set it to the shared one when there are replicas, because a key one process remembers is run again by the next.

Acceptance test

  • The Resource's unit test: the keys answered are exactly the listed ones.
  • A feature test as a JSON client: 200 with the fields and Vary: Accept, and a problem document (Content-Type: application/problem+json, status, title) for a missing row, a refusal, a conflict and a rejected input -- TestAJSONClientIsAnsweredThroughTheNoteResource and TestAJSONClientIsRefusedWithProblemDocuments.
  • For a token route, as tests/Feature/NotesAPI_test.go does: a write with the token and no session answers 2xx and is the token's account in its tenant; another member's record is still 403; an unknown and a revoked token answer the same 401 with WWW-Authenticate: Bearer; a write the browser reports cross-site is 403, and one riding a session cookie without the CSRF token is 419.
  • For an idempotent write: a retry with the same key answers Idempotent-Replayed: true and changes nothing twice.

Limits

This project issues tokens through the service and has no screen for it: a page that lists an account's tokens, shows a new one once and revokes them is application code to write, on the service that is already here. A token acts as its account in the tenant every sign-in of the deployment belongs to; an application whose accounts live in several tenants decides how a token's tenant is told apart -- never from the request -- and that is an arandu-ecosystem question first.

A token carries the account's stored roles and no narrower scope of its own; the policies decide every record. The generated Resource has no knowledge of who reads it; a field only some readers may see is a decision written in the custom block.

Gates

Run them all, in this order, as AGENTS.md lists them:

sh
export GOWORK=off
aru model:build --check
aru view:build
gofmt -l $(find . -name '*.go' -not -path '*/testdata/*' -not -name '*.kyse.go')
go vet ./...
bash tests/test-layout-guard.sh
go test -race ./...
go build ./...
aru doctor
<!-- arandu:begin custom -->
<!-- arandu:end custom -->

© arandu-io, MIT. 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 .agents/skills/arandu-api of arandu-io/arandu.

Open the folder on GitHubat commit b8a4273

Compare with similar skills

Arandu API 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.

Arandu API compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Arandu API this skillarandu-io/arandu281—~2.5kAutomated safety check: PassMIT
Configuring Horizoncoollabsio/coolify63k4 repos~898Automated safety check: PassMIT
Nestjs Best Practicesrolling-scopes/rsschool-app10k6 repos~1.2kAutomated safety check: PassMIT
Sub2API AdminWei-Shaw/sub2api44k1 repos~717Automated safety check: PassLGPL-3.0
Firecrawl Build Onboardingfirecrawl/firecrawl190k1 repos~1.4kAutomated safety check: NotesISC
Obsidian BasesAtmosphere/atmosphere3.8k22 repos~3.2kAutomated safety check: PassApache-2.0

Similar skills

  • Configuring Horizon

    coollabsio/coolify

    A skill your agent uses whenever the user mentions Horizon by name in a Laravel context.

    63k GitHub starsUsed in 4 repos~898 tokens
    Backend & APIsAuto-check passed
  • Nestjs Best Practices

    rolling-scopes/rsschool-app

    NestJS best practices and architecture patterns for building production-ready applications.

    10k GitHub starsUsed in 6 repos~1.2k tokens
    Backend & APIsAuto-check passed
  • Sub2API Admin

    Wei-Shaw/sub2api

    Manages a Sub2API deployment from the command line: accounts, redeem and invitation codes, groups, proxies, imports, exports and raw admin API calls.

    44k GitHub starsUsed in 1 repo~717 tokens
    Backend & APIsAuto-check passed
  • Firecrawl Build Onboarding

    firecrawl/firecrawl

    Gets Firecrawl working in a project: signs you in through the browser, saves FIRECRAWL_API_KEY to .env and picks the first SDK or REST path.

    190k GitHub starsUsed in 1 repo~1.4k tokens
    Backend & APIsAuto-check: notes
  • Obsidian Bases

    Atmosphere/atmosphere

    Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries.

    3.8k GitHub starsUsed in 22 repos~3.2k tokens
    Backend & APIsAuto-check passed
  • Fortify Development

    coollabsio/coolify

    ACTIVATE when the user works on authentication in Laravel. An agent skill from coollabsio/coolify.

    63k GitHub starsUsed in 4 repos~1.9k tokens
    Backend & APIsAuto-check passed

More from arandu-io/arandu

All 12 skills in this repo
  • Arandu Async

    arandu-io/arandu

    Work that does not happen inside the request in an Arandu (Go) application -- background jobs and the worker, scheduled tasks, domain events through the outbox, listeners, notifications, mail and…

    281 GitHub stars~2.7k tokensUpdated yesterday
    Auto-check passed
  • Decides whether a feature belongs in the application or in one of five shared Arandu modules before adding permissions, wallets, tags, Markdown rendering or API docs.

    281 GitHub stars~1.8k tokensUpdated yesterday
    Auto-check passed
  • Arandu Feature

    arandu-io/arandu

    Start here for any change to an Arandu (Go) application that adds or changes behaviour -- "add invoices", "let users publish a post", "send a weekly report", "call the payment provider", "expose…

    281 GitHub stars~2.5k tokensUpdated yesterday
    Auto-check passed
  • Arandu HTTP

    arandu-io/arandu

    Controllers, requests and routes of an Arandu (Go) application -- the seven resource actions, a resource nested under another, a singleton, a single-action (invokable) controller, a named action…

    281 GitHub stars~2.5k tokensUpdated yesterday
    Auto-check passed
  • Arandu Integrations

    arandu-io/arandu

    Reaching other systems from an Arandu (Go) application, and letting them reach it -- the client of an external API with its interface and fake, webhooks sent and received, and tools, resources and…

    281 GitHub stars~3.1k tokensUpdated yesterday
    Auto-check passed
  • Arandu Module Generator

    arandu-io/arandu

    Adds a new entity, resource or CRUD module to an Arandu Go application by writing a YAML specification instead of hand-writing the Go code.

    281 GitHub stars~2.4k tokensUpdated yesterday
    Auto-check passed

Categories

Questions about Arandu API

What does Arandu API do?

Answering a program rather than a person in an Arandu (Go) application -- a JSON Resource, a JSON answer from the same routes the pages use, problem+json errors, bearer-token authentication and…. Arandu API is an agent skill from arandu-io/arandu. Answering a program rather than a person in an Arandu (Go) application -- a JSON Resource, a JSON answer from the same routes the pages use, problem+json errors, bearer-token authentication and Idempotency-Key replay.

When should I use Arandu API?

Arandu API fits situations like: the request is to add an API; add an endpoint for the mobile app; make this POST idempotent; the error format of the API.

How do I install Arandu API in Claude Code?

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

How do I install Arandu API in Codex?

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

Can I use Arandu API 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 arandu-io/arandu --skill arandu-api -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/arandu-api, .gemini/skills/arandu-api, .github/skills/arandu-api and .opencode/skills/arandu-api in your project.

What does Arandu API need to run?

Going by SKILL.md and its folder, Arandu API needs the command-line tools its instructions call (go and bash).

Does Arandu API 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 Arandu API 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 Arandu API use?

Arandu API is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Arandu API use?

About 2.5k tokens (SKILL.md is roughly 10k 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 Arandu API?

Skills that share tags, products or a category with Arandu API: Configuring Horizon (coollabsio/coolify, 63k stars), Nestjs Best Practices (rolling-scopes/rsschool-app, 10k stars), Sub2API Admin (Wei-Shaw/sub2api, 44k stars) and Firecrawl Build Onboarding (firecrawl/firecrawl, 190k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Arandu API?

arandu-io (a GitHub organization) maintains it in arandu-io/arandu, which has 281 GitHub stars. The repository holds 12 skills in this directory. The repository was last updated on October 10, 2026.

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