Interacting with Nile
Nile exposes a single HTTP endpoint for all interactions. All requests are POST requests with a JSON body that specifies the intent, service, action, and payload.
The Nile Client (Recommended)
While you can interact with Nile using raw HTTP requests, we recommend using the @nilejs/client package for a better developer experience, type-safety, and graceful error handling.
import { createNileClient } from "@nilejs/client";
import type { ServicePayloads } from "./generated/types";
const nile = createNileClient<ServicePayloads>({ baseUrl: "/api" });
const { error, data } = await nile.invoke({
service: "tasks",
action: "create",
payload: { title: "Buy milk" }
});
See the Client guide for the full API reference.
The Single Endpoint
The default base URL is /api, so the full endpoint is typically:
Every request follows this structure:
{
"intent": "explore" | "execute" | "schema",
"service": "serviceName",
"action": "actionName",
"payload": { ... }
}
Intents
1. Execute (intent: "execute")
Execute an action. This is the most common intent for running your business logic. In the Nile Client, this is called via nile.invoke().
curl -X POST http://localhost:8000/api/services \
-H "Content-Type: application/json" \
-d '{
"intent": "execute",
"service": "tasks",
"action": "create",
"payload": { "title": "Buy milk", "status": "pending" }
}'
Response:
{
"status": true,
"message": "Action 'tasks.create' executed",
"data": {
"task": {
"id": "abc-123",
"title": "Buy milk",
"status": "pending"
}
}
}
2. Explore (intent: "explore")
Discover available services and actions. Use wildcards to explore.
List all services:
curl -X POST http://localhost:8000/api/services \
-H "Content-Type: application/json" \
-d '{
"intent": "explore",
"service": "*",
"action": "*",
"payload": {}
}'
Response:
{
"status": true,
"message": "Available services",
"data": [
{
"name": "tasks",
"description": "Task management operations",
"meta": { "version": "1.0.0" },
"actions": ["create", "list", "get", "update", "delete"]
},
{
"name": "auth",
"description": "Authentication service",
"actions": ["login", "logout", "register"]
}
]
}
List all actions in a service:
curl -X POST http://localhost:8000/api/services \
-H "Content-Type: application/json" \
-d '{
"intent": "explore",
"service": "tasks",
"action": "*",
"payload": {}
}'
Response:
{
"status": true,
"message": "Actions for 'tasks'",
"data": [
{
"name": "create",
"description": "Create a new task",
"isProtected": false,
"validation": true,
"accessControl": []
},
{
"name": "list",
"description": "List all tasks",
"isProtected": false,
"validation": false,
"accessControl": []
},
{
"name": "get",
"description": "Get a task by ID",
"isProtected": true,
"validation": true,
"accessControl": []
}
]
}
Get details of a specific action:
curl -X POST http://localhost:8000/api/services \
-H "Content-Type: application/json" \
-d '{
"intent": "explore",
"service": "tasks",
"action": "create",
"payload": {}
}'
Response:
{
"status": true,
"message": "Details for 'tasks.create'",
"data": {
"name": "create",
"description": "Create a new task",
"isProtected": false,
"accessControl": null,
"hooks": {
"before": [],
"after": []
},
"meta": null
}
}
3. Schema (intent: "schema")
Get the Zod validation schemas as JSON Schema. Useful for generating type-safe clients.
Get all schemas:
curl -X POST http://localhost:8000/api/services \
-H "Content-Type: application/json" \
-d '{
"intent": "schema",
"service": "*",
"action": "*",
"payload": {}
}'
Response:
{
"status": true,
"message": "All service schemas",
"data": {
"tasks": {
"create": {
"type": "object",
"properties": {
"title": { "type": "string", "minLength": 1 },
"status": { "type": "string", "enum": ["pending", "in-progress", "done"] }
},
"required": ["title"]
},
"list": null,
"get": {
"type": "object",
"properties": {
"id": { "type": "string" }
},
"required": ["id"]
}
},
"auth": {
"login": {
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"password": { "type": "string" }
},
"required": ["email", "password"]
}
}
}
}
Get schemas for a specific service:
curl -X POST http://localhost:8000/api/services \
-H "Content-Type: application/json" \
-d '{
"intent": "schema",
"service": "tasks",
"action": "*",
"payload": {}
}'
Response:
{
"status": true,
"message": "Schemas for 'tasks'",
"data": {
"create": {
"type": "object",
"properties": {
"title": { "type": "string", "minLength": 1 },
"status": { "type": "string", "enum": ["pending", "in-progress", "done"] }
},
"required": ["title"]
},
"list": null,
"get": {
"type": "object",
"properties": {
"id": { "type": "string" }
},
"required": ["id"]
}
}
}
Get schema for a specific action:
curl -X POST http://localhost:8000/api/services \
-H "Content-Type: application/json" \
-d '{
"intent": "schema",
"service": "tasks",
"action": "create",
"payload": {}
}'
Response:
{
"status": true,
"message": "Schema for 'tasks.create'",
"data": {
"create": {
"type": "object",
"properties": {
"title": { "type": "string", "minLength": 1 },
"status": { "type": "string", "enum": ["pending", "in-progress", "done"] }
},
"required": ["title"]
}
}
}
All responses follow a consistent structure:
{
status: boolean; // true for success, false for error
message: string; // human-readable message
data: { // the actual response data
error_id?: string; // present on errors
[key: string]: any;
}
}
Success response:
{
"status": true,
"message": "Action executed successfully",
"data": { ... }
}
Error response:
{
"status": false,
"message": "Validation failed: Title is required",
"data": {}
}
Error Handling
Nile uses a Result pattern internally. All errors are returned in the response without throwing HTTP exceptions:
Health Check
If enabled in config, you can check server health:
{
"status": true,
"message": "my-app is running",
"data": {}
}