Skip to main content
Automatic REST APIs — Laravel · Rails · NestJS

The right way
AI agents write code.

Register a model, get a secure API. Permissions, validation, multi-tenancy, and audit trails — all built in. AI agents ship better code when the framework, not the model, owns the conventions.

$composer require rhino-project/rhino-laravel
28 built-in features0 AI tokens for scaffolding3 frameworksMIT licensed
~/acme — zsh
live
AI-Powered

Describe what you need.
AI writes the Blueprint.

Claude and Cursor read the Rhino conventions and emit a YAML blueprint. You review it like a diff. The framework — not the model — turns it into production code.

  • Declarative. No more guessing at controllers.
  • Reviewable. A 30-line YAML beats a 300-line PR.
  • Deterministic. Same YAML → same code, every time.
claude code — ~/acme
U
You
Create a Contract model with title, total_value, and status. Admins can create all fields but only update title + status. Viewers can see id, title, status only.
✦
Claude · rhino-blueprint
Running /rhino-blueprint. Here's the YAML:
model: Contract
columns:
  - title:       string # required
  - total_value: decimal
  - status:      enum(draft, signed, void)
permissions:
  admin:
    create: [title, total_value, status]
    update: [title, status]
    show:   *
  viewer:
    show:   [id, title, status]
U
You
Now generate the code.
✦
Claude · rhino-blueprint
php artisan rhino:blueprint contracts.yaml
✓ Model
✓ Migration
✓ Factory
✓ Policy
✓ Tests
✓ Seeder
Done — 6 files generated. Zero AI tokens used.
Zero-Token Generation

From YAML to production code.
Fully deterministic.

Define the permission matrix once. Generate policies, migrations, tests, and seeders — no AI in the loop.

.rhino/blueprints/contracts.yaml
# Source of truth
model: Contract
traits: [uuid, soft_deletes, org]

columns:
  - title:       string(140)
  - total_value: decimal(12,2)
  - status:      enum(draft,signed,void)

permissions:
  admin:
    create: *
    update: [title, status]
    show:   *
  viewer:
    show:   [id, title, status]

query:
  filters: [status, owner_id]
  sorts:   [created_at, total_value]
  search:  [title]
rhino:blueprint
app/Policies/ContractPolicy.php
class ContractPolicy extends ResourcePolicy {
  public function permittedAttributesForShow(User $user): array
  {
    return match ($user->roleFor($this->org)) {
      'admin'  => ['*'],
      'viewer' => ['id', 'title', 'status'],
      default  => [],
    };
  }

  public function permittedAttributesForUpdate(User $user): array
  {
    return match ($user->roleFor($this->org)) {
      'admin' => ['title', 'status'],
      default => [],
    };
  }
}
0
AI tokens used
fully deterministic
6
Files generated
model • migration • factory • policy • tests • seeder
28
Built-in features
CRUD • auth • policies • multi-tenancy
3
Frameworks
Laravel • Rails • NestJS
Built-In

Everything you need,
out of the box.

❯rhino init

AI-Native Architecture

Declarative, config-driven models that AI agents can read, scaffold, and extend. Built to be prompted, not hand-coded.

ai-ready01 / 06
❯rhino:blueprint

Blueprint Generator

Define your permission matrix in YAML, generate fully working policies, tests, and seeders — zero AI tokens, fully deterministic.

zero-token02 / 06
❯resource :posts

Automatic CRUD

Register a model, get full REST endpoints instantly. Index, show, store, update, destroy — plus soft-delete, restore, force-delete.

zero-boilerplate03 / 06
❯POST /login

Auth, Policies & RBAC

Token-based auth, role-based access control, and a ResourcePolicy base with attribute-level permissions. Per org, per role.

security04 / 06
❯?filter[x]=y&sort=-created

Advanced Querying

Filtering, sorting, full-text search, pagination, sparse fieldsets, and eager-loading — all via query string. No controller work.

spatie-powered05 / 06
❯org:acme

Multi-Tenancy

Organization-based data isolation with BelongsToOrganization. Cross-tenant FKs are auto-scoped. Subdomain or route-prefix.

saas-ready06 / 06
How it works

Register a model.
Get a full API. Use a hook.

1Define your model———2Register in config———3Use the hook
app/Models/Post.php
class Post extends Model {
  use HasRhino, BelongsToOrganization, SoftDeletes;

  protected $fillable = ['title', 'body', 'published_at'];

  public $allowedFilters  = ['author_id', 'published'];
  public $allowedSorts    = ['-published_at', 'title'];
  public $allowedIncludes = ['author', 'comments'];

  public function validationRules(): array {
    return ['title' => 'required|max:120', 'body' => 'required'];
  }
}
config/rhino.php
return [
  'resources' => [
    App\\Models\\Post::class => [
      'slug'       => 'posts',
      'policy'     => App\\Policies\\PostPolicy::class,
      'middleware' => ['auth:sanctum'],
    ],
  ],
];
auto-generated endpoints
instant
GET/api/posts# list with filters, sorts, includes
POST/api/posts# create with validation
GET/api/posts/{id}# show with relationships
PUT/api/posts/{id}# update with validation
DELETE/api/posts/{id}# soft delete
GET/api/posts/trashed# list soft-deleted
POST/api/posts/{id}/restore# restore
DELETE/api/posts/{id}/force-delete# permanent delete
Ready to ship

Stop writing boilerplate.
Start shipping.

Install Rhino and ship your API today — in Laravel, Rails, or NestJS.

# 60 seconds to first endpoint
composer require rhino-project/rhino-laravel
php artisan rhino:install
php artisan rhino:generate Post
→ 8 endpoints ready at /api/posts