worker.register_trigger({ "type": "http", "function_id": "math::add", "config": {"api_path": "/math/add", "http_method": "POST"}, }) ``` </Tab> <Tab title="Rust"> ```rust use iii_sdk::RegisterTriggerInput; use serde_json::json; // http worker not started worker.register_trigger(RegisterTriggerInput { trigger_type: "http".into(), function_id: "math::add".into(), config: json!({ "api_path": "/math/add", "http_method": "POST" }), metadata: None, })?; ``` </Tab> </Tabs> Start the http worker afte...
Scanned 9/3/2026
Install to Claude Code
npx -y skills add iii-hq/iii --skill using-iii --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Using Iii?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/iii-hq-using-iii-e805dea0)More formats (shields.io, HTML) on the badges page.
<!-- generated by iii-skill-render. DO NOT EDIT (changes here are overwritten on the next render). Edit docs/next/using-iii/triggers.mdx. -->
{/* TODO: Re-link worker references to https://workers.iii.dev/workers/<name> once the Worker Docs migration ships. */}
<Note>
Calling a function directly with `worker.trigger` or `iii trigger` are documented in [Using iii /
Functions](./functions#triggering-invoking-functions). This page covers specifics about Triggers
such as registering (binding) Triggers to Functions, gating triggers, and unregistering them.
</Note>
## Register a trigger
<Note>
If you're authoring a worker, you'll want to refer to [Creating Workers /
Triggers](../creating-workers/triggers#bind-a-function-to-an-existing-trigger-type) to learn the
difference between registering a trigger, and registering a trigger type.
</Note>
Functions can also run when a trigger is satisfied. A trigger can be any event that happens such as
a request to an `http` endpoint, a `cron` job, a change in `state`, or any other trigger that a
worker supports. You can also [write your own](../creating-workers/triggers).
You bind triggers to functions via the `function_id`. The trigger declares its `type`, its `config`
(defined by each type), and the function to invoke.
<Tabs>
<Tab title="Node / TypeScript">
```typescript
import { registerWorker } from "iii-sdk";
const url = process.env.III_URL;
if (!url) throw new Error("III_URL must be set");
const worker = registerWorker(url);
worker.registerTrigger({
type: "http",
function_id: "math::add",
config: { api_path: "/math/add", http_method: "POST" },
});
```
</Tab>
<Tab title="Python">
```python
import os
from iii import register_worker, InitOptions
worker = register_worker(
os.environ.get("III_URL"),
InitOptions(worker_name="my-worker"),
)
worker.register_trigger({
"type": "http",
"function_id": "math::add",
"config": {"api_path": "/math/add", "http_method": "POST"},
})
```
</Tab>
<Tab title="Rust">
```rust
use iii_sdk::{InitOptions, RegisterTriggerInput, register_worker};
use serde_json::json;
let url = std::env::var("III_URL").expect("III_URL must be set");
let worker = register_worker(&url, InitOptions::default());
worker.register_trigger(RegisterTriggerInput {
trigger_type: "http".into(),
function_id: "math::add".into(),
config: json!({ "api_path": "/math/add", "http_method": "POST" }),
metadata: None,
})?;
```
</Tab>
</Tabs>
Per-type configuration is documented in each worker's Worker Docs (e.g.
[http](https://workers.iii.dev/workers/http) for the `http` type).
### Trigger metadata
The optional `metadata` field on a trigger registration (`null` / `None` in the examples above) is
arbitrary JSON stored with the trigger and delivered to the receiving function as a distinct
argument alongside the payload. It is useful for providing contextual information about the trigger
or execution context to the receiving function.
A target function shared by many triggers can use it to recover which registration fired and with
what context. See
[Receive per-invocation metadata](../creating-workers/functions#receive-per-invocation-metadata) for
handler-side access in each SDK.
<Note>
`metadata` can be provided both via `registerTrigger` and direct `trigger()` invocations
</Note>
## Registering before a trigger type is available
Registration is order-independent. If you register a trigger whose type is not active in the project
yet (for example, the worker that publishes `http` has not connected), the engine stores the
registration optimistically and activates it automatically once that trigger type becomes available.
The engine logs a pending notice while a registration waits, and re-establishes stored registrations
when a publishing worker restarts, so a worker that comes up after its consumers receives trigger
registrations as expected.
Bind `math::add` to the `http` type before the http worker is running. The engine accepts the
registration and stores it:
<Tabs>
<Tab title="Node / TypeScript">
```typescript
// http worker not started
worker.registerTrigger({
type: "http",
function_id: "math::add",
config: { api_path: "/math/add", http_method: "POST" },
});
```
</Tab>
<Tab title="Python">
```python
# http worker not started
worker.register_trigger({
"type": "http",
"function_id": "math::add",
"config": {"api_path": "/math/add", "http_method": "POST"},
})
```
</Tab>
<Tab title="Rust">
```rust
use iii_sdk::RegisterTriggerInput;
use serde_json::json;
// http worker not started
worker.register_trigger(RegisterTriggerInput {
trigger_type: "http".into(),
function_id: "math::add".into(),
config: json!({ "api_path": "/math/add", "http_method": "POST" }),
metadata: None,
})?;
```
</Tab>
</Tabs>
Start the http worker afterward. The engine activates the stored binding automatically, and the
endpoint serves requests without re-registering:
```bash
# http worker started after registration
iii worker add http
# the stored binding is now live on the http worker's default port (3111)
curl -X POST http://localhost:3111/math/add \
-H 'Content-Type: application/json' \
-d '{"a": 2, "b": 3}'
# 200 OK: the request reaches math::add through the activated trigger
```
For known trigger types (ex. `http`, `state`, `durable:subscriber`, `stream`), the pending notice
includes the install command for the worker that provides the type. For other types, find the worker
that exposes the needed type at [workers.iii.dev](https://workers.iii.dev).
A registration fails when an active provider rejects the config it was given (for example, an
invalid trigger config). The engine then sends a `TriggerRegistrationResult` with an `error` body
back to the worker that initiated the request and logs it.
## Bind multiple triggers to one function
It's valid to bind multiple triggers to the same `function_id` and this can be done across any
number of types. Register a second trigger with the same `function_id` and a different type or
config; the function runs unchanged whether the call arrives over HTTP, on a cron schedule, or from
a queue message.
<Tabs>
<Tab title="Node / TypeScript">
```typescript
// Same handler runs for an HTTP POST and a weekly cron tick.
worker.registerTrigger({
type: "http",
function_id: "reports::generate",
config: { api_path: "/reports/generate", http_method: "POST" },
});
worker.registerTrigger({
type: "cron",
function_id: "reports::generate",
config: { expression: "0 0 9 * * 1" }, // Every Monday at 09:00
});
```
</Tab>
<Tab title="Python">
```python
worker.register_trigger({
"type": "http",
"function_id": "reports::generate",
"config": {"api_path": "/reports/generate", "http_method": "POST"},
})
worker.register_trigger({
"type": "cron",
"function_id": "reports::generate",
"config": {"expression": "0 0 9 * * 1"}, # Every Monday at 09:00
})
```
</Tab>
<Tab title="Rust">
```rust
use iii_sdk::RegisterTriggerInput;
use serde_json::json;
worker.register_trigger(RegisterTriggerInput {
trigger_type: "http".into(),
function_id: "reports::generate".into(),
config: json!({ "api_path": "/reports/generate", "http_method": "POST" }),
metadata: None,
})?;
worker.register_trigger(RegisterTriggerInput {
trigger_type: "cron".into(),
function_id: "reports::generate".into(),
config: json!({ "expression": "0 0 9 * * 1" }), // Every Monday at 09:00
metadata: None,
})?;
```
</Tab>
</Tabs>
## Gate a trigger with a condition
A trigger can carry an optional `condition_function_id` (set inside the trigger's `config`). When
the trigger fires, the engine invokes the condition function first with the same payload the handler
would receive; the target `function_id` only runs when the condition returns truthy. The condition
is a regular registered function.
<Tabs>
<Tab title="Node / TypeScript">
```typescript
worker.registerFunction(
"orders::is-priority",
async (payload: { customer_tier: string }) => payload.customer_tier === "gold",
);
worker.registerTrigger({
type: "http",
function_id: "orders::expedite",
config: {
api_path: "/orders/expedite",
http_method: "POST",
condition_function_id: "orders::is-priority",
},
});
```
</Tab>
<Tab title="Python">
```python
def is_priority(payload: dict) -> bool:
return payload.get("customer_tier") == "gold"
worker.register_function("orders::is-priority", is_priority)
worker.register_trigger({
"type": "http",
"function_id": "orders::expedite",
"config": {
"api_path": "/orders/expedite",
"http_method": "POST",
"condition_function_id": "orders::is-priority",
},
})
```
</Tab>
<Tab title="Rust">
```rust
use iii_sdk::{RegisterFunction, RegisterTriggerInput};
use schemars::JsonSchema;
use serde::Deserialize;
use serde_json::json;
#[derive(Deserialize, JsonSchema)]
struct Payload { customer_tier: String }
worker.register_function(RegisterFunction::new(
"orders::is-priority",
|input: Payload| -> Result<bool, String> {
Ok(input.customer_tier == "gold")
},
));
worker.register_trigger(RegisterTriggerInput {
trigger_type: "http".into(),
function_id: "orders::expedite".into(),
config: json!({
"api_path": "/orders/expedite",
"http_method": "POST",
"condition_function_id": "orders::is-priority",
}),
metadata: None,
})?;
```
</Tab>
</Tabs>
## Unregister a trigger
Trigger registration returns a handle with an `unregister()` method. Call it to drop the trigger at
runtime; when the worker disconnects, all of its triggers are removed automatically.
<Tabs>
<Tab title="Node / TypeScript">
```typescript
const trigger = worker.registerTrigger({
type: "http",
function_id: "math::add",
config: { api_path: "/math/add", http_method: "POST" },
});
trigger.unregister();
```
</Tab>
<Tab title="Python">
```python
trigger = worker.register_trigger({
"type": "http",
"function_id": "math::add",
"config": {"api_path": "/math/add", "http_method": "POST"},
})
trigger.unregister()
```
</Tab>
<Tab title="Rust">
```rust
use iii_sdk::RegisterTriggerInput;
use serde_json::json;
let trigger = worker.register_trigger(RegisterTriggerInput {
trigger_type: "http".into(),
function_id: "math::add".into(),
config: json!({ "api_path": "/math/add", "http_method": "POST" }),
metadata: None,
})?;
trigger.unregister();
```
</Tab>
</Tabs>
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!