Documentation Index Fetch the complete documentation index at: https://mintlify.com/iii-hq/sdk/llms.txt
Use this file to discover all available pages before exploring further.
Triggers automatically invoke functions when specific events occur, such as HTTP requests, scheduled times, or custom events.
registerTrigger()
Register a trigger to invoke a function when an event occurs.
const trigger = iii . registerTrigger ( config )
config
RegisterTriggerInput
required
Trigger configuration Show RegisterTriggerInput properties
Trigger type (e.g., 'http', 'cron', 'functions_available')
ID of the function to invoke
Type-specific trigger configuration
Trigger reference with unregister method Function to unregister this trigger
HTTP Triggers
Expose functions as HTTP endpoints.
Basic HTTP Endpoint
import { init , type HttpRequest , type ApiResponse } from 'iii-sdk'
const iii = init ( 'ws://localhost:49199' )
// Register function
iii . registerFunction (
{ id: 'api::hello' },
async ( req : HttpRequest ) : Promise < ApiResponse > => {
return {
status_code: 200 ,
body: { message: 'Hello, World!' }
}
}
)
// Register HTTP trigger
const trigger = iii . registerTrigger ({
type: 'http' ,
function_id: 'api::hello' ,
config: {
api_path: 'hello' ,
http_method: 'GET'
}
})
Endpoint available at: http://localhost:3199/hello
HTTP Request Types
HTTP request object passed to function handlers Show HttpRequest properties
Path parameters extracted from route (e.g., :id)
query_params
Record<string, string | string[]>
Query string parameters
Parsed request body (JSON for application/json)
HTTP method (GET, POST, etc.)
Streaming request body reader
JSON response format Show ApiResponse properties
HTTP status code (e.g., 200, 404, 500)
body
string | Buffer | Record<string, unknown>
Response body (automatically JSON-stringified for objects)
Path Parameters
iii . registerFunction (
{ id: 'api::get_user' },
async ( req : HttpRequest ) : Promise < ApiResponse > => {
const userId = req . path_params . id
return {
status_code: 200 ,
body: { id: userId , name: 'John Doe' }
}
}
)
iii . registerTrigger ({
type: 'http' ,
function_id: 'api::get_user' ,
config: {
api_path: 'users/:id' ,
http_method: 'GET'
}
})
// GET /users/123 → { id: "123", name: "John Doe" }
Query Parameters
iii . registerFunction (
{ id: 'api::search' },
async ( req : HttpRequest ) : Promise < ApiResponse > => {
const query = req . query_params . q as string
const limit = parseInt ( req . query_params . limit as string || '10' )
return {
status_code: 200 ,
body: { query , limit , results: [] }
}
}
)
iii . registerTrigger ({
type: 'http' ,
function_id: 'api::search' ,
config: {
api_path: 'search' ,
http_method: 'GET'
}
})
// GET /search?q=hello&limit=20
Request Body
iii . registerFunction (
{ id: 'api::create_post' },
async ( req : HttpRequest ) : Promise < ApiResponse > => {
const body = req . body as { title : string ; content : string }
const post = {
id: crypto . randomUUID (),
title: body . title ,
content: body . content ,
created_at: new Date (). toISOString ()
}
return {
status_code: 201 ,
body: post
}
}
)
iii . registerTrigger ({
type: 'http' ,
function_id: 'api::create_post' ,
config: {
api_path: 'posts' ,
http_method: 'POST'
}
})
Streaming HTTP Responses
For streaming responses (SSE, file downloads, etc.), use the http() helper:
import { init , http , type HttpRequest , type HttpResponse } from 'iii-sdk'
import * as fs from 'node:fs'
import { pipeline } from 'node:stream/promises'
const iii = init ( 'ws://localhost:49199' )
// File download
iii . registerFunction (
{ id: 'api::download' },
http ( async ( req : HttpRequest , response : HttpResponse ) => {
const fileStream = fs . createReadStream ( './report.pdf' )
response . status ( 200 )
response . headers ({
'Content-Type' : 'application/pdf' ,
'Content-Disposition' : 'attachment; filename="report.pdf"'
})
await pipeline ( fileStream , response . stream )
})
)
iii . registerTrigger ({
type: 'http' ,
function_id: 'api::download' ,
config: {
api_path: 'download/report' ,
http_method: 'GET'
}
})
Server-Sent Events (SSE)
iii . registerFunction (
{ id: 'api::events' },
http ( async ( req : HttpRequest , response : HttpResponse ) => {
response . status ( 200 )
response . headers ({
'Content-Type' : 'text/event-stream' ,
'Cache-Control' : 'no-cache' ,
'Connection' : 'keep-alive'
})
// Send events
for ( let i = 0 ; i < 10 ; i ++ ) {
const event = `data: ${ JSON . stringify ({ count: i }) } \n\n `
response . stream . write ( Buffer . from ( event ))
await new Promise ( resolve => setTimeout ( resolve , 1000 ))
}
response . stream . end ()
})
)
iii . registerTrigger ({
type: 'http' ,
function_id: 'api::events' ,
config: {
api_path: 'events' ,
http_method: 'GET'
}
})
Streaming Request Body
iii . registerFunction (
{ id: 'api::upload' },
http ( async ( req : HttpRequest , response : HttpResponse ) => {
const chunks : Buffer [] = []
// Read streaming request body
for await ( const chunk of req . request_body . stream ) {
chunks . push ( Buffer . isBuffer ( chunk ) ? chunk : Buffer . from ( chunk ))
}
const totalSize = chunks . reduce (( sum , buf ) => sum + buf . length , 0 )
response . status ( 200 )
response . headers ({ 'Content-Type' : 'application/json' })
response . stream . end (
Buffer . from ( JSON . stringify ({ uploaded_bytes: totalSize }))
)
})
)
iii . registerTrigger ({
type: 'http' ,
function_id: 'api::upload' ,
config: {
api_path: 'upload' ,
http_method: 'POST'
}
})
Custom Trigger Types
Create custom trigger types for your own event sources.
registerTriggerType()
iii . registerTriggerType < TConfig >( triggerType , handler )
triggerType
RegisterTriggerTypeMessage
required
Trigger type definition Human-readable description
handler
TriggerHandler<TConfig>
required
Handler for registering/unregistering triggers interface TriggerHandler < TConfig > {
registerTrigger ( config : {
id : string
function_id : string
config : TConfig
}) : Promise < void >
unregisterTrigger ( config : {
id : string
function_id : string
config : TConfig
}) : Promise < void >
}
Example: Custom Webhook Trigger
interface WebhookConfig {
url : string
secret : string
}
const webhooks = new Map < string , WebhookConfig >()
iii . registerTriggerType < WebhookConfig >(
{
id: 'webhook' ,
description: 'Trigger function via webhook'
},
{
async registerTrigger ({ id , function_id , config }) {
webhooks . set ( id , config )
// Subscribe to webhook service
await fetch ( config . url , {
method: 'POST' ,
headers: { 'X-Secret' : config . secret },
body: JSON . stringify ({
action: 'subscribe' ,
callback: `http://engine:3199/webhooks/ ${ id } `
})
})
},
async unregisterTrigger ({ id , config }) {
const webhook = webhooks . get ( id )
if ( webhook ) {
// Unsubscribe from webhook service
await fetch ( config . url , {
method: 'POST' ,
headers: { 'X-Secret' : config . secret },
body: JSON . stringify ({ action: 'unsubscribe' })
})
webhooks . delete ( id )
}
}
}
)
// Use the custom trigger type
iii . registerTrigger ({
type: 'webhook' ,
function_id: 'handlers::webhook' ,
config: {
url: 'https://webhook-service.com/subscribe' ,
secret: process . env . WEBHOOK_SECRET !
}
})
unregisterTriggerType()
Remove a custom trigger type:
iii . unregisterTriggerType ({
id: 'webhook' ,
description: 'Webhook trigger'
})
Engine Built-in Triggers
The III Engine provides built-in trigger types:
functions_available
Triggers when new functions are registered or unregistered.
iii . onFunctionsAvailable (( functions ) => {
console . log ( 'Functions updated:' , functions . length )
functions . forEach ( fn => {
console . log ( `- ${ fn . function_id } ` )
})
})
See onFunctionsAvailable for details.
Best Practices
Use descriptive API paths
// Good
api_path : 'users/:id/orders'
api_path : 'products/search'
// Avoid
api_path : 'u/:id/o'
api_path : 'psearch'
Return appropriate status codes
// 200 OK - Successful GET/PUT/PATCH
// 201 Created - Successful POST
// 204 No Content - Successful DELETE
// 400 Bad Request - Invalid input
// 404 Not Found - Resource not found
// 500 Internal Server Error - Server error
return {
status_code: 404 ,
body: { error: 'User not found' }
}
Clean up triggers on shutdown
const triggers : Trigger [] = []
triggers . push ( iii . registerTrigger ({ /* ... */ }))
process . on ( 'SIGTERM' , () => {
triggers . forEach ( t => t . unregister ())
})