Initialize
Use this guide when your application initializes plugins through a language
SDK. It covers validation, activation, reports, and shutdown through the shared
plugin-host API in Rust, Python, Node.js, Go, and C.
Use Configure
for the full plugins.toml format and merge rules. Use a component guide for
component-specific settings. Use Manage
for discoverable-plugin installation and lifecycle commands in the CLI.
Choose a Configuration Path
Initialize, Validate, or Validate Exactly
All bindings use the same three operations. They accept a canonical plugin
document. The document has a version, components, and optional policy.
Component configuration keys use snake_case in every binding.
path is optional. In Rust it is an Option<PathBuf>. In Python it can be a
string or path-like value. Node.js uses an optional string, Go uses an optional
string pointer, and C accepts a nullable C string.
Know Which Configuration Relay Uses
Relay merges file layers first, then applies the configuration passed by your application. Programmatic values therefore take precedence over file values.
An explicit path replaces user-file discovery; it does not remove the system file. A missing file is skipped. The system file can still add settings that the application does not declare.
The application configuration can define static components. Dynamic plugin
records, such as [[plugins.dynamic]], come from plugins.toml. Use the
optional path when an embedded host needs a specific dynamic-plugin file.
For details such as list order, component matching, disabled components, and how omitted values behave, see Configure.
Initialize Through a Language SDK
The following examples validate before activation. They use an empty document to show the host lifecycle. Replace it with component settings from the guide for the plugin you want to use.
Python
Node.js
Rust
Read the Report
validate returns a PluginHostReport. A successful initialize stores the
same kind of report on its activation handle. Check the report before starting
application work.
A diagnostic has a level, code, and message. It also names the component and field when Relay knows them.
For every lifecycle-selected dynamic plugin, validate returns a report even
when integrity or signature verification fails. Trust failures do not make
validate raise; inspect status.integrity, status.authenticity, and
failure, then fail the deployment if the report is not acceptable. A failed
trust report has selected = false because Relay will not activate that
plugin. With startup = "required", initialize still rejects the same
failure before it loads plugin code.
validate is a preflight. It proves that Relay can resolve and check the
configuration without starting plugin code. It does not prove that a remote
exporter can deliver data after activation. Use component health checks and
runtime diagnostics for that work.
Keep the Activation Handle Alive
initialize returns a PluginHostActivation. Keep it alive while any plugin
callback can run. Only one plugin-host activation can exist in a process at a
time.
Close the handle during normal shutdown. Closing removes component-owned
registrations before Relay unloads native libraries or stops worker processes.
If close fails, keep the handle and retry close; do not deregister a custom
plugin kind while its activation is still active.
Use a guaranteed cleanup path. Node.js flushes queued subscribers before it closes the activation. Python and Rust close the activation after application work finishes.
Python
Node.js
Rust
Common Use Cases
Preflight a Deployment
Call validate with the same configuration and optional file path that
production will use. Fail the deployment on error diagnostics or a dynamic
plugin failure. This checks configuration, manifest compatibility, and trust
policy before the application starts plugin code.
Configure a Service in Code
Build a PluginConfig for application-owned settings. Call initialize once
during startup, retain the activation handle, and close it during graceful
shutdown. This works well when the service owns its plugin choices.
Use a Provisioned Plugin File
Store shared plugin settings and dynamic-plugin records in plugins.toml.
Pass the file path to validate and initialize when the host must use that
selected file instead of a discovered user file. This is useful for a service that receives configuration from its
deployment system.
Embedded Python Host Initialization
Python hosts pass an optional explicit plugins.toml directly to the unified
host initializer:
Core resolves manifest references relative to the declaring file, applies
lifecycle state and trust policy, validates all selected plugins before loading
code, and owns every resulting runtime through the returned activation handle.
Use plugin.activate(...) when the host lifetime fits one async with block.
Use await plugin.initialize(...) when the caller needs to retain and close the
activation manually.
Validate One Component in Isolation
Use exact validation when the supplied document is complete and file discovery would hide a mistake. This is useful for unit tests and component-specific configuration helpers. Exact validation does not test manifest-backed plugins.
For a complete configuration document, see Configure. For manifest-backed plugins, see Manage.