Agent skill

bknd-api-discovery

Use when exploring Bknd's auto-generated API endpoints. Covers REST endpoint patterns, route listing, module base paths, SDK method mapping, admin panel API explorer, and understanding the API structure.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/bknd-api-discovery

SKILL.md

API Discovery

Explore and understand Bknd's auto-generated REST API endpoints.

Prerequisites

  • Running Bknd instance (local or deployed)
  • Access to admin panel (optional but helpful)
  • Basic understanding of REST APIs

When to Use UI Mode

  • Browsing available entities and their fields
  • Viewing schema structure visually
  • Quick endpoint exploration via browser

UI steps: Admin Panel > Data > Entities

When to Use Code Mode

  • Listing all registered routes programmatically
  • Understanding endpoint patterns for integration
  • Debugging route registration issues
  • Building API documentation

Understanding Bknd's API Structure

Bknd auto-generates REST endpoints for all configured modules:

┌─────────────────────────────────────────────────────────────┐
│                    Bknd API Structure                       │
├─────────────────────────────────────────────────────────────┤
│  /api/data      → CRUD for all entities                     │
│  /api/auth      → Authentication (login, register, logout)  │
│  /api/media     → File uploads and serving                  │
│  /api/system    → System operations                         │
│  /flow          → Flow management and triggers              │
│  /admin         → Admin UI (if enabled)                     │
└─────────────────────────────────────────────────────────────┘

Code Approach

Step 1: List All Routes (CLI)

Use the debug command to list all registered routes:

bash
bknd debug routes

Output:

GET     /admin/*
GET     /api/auth/me
POST    /api/auth/password/login
POST    /api/auth/logout
POST    /api/auth/register
GET     /api/data/:entity
POST    /api/data/:entity
GET     /api/data/:entity/:id
PATCH   /api/data/:entity/:id
DELETE  /api/data/:entity/:id
POST    /api/media/upload
GET     /api/media/:path
...

Step 2: Data API Endpoints

All entities get CRUD endpoints automatically:

Method Path Description SDK Method
GET /api/data/:entity List records api.data.readMany(entity)
POST /api/data/:entity/query List (complex query) api.data.readMany(entity, query)
GET /api/data/:entity/:id Get single record api.data.readOne(entity, id)
GET /api/data/:entity/:id/:ref Get related records api.data.readManyByReference(...)
POST /api/data/:entity Create record(s) api.data.createOne/Many(entity, data)
PATCH /api/data/:entity/:id Update single api.data.updateOne(entity, id, data)
PATCH /api/data/:entity Update many api.data.updateMany(entity, where, data)
DELETE /api/data/:entity/:id Delete single api.data.deleteOne(entity, id)
DELETE /api/data/:entity Delete many api.data.deleteMany(entity, where)
POST /api/data/:entity/fn/count Count records api.data.count(entity, where)
POST /api/data/:entity/fn/exists Check existence api.data.exists(entity, where)

Example: Explore posts entity

bash
# List all posts
curl http://localhost:7654/api/data/posts

# Get post by ID
curl http://localhost:7654/api/data/posts/1

# Get with query params
curl "http://localhost:7654/api/data/posts?limit=10&sort[created_at]=desc"

# Get with relations
curl "http://localhost:7654/api/data/posts?with[]=author&with[]=comments"

# Complex query via POST
curl -X POST http://localhost:7654/api/data/posts/query \
  -H "Content-Type: application/json" \
  -d '{"where": {"status": "published"}, "limit": 10}'

Step 3: Auth API Endpoints

Method Path Description
GET /api/auth/me Current user info
POST /api/auth/:strategy/login Login (e.g., /api/auth/password/login)
POST /api/auth/register Register new user
POST /api/auth/logout Logout
GET /api/auth/:strategy/redirect OAuth redirect
GET /api/auth/:strategy/callback OAuth callback

Example:

bash
# Check current user
curl http://localhost:7654/api/auth/me \
  -H "Authorization: Bearer $TOKEN"

# Login
curl -X POST http://localhost:7654/api/auth/password/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@test.com", "password": "pass123"}'

# Register
curl -X POST http://localhost:7654/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "new@test.com", "password": "pass123"}'

Step 4: Media API Endpoints

Method Path Description
POST /api/media/upload Upload file
GET /api/media/:path Serve/download file

Example:

bash
# Upload file
curl -X POST http://localhost:7654/api/media/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@image.png"

# Serve file
curl http://localhost:7654/api/media/uploads/image.png

Step 5: Flow Endpoints

Method Path Description
GET /flow List all flows
GET /flow/:name Get flow details
GET /flow/:name/run Manually run flow
* Custom trigger path HTTP trigger endpoints

Example:

bash
# List flows
curl http://localhost:7654/flow

# Run flow manually
curl http://localhost:7654/flow/my-flow/run

Step 6: Programmatic Route Discovery

Access route information from your code:

typescript
import { App } from "bknd";

const app = new App({ /* config */ });
await app.build();

// Get Hono server instance
const server = app.server;

// Routes are registered on the Hono instance
// Use bknd debug routes for listing

Step 7: Discover Entity Schema

Query the system to understand available entities:

typescript
import { Api } from "bknd";

const api = new Api({ host: "http://localhost:7654" });

// List available entities by checking which respond
const entities = ["posts", "users", "comments", "categories"];

for (const entity of entities) {
  const { ok } = await api.data.readMany(entity, { limit: 1 });
  if (ok) {
    console.log(`Entity exists: ${entity}`);
  }
}

Step 8: Response Format Discovery

All endpoints return consistent response format:

Success (list):

json
{
  "data": [
    { "id": 1, "title": "Post 1" },
    { "id": 2, "title": "Post 2" }
  ],
  "meta": {
    "total": 50,
    "limit": 20,
    "offset": 0
  }
}

Success (single):

json
{
  "data": { "id": 1, "title": "Post 1" }
}

Error:

json
{
  "error": {
    "message": "Record not found",
    "code": "NOT_FOUND"
  }
}

UI Approach: Admin Panel

Step 1: Access Admin Panel

Navigate to: http://localhost:7654/admin

Step 2: Browse Entities

  1. Click Data in sidebar
  2. View list of all entities
  3. Click entity to see:
    • All fields with types
    • Relationships
    • Sample data

Step 3: View Entity Structure

Admin panel shows:

  • Field names and types
  • Required vs optional fields
  • Default values
  • Relation configurations

Step 4: Test Queries

Admin panel provides:

  • Data browser for each entity
  • Filter/sort interface
  • Create/edit forms
  • Relationship navigation

Query Parameter Reference

Data Endpoints

Parameter Example Description
limit ?limit=10 Max records to return
offset ?offset=20 Skip N records
sort[field] ?sort[created_at]=desc Sort by field
where[field] ?where[status]=published Filter by field
with[] ?with[]=author Include relation
join[] ?join[]=author Join relation (same result)
select[] ?select[]=id&select[]=title Select specific fields

Complex Queries (POST)

bash
curl -X POST http://localhost:7654/api/data/posts/query \
  -H "Content-Type: application/json" \
  -d '{
    "where": {
      "status": "published",
      "views": { "$gt": 100 }
    },
    "sort": { "created_at": "desc" },
    "limit": 10,
    "offset": 0,
    "with": ["author", "category"]
  }'

SDK Method to Endpoint Mapping

typescript
import { Api } from "bknd";
const api = new Api({ host: "http://localhost:7654" });

// Method                        → Endpoint
api.data.readMany("posts")       // GET  /api/data/posts
api.data.readOne("posts", 1)     // GET  /api/data/posts/1
api.data.createOne("posts", {})  // POST /api/data/posts
api.data.updateOne("posts", 1, {})// PATCH /api/data/posts/1
api.data.deleteOne("posts", 1)   // DELETE /api/data/posts/1

api.auth.login("password", {})   // POST /api/auth/password/login
api.auth.register({})            // POST /api/auth/register
api.auth.logout()                // POST /api/auth/logout
api.auth.me()                    // GET  /api/auth/me

api.media.upload(file)           // POST /api/media/upload

Testing Endpoints

Quick Health Check

bash
# Check if API is running
curl http://localhost:7654/api/auth/me
# Returns user info or 401

Explore Available Data

bash
# Try common entity names
for entity in posts users comments products orders; do
  echo "Testing $entity..."
  curl -s -o /dev/null -w "%{http_code}" http://localhost:7654/api/data/$entity
  echo ""
done

Debug Script

typescript
async function discoverApi(host: string) {
  const api = new Api({ host });

  console.log("API Discovery Report");
  console.log("===================");

  // Test auth
  const { ok: authOk } = await api.auth.me();
  console.log(`Auth endpoint: ${authOk ? "working" : "requires auth"}`);

  // Test common entities
  const testEntities = ["posts", "users", "comments", "products"];
  for (const entity of testEntities) {
    const { ok, meta } = await api.data.readMany(entity, { limit: 1 });
    if (ok) {
      console.log(`Entity "${entity}": ${meta?.total ?? "?"} records`);
    }
  }
}

discoverApi("http://localhost:7654");

Common Pitfalls

Wrong Base Path

Problem: 404 errors on API calls

Fix: Use correct base paths:

bash
# WRONG
curl http://localhost:7654/data/posts
curl http://localhost:7654/posts

# CORRECT
curl http://localhost:7654/api/data/posts

Auth Strategy in Path

Problem: Login fails

Fix: Include strategy name:

bash
# WRONG
curl -X POST http://localhost:7654/api/auth/login

# CORRECT (password strategy)
curl -X POST http://localhost:7654/api/auth/password/login

Query vs GET Params

Problem: Complex queries don't work via GET

Fix: Use POST for complex queries:

bash
# Limited filtering via GET
curl "http://localhost:7654/api/data/posts?where[status]=published"

# Complex filtering via POST
curl -X POST http://localhost:7654/api/data/posts/query \
  -H "Content-Type: application/json" \
  -d '{"where": {"$or": [{"status": "published"}, {"featured": true}]}}'

Entity Name Mismatch

Problem: 404 on entity endpoints

Fix: Use exact entity names (case-sensitive, usually lowercase):

bash
# WRONG
curl http://localhost:7654/api/data/Posts
curl http://localhost:7654/api/data/post

# CORRECT
curl http://localhost:7654/api/data/posts

Missing Content-Type

Problem: POST/PATCH returns 400

Fix: Include Content-Type header:

bash
# WRONG
curl -X POST http://localhost:7654/api/data/posts \
  -d '{"title": "Test"}'

# CORRECT
curl -X POST http://localhost:7654/api/data/posts \
  -H "Content-Type: application/json" \
  -d '{"title": "Test"}'

Endpoint Quick Reference

Module Base Path Key Operations
Data /api/data CRUD for all entities
Auth /api/auth Login, register, logout, me
Media /api/media Upload, serve files
Flows /flow List, view, run flows
Admin /admin Admin UI

DOs and DON'Ts

DO:

  • Use bknd debug routes to list all endpoints
  • Check admin panel for visual schema exploration
  • Use POST /query endpoint for complex filters
  • Include Content-Type header on POST/PATCH
  • Test endpoints with curl before implementing

DON'T:

  • Forget /api/ prefix on API paths
  • Mix up entity names (case matters)
  • Use GET for complex queries with nested operators
  • Assume entity names - verify they exist first
  • Forget auth strategy in login path (/api/auth/password/login)

Related Skills

  • bknd-client-setup - Set up SDK in frontend
  • bknd-crud-read - Query data with filtering
  • bknd-custom-endpoint - Create custom API endpoints
  • bknd-login-flow - Implement authentication
  • bknd-local-setup - Set up local development

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results