Agent skill

API Patterns

by dilolabs in dilolabs/nosia

Builds REST APIs using respondto blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy.

MITAuto-check passedBackend & APIs

Install API Patterns

skills CLI
$ npx skills add dilolabs/nosia --skill api-patterns -a claude-code

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

GitHub CLI
$ gh skill install dilolabs/nosia api-patterns --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/dilolabs/nosia.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.vibe/skills/api-patterns .claude/skills/api-patterns && 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
api-patterns
GitHub stars
213
Used in
1 other repo
Token cost
~2.5k tokens
SKILL.md length
263 words
Files
4 (incl. references)
Skills in repo
15
Repo updated
First seen
Licence
MIT

At a glance

Builds REST APIs using respondto blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy.

  • Adding API endpoints
  • SKILL.md covers Philosophy: Same Controllers,…, Project Knowledge, Pattern 1: Respond To Blocks and Pattern 2: Jbuilder Templates, plus 6 more sections
  • Calls rails and curl
  • Token authentication

What it does

API Patterns is an agent skill from dilolabs/nosia. Builds REST APIs using respondto blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy. Use when adding API endpoints, JSON responses, token authentication, pagination, or when user mentions API, JSON, REST, or Jbuilder. WHEN NOT: For HTML-only controllers (use crud-patterns), for webhook delivery (use event-tracking).

Its SKILL.md is about 2.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/api-auth.md`, `references/api-versioning.md` and `references/jbuilder-templates.md`). Compatibility notes: Ruby 3.3+, Rails 8.0+, Jbuilder

It sits in Backend & APIs, covering REST APIs, Webhooks and Product analytics. The repository describes itself as: Self-hosted AI RAG + MCP Platform. The licence is MIT.

When your agent uses it

  • Adding API endpoints
  • Token authentication
  • User mentions API

Example prompts

  • “Use the api-patterns skill to build REST APIs using respondto blocks with Jbuilder templates following the 37signals…”
  • “/api-patterns”

Requirements

  • Compatibility (from SKILL.md): Ruby 3.3+, Rails 8.0+, Jbuilder

What it can do on your machine

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

    • rails
    • curl

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

  • Network

    No URLs in SKILL.md. Its commands use curl, which can reach the network depending on how they are called.

    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.

  • Compatibility

    Ruby 3.3+, Rails 8.0+, Jbuilder

    From compatibility in the SKILL.md frontmatter.

Context cost

API Patterns loads about 2.5k tokens when it runs, and up to ~5.8k if it reads all its reference files. Until then it costs about 95 tokens; SKILL.md has 263 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~95
When it runs · the whole SKILL.md, loaded when a task matches
~2.5k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~5.8k

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 dilolabs/nosia at commit 0ef5e5d, republished under its MIT licence (© dilolabs). 263 words, ~2,522 tokens.

Download SKILL.mdSave it as .claude/skills/api-patterns/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
api-patterns
description
Builds REST APIs using respond_to blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy. Use when adding API endpoints, JSON responses, token authentication, pagination, or when user mentions API, JSON, REST, or Jbuilder. WHEN NOT: For HTML-only controllers (use crud-patterns), for webhook delivery (use event-tracking).
compatibility
Ruby 3.3+, Rails 8.0+, Jbuilder
license
MIT

API Patterns

Philosophy: Same Controllers, Different Formats

  • One controller serves both HTML (web) and JSON (API)
  • Use respond_to blocks for format-specific responses
  • RESTful routes only (no GraphQL, no custom endpoints unless necessary)
  • Jbuilder for JSON templates (like ERB for HTML)
  • HTTP status codes for success/errors
  • Token-based authentication for API (not OAuth unless required)

Project Knowledge

Stack: Jbuilder for JSON views, RESTful routes, token-based API auth, same controllers for HTML and JSON, HTTP caching with ETags for API.

Multi-tenancy: API uses same account scoping (/accounts/:account_id/...), token scoped to account.

Commands:

bash
# Generate API token model
rails generate model ApiToken user:references account:references \
  token:string last_used_at:datetime

# Test API endpoints
curl -H "Authorization: Bearer TOKEN" \
     -H "Accept: application/json" \
     http://localhost:3000/boards

Pattern 1: Respond To Blocks

ruby
class BoardsController < ApplicationController
  before_action :set_board, only: [:show, :edit, :update, :destroy]

  def index
    @boards = Current.account.boards.includes(:creator).order(created_at: :desc)

    respond_to do |format|
      format.html  # renders index.html.erb
      format.json  # renders index.json.jbuilder
    end
  end

  def show
    respond_to do |format|
      format.html
      format.json
    end
  end

  def create
    @board = Current.account.boards.build(board_params)
    @board.creator = Current.user

    respond_to do |format|
      if @board.save
        format.html { redirect_to @board, notice: "Board created" }
        format.json { render :show, status: :created, location: @board }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @board.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @board.update(board_params)
        format.html { redirect_to @board, notice: "Board updated" }
        format.json { render :show, status: :ok }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @board.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @board.destroy

    respond_to do |format|
      format.html { redirect_to boards_path, notice: "Board deleted" }
      format.json { head :no_content }
    end
  end

  private

  def set_board
    @board = Current.account.boards.find(params[:id])
  end

  def board_params
    params.require(:board).permit(:name, :description)
  end
end

Pattern 2: Jbuilder Templates

See @references/jbuilder-templates.md for full details.

ruby
# app/views/boards/index.json.jbuilder
json.array! @boards do |board|
  json.extract! board, :id, :name, :description, :created_at, :updated_at
  json.creator do
    json.extract! board.creator, :id, :name, :email
  end
  json.url board_url(board, format: :json)
end

# app/views/boards/show.json.jbuilder
json.extract! @board, :id, :name, :description, :created_at, :updated_at
json.creator do
  json.extract! @board.creator, :id, :name, :email
end
json.cards @board.cards, partial: "cards/card", as: :card
json.url board_url(@board, format: :json)

# app/views/cards/_card.json.jbuilder
json.extract! card, :id, :title, :description, :created_at, :updated_at
json.creator do
  json.extract! card.creator, :id, :name
end
json.url board_card_url(card.board, card, format: :json)

Pattern 3: API Token Authentication

See @references/api-auth.md for full details.

ruby
# app/models/api_token.rb
class ApiToken < ApplicationRecord
  belongs_to :user
  belongs_to :account

  has_secure_token :token, length: 32

  validates :name, presence: true
  validates :token, presence: true, uniqueness: true

  scope :active, -> { where(active: true) }

  def use!
    touch(:last_used_at)
  end
end

# app/controllers/concerns/api_authenticatable.rb
module ApiAuthenticatable
  extend ActiveSupport::Concern

  included do
    before_action :authenticate_from_token, if: :api_request?
  end

  private

  def api_request?
    request.format.json?
  end

  def authenticate_from_token
    token = request.headers["Authorization"]
      &.match(/Bearer (.+)/)&.captures&.first

    if token
      @api_token = ApiToken.active.find_by(token: token)
      if @api_token
        @api_token.use!
        Current.user = @api_token.user
        Current.account = @api_token.account
      else
        render json: { error: "Unauthorized" }, status: :unauthorized
      end
    else
      render json: { error: "Unauthorized" }, status: :unauthorized
    end
  end
end

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include ApiAuthenticatable

  skip_before_action :verify_authenticity_token, if: :api_request?
  before_action :authenticate_user!, unless: :api_request?
end

Pattern 4: Error Handling

ruby
module ApiErrorHandling
  extend ActiveSupport::Concern

  included do
    rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
    rescue_from ActiveRecord::RecordInvalid, with: :render_unprocessable_entity
    rescue_from ActionController::ParameterMissing, with: :render_bad_request
  end

  private

  def render_not_found(exception)
    respond_to do |format|
      format.html { raise exception }
      format.json { render json: { error: "Not found" }, status: :not_found }
    end
  end

  def render_unprocessable_entity(exception)
    respond_to do |format|
      format.html { raise exception }
      format.json do
        render json: {
          error: "Validation failed",
          details: exception.record.errors.as_json
        }, status: :unprocessable_entity
      end
    end
  end

  def render_bad_request(exception)
    respond_to do |format|
      format.html { raise exception }
      format.json do
        render json: { error: "Bad request", message: exception.message },
               status: :bad_request
      end
    end
  end
end

Pattern 5: HTTP Caching for API

ruby
def index
  @boards = Current.account.boards.includes(:creator).order(created_at: :desc)

  respond_to do |format|
    format.html
    format.json do
      if stale?(@boards)
        render :index
      end
    end
  end
end

def show
  @board = Current.account.boards.find(params[:id])

  respond_to do |format|
    format.html
    format.json do
      if stale?(@board)
        render :show
      end
    end
  end
end

Pattern 6: Pagination

See @references/api-versioning.md for versioning details.

ruby
def index
  @boards = Current.account.boards.includes(:creator)
    .order(created_at: :desc)
    .page(params[:page])
    .per(params[:per_page] || 25)

  respond_to do |format|
    format.html
    format.json do
      response.headers["X-Total-Count"] = @boards.total_count.to_s
      response.headers["X-Page"] = @boards.current_page.to_s
      response.headers["X-Per-Page"] = @boards.limit_value.to_s
      render :index
    end
  end
end

# app/views/boards/index.json.jbuilder
json.boards @boards do |board|
  json.extract! board, :id, :name, :description, :created_at
  json.url board_url(board, format: :json)
end

json.pagination do
  json.current_page @boards.current_page
  json.per_page @boards.limit_value
  json.total_pages @boards.total_pages
  json.total_count @boards.total_count
  json.next_page boards_url(page: @boards.next_page, format: :json) if @boards.next_page
  json.prev_page boards_url(page: @boards.prev_page, format: :json) if @boards.prev_page
end

Cursor-based alternative:

ruby
def index
  @boards = Current.account.boards.order(created_at: :desc)
  @boards = @boards.where("created_at < ?", Time.zone.parse(params[:before])) if params[:before]
  @boards = @boards.limit(params[:limit] || 25)

  respond_to do |format|
    format.html
    format.json
  end
end

Pattern 7: Batch Operations

ruby
class Cards::BatchController < ApplicationController
  before_action :set_board

  def update
    results, errors = [], []

    batch_params[:cards].each do |card_params|
      card = @board.cards.find(card_params[:id])
      if card.update(card_params.except(:id))
        results << card
      else
        errors << { id: card.id, errors: card.errors }
      end
    end

    respond_to do |format|
      format.json do
        if errors.empty?
          render json: { success: true, cards: results }, status: :ok
        else
          render json: { success: false, errors: errors }, status: :unprocessable_entity
        end
      end
    end
  end
end

Boundaries

Always
  • Use same controllers for HTML and JSON (respond_to blocks)
  • Use Jbuilder for JSON views (not inline JSON in controllers)
  • Return proper HTTP status codes (201, 404, 422, etc.)
  • Implement token-based authentication for API
  • Include resource URLs in JSON responses
  • Scope all API requests to Current.account
  • Use ETags for HTTP caching
  • Test both HTML and JSON responses
Ask First
  • Whether to version API (most apps don't need it initially)
  • Pagination strategy (page-based vs cursor-based)
  • Whether to support batch operations
  • Rate limiting requirements
Never
  • Use GraphQL (stick to REST)
  • Create separate API controllers when respond_to works
  • Use Active Model Serializers (use Jbuilder)
  • Inline JSON in controllers (use views)
  • Skip authentication for API endpoints
  • Return HTML errors for JSON requests
  • Use session-based auth for API (use tokens)

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

Files

SKILL.md and 3 other files (references) in .vibe/skills/api-patterns of dilolabs/nosia.

  • SKILL.md
  • references/api-auth.md
  • references/api-versioning.md
  • references/jbuilder-templates.md

Open the folder on GitHubat commit 0ef5e5d

Used in 1 other repository

We found 3 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in dilolabs/nosia, which our catalogue first saw on October 7, 2026.

Compare with similar skills

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

API Patterns compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
API Patterns this skilldilolabs/nosia2131 repos~2.5kAutomated safety check: PassMIT
Frappe Core APIImpertio-Studio/Frappe_Claude_Skill_Package1871 repos~3.2kAutomated safety check: PassMIT
Frappe Errors APIImpertio-Studio/Frappe_Claude_Skill_Package1871 repos~4kAutomated safety check: PassMIT
Fishjam Platformsoftware-mansion-labs/skills291—~1.7kAutomated safety check: PassMIT
Kreuzberg Cloudhashgraph-online/awesome-codex-plugins1.2k—~2.7kAutomated safety check: PassMIT
Databuddydatabuddy-analytics/Databuddy1.2k—~2.1kAutomated safety check: PassAGPL-3.0

Similar skills

  • Frappe Core API

    Impertio-Studio/Frappe_Claude_Skill_Package

    A skill your agent uses when building ERPNext/Frappe API integrations (v14/v15/v16) including REST API, RPC API, authentication, webhooks, and rate limiting.

    187 GitHub starsUsed in 1 repo~3.2k tokens
    Backend & APIsAuto-check passed
  • Frappe Errors API

    Impertio-Studio/Frappe_Claude_Skill_Package

    A skill your agent uses when debugging or handling API errors in Frappe/ERPNext v14/v15/v16.

    187 GitHub starsUsed in 1 repo~4k tokens
    Backend & APIsAuto-check passed
  • Fishjam Platform

    software-mansion-labs/skills

    Fishjam platform fundamentals — domain model and auth shared by all SDKs.

    291 GitHub stars~1.7k tokensUpdated 9 days ago
    Backend & APIsAuto-check passed
  • Kreuzberg Cloud

    hashgraph-online/awesome-codex-plugins

    Managed Kreuzberg document intelligence at api.kreuzberg.dev.

    1.2k GitHub stars~2.7k tokensUpdated today
    Backend & APIsAuto-check passed
  • Databuddy

    databuddy-analytics/Databuddy

    Integrate Databuddy analytics using the SDK, REST API, or MCP.

    1.2k GitHub stars~2.1k tokensUpdated today
    Backend & APIsAuto-check passed
  • Laravel Specialist

    Jeffallan/claude-skills

    Builds Laravel 10+ applications with Eloquent models, Sanctum authentication, Horizon queues, API resources and Livewire components, tested with Pest or PHPUnit.

    12k GitHub starsUsed in 1 repo~2.1k tokens
    Backend & APIsAuto-check passed

More from dilolabs/nosia

All 15 skills in this repo
  • Auth Setup

    dilolabs/nosia

    Implements custom passwordless authentication without Devise.

    213 GitHub starsUsed in 1 repo~2.9k tokens
    Auto-check passed
  • Caching Patterns

    dilolabs/nosia

    Implements HTTP caching with ETags, fragment caching, Russian doll caching, and Solid Cache configuration.

    213 GitHub starsUsed in 1 repo~1.9k tokens
    Auto-check passed
  • Concern Patterns

    dilolabs/nosia

    Creates and refactors model and controller concerns for shared behavior.

    213 GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check passed
  • Event Tracking

    dilolabs/nosia

    Builds event tracking, activity feeds, and webhook systems following 37signals patterns with a generic Event model and Eventable concern.

    213 GitHub starsUsed in 1 repo~3.3k tokens
    Auto-check passed
  • Job Patterns

    dilolabs/nosia

    Implements shallow background jobs with later/now conventions using Solid Queue.

    213 GitHub starsUsed in 1 repo~1.6k tokens
    Auto-check passed
  • Mailer Patterns

    dilolabs/nosia

    Creates minimal Action Mailer classes with bundled notification patterns following 37signals conventions.

    213 GitHub starsUsed in 1 repo~2.6k tokens
    Auto-check passed

Categories

Questions about API Patterns

What does API Patterns do?

Builds REST APIs using respondto blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy. API Patterns is an agent skill from dilolabs/nosia. Builds REST APIs using respondto blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy.

When should I use API Patterns?

API Patterns fits situations like: adding API endpoints; token authentication; user mentions API.

How do I install API Patterns in Claude Code?

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

How do I install API Patterns in Codex?

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

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

What does API Patterns need to run?

Going by SKILL.md and its folder, API Patterns needs the command-line tools its instructions call (rails and curl). Compatibility (from SKILL.md): Ruby 3.3+, Rails 8.0+, Jbuilder.

Does API Patterns access the network?

SKILL.md contains no URLs. Its commands use curl, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is API Patterns 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 API Patterns use?

API Patterns 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 API Patterns 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. Its references folder adds about 3.3k tokens, read only when the agent opens those files.

What are the alternatives to API Patterns?

Skills that share tags, products or a category with API Patterns: Frappe Core API (Impertio-Studio/Frappe_Claude_Skill_Package, 187 stars), Frappe Errors API (Impertio-Studio/Frappe_Claude_Skill_Package, 187 stars), Fishjam Platform (software-mansion-labs/skills, 291 stars) and Kreuzberg Cloud (hashgraph-online/awesome-codex-plugins, 1.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains API Patterns?

dilolabs (a GitHub organization) maintains it in dilolabs/nosia, which has 213 GitHub stars. The repository holds 15 skills in this directory. The repository was last updated on September 9, 2026.

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