Satellites
Satellites are project-level JSON-RPC integrations that are owned and configured by the project team. They are useful when a project needs to connect Protokol workflows to a custom service without publishing an integration to the marketplace.
Satellites are not marketplace integrations. They are only visible in the Developer section of the project where they are created, and they are only available to users in that project.
How Satellites Work
A satellite has two parts:
| Part | Purpose |
|---|---|
| Template | Operational metadata: ID, label, JSON-RPC endpoint URL, optional health check URL, optional logs URL, auth type, and timeout. |
| Schema version | Versioned capabilities: permissions, JSON-RPC commands, and workflow nodes. |
The template stores the active schema versions for the two platform environments:
| Environment | Template field |
|---|---|
| Development | dev_version |
| Live | live_version |
Deploying a schema version stores that schema's schema_version string in one of those fields. Rolling back is the same operation: deploy an older schema_version to dev or live.
When Protokol calls the satellite, it sends the active environment in the X-Env header. The satellite can use that header to route to development or live behavior on its side.
Transport
Satellites use JSON-RPC over HTTP. A satellite exposes one JSON-RPC endpoint, and Protokol proxies command execution to that endpoint.
The public platform command endpoint is:
The SDK exposes this through Satellites.execute().
The satellite implementor does not need to create separate HTTP endpoints for every command. The schema maps platform command names to JSON-RPC methods.
Authentication
Satellites support:
| Auth type | Behavior |
|---|---|
bearer |
Protokol injects Authorization: Bearer <secret> when calling the satellite. |
api_key |
Protokol injects the configured custom header name with the configured secret. |
Secrets are provided by the user, encrypted at rest, decrypted at runtime, and injected only when requests are sent to the satellite.
For api_key, auth_config.header_name is required.
Platform Headers
When Protokol calls a satellite, it resolves platform auth and authorization first, then forwards execution context through headers.
Common headers include:
| Header | Purpose |
|---|---|
X-Env |
Current platform environment: dev or live. |
X-Claims-Entity-Type |
Claim entity type, for example user or service, when available. |
X-Claims-Entity-Id |
Stable authenticated actor id. Satellites should use this when they need the current user/service id. |
X-Claims-Entity-Name |
Claim entity display name when available. |
X-Claims-Entity-Prn |
PRN pointer for the authenticated caller when available. |
X-Session |
Temporary compatibility header that mirrors the caller PRN for satellite runtimes that already read session context. |
X-Request-UUID |
Request correlation ID. |
The exact command input is sent as JSON-RPC params by the platform runtime. The same caller PRN is also included in JSON-RPC context as caller_prn, and split claim entity fields are included under claims_entity when available.
Permissions
The schema can export permissions. Exported permissions are made available in the platform RBAC system and can be assigned to roles.
Permission keys are generated by Protokol:
For example:
Commands are protected by permissions. Each command can define a permission_action; if omitted, the command name is used as the action.
If a permission is removed from a later schema version and it is still assigned to a role, background cleanup can remove stale assignments later. Runtime checks only allow commands whose required permission currently exists and is assigned.
Health Checks
A template can define health_check_url. The consolidation service checks satellite health every 60 seconds.
Health status is shown in the Developer UI. There are no platform rate limits for these checks because the satellite is an external project-owned service.
Logs
A template can define logs_url. The Developer UI can load logs from the satellite through Protokol.
When Protokol requests logs, it sends the since query parameter:
Satellite implementors should return logs since that timestamp. JSON responses are passed through. Plain text responses are wrapped by Protokol.
Resource Resolver
Satellites can resolve project resources through the existing platform Resource Resolver flow.
The PRN format is standardized:
Users still call the normal Resource Resolver endpoint. Protokol recognizes the external satellite integration PRN, resolves the satellite and active schema internally, then proxies the resolver call to the satellite JSON-RPC command named resolve_resource.
resolve_resource is a reserved convention. Satellite schemas should expose a jsonrpc_commands entry with name: "resolve_resource" when they support resource resolution; schemas do not configure a separate resolver command.
Workflow Nodes
Satellites can expose workflow operation nodes through workflownodes.
In v1:
- satellites can provide workflow nodes
- satellites cannot provide workflow events
- satellites cannot provide render events
- satellites do not use onboarding schema
- satellites do not use settings schema
Each workflow node maps to a satellite command. When the workflow executes that node, Protokol calls:
Template Example
{
"id": "crm-satellite",
"label": { "en_US": "CRM Satellite" },
"description": { "en_US": "Project-owned JSON-RPC satellite for CRM workflows." },
"icon": "satellite",
"jsonrpc_endpoint_url": "http://host.docker.internal:8787/jsonrpc",
"health_check_url": "http://host.docker.internal:8787/health",
"logs_url": "http://host.docker.internal:8787/logs",
"auth_type": "bearer",
"auth_config": {
"secret": "dev-secret"
},
"timeout_ms": 30000
}
For API key authentication:
Schema Example
{
"schema_version": "2026-06-22.crm.v1",
"schema": {
"name": "crm-satellite",
"description": "CRM satellite schema for JSON-RPC command, resource resolver, and workflow node execution."
},
"permissions": [
{
"action": "execute",
"label": { "en_US": "Execute CRM satellite commands" },
"description": { "en_US": "Allows running JSON-RPC commands exposed by the CRM satellite." }
},
{
"action": "read_resource",
"label": { "en_US": "Resolve CRM satellite resources" },
"description": { "en_US": "Allows resolving PRNs owned by the CRM satellite." }
}
],
"jsonrpc_commands": [
{ "name": "echo", "method": "echo", "permission_action": "execute" },
{ "name": "add", "method": "math.add", "permission_action": "execute" },
{ "name": "uppercase", "method": "workflow.uppercase", "permission_action": "execute" },
{ "name": "resolve_resource", "method": "resource.resolve", "permission_action": "read_resource" }
],
"workflownodes": [
{
"name": "satellite.crm.uppercase",
"label": { "en_US": "Uppercase Text" },
"description": { "en_US": "Converts input text to uppercase using the CRM satellite." },
"icon": "satellite",
"command": "uppercase",
"inputs": [
{
"name": "text",
"type": "string",
"required": true,
"label": { "en_US": "Text" },
"description": { "en_US": "Text to transform." }
}
],
"outputs": [
{ "name": "text", "type": "string" },
{ "name": "uppercase", "type": "string" },
{ "name": "length", "type": "number" }
]
}
]
}
Schema Fields
| Field | Required | Description |
|---|---|---|
schema_version |
Yes | Human-readable schema version label. |
schema |
No | Metadata for the satellite schema. This is not onboarding or settings schema. |
permissions |
No | Permission actions exported into platform RBAC. |
jsonrpc_commands |
Yes | Commands the platform can execute through JSON-RPC. |
workflownodes |
No | Workflow operation nodes exposed in the workflow canvas. |
jsonrpc_commands
| Field | Required | Description |
|---|---|---|
name |
Yes | Stable platform command name. Used in /commands/{command}/execute. |
method |
Yes | JSON-RPC method sent to the satellite endpoint. |
permission_action |
No | Permission action required to execute the command. Defaults to name. |
workflownodes
| Field | Required | Description |
|---|---|---|
name |
Yes | Stable internal workflow node identifier. |
label |
Yes | User-facing label in the workflow canvas. |
description |
No | User-facing description in the workflow node palette. |
icon |
No | Node icon. Use satellite for the built-in antenna icon. |
command |
Yes | Satellite command executed by this node. |
inputs |
No | Input fields rendered in the workflow node configuration. |
outputs |
No | Output fields available to downstream workflow nodes. |
SDK Example
import { Satellites } from '@ptkl/sdk/beta';
const satellites = new Satellites({
host: 'https://lemon.protokol.io/luma/integrations',
token: process.env.PROJECT_API_TOKEN,
env: 'dev',
});
const created = await satellites.create({
template: {
id: 'crm-satellite',
label: { en_US: 'CRM Satellite' },
jsonrpc_endpoint_url: 'http://host.docker.internal:8787/jsonrpc',
auth_type: 'bearer',
auth_config: { secret: 'dev-secret' },
},
schema: {
schema_version: '2026-06-22.crm.v1',
jsonrpc_commands: [
{ name: 'echo', method: 'echo', permission_action: 'execute' },
],
},
});
await satellites.deploy(created.id, {
env: 'dev',
schema_version: '2026-06-22.crm.v1',
});
const response = await satellites.execute(created.id, 'echo', {
inputs: { message: 'hello' },
context: { source: 'docs' },
});