Self-hosted agents let you connect your own runtime to Leadtime. This can be an OpenClaw gateway, Hermes, a small wrapper around Claude Code, a custom worker, or any process that can receive HTTPS webhooks and call the Leadtime Public API.
Leadtime owns the bot identity, task trigger, session record, signed webhook, and task history UI. Your wrapper owns the runtime: it receives the webhook, starts the agent, reports progress, and decides which tools or API calls the model can use.
Most teams should start from an existing connector instead of building the protocol from scratch:
OpenClaw plugin: a complete Leadtime connector for OpenClaw with setup-code provisioning, webhook handling, task tools, and full API mode. View repository
Hermes plugin: the same connector pattern for Hermes Agent runtimes. View repository
Minimal wrapper example: a small TypeScript reference for custom integrations. View repository
For API details, keep these references open: Public API documentation and OpenAPI JSON.
Bot personal access tokens let your wrapper call the Public API as the bot. Use them for normal Leadtime actions: read a task, write a comment, update status, create records, or call any other endpoint allowed by the bot role and token scopes.
Agent sessions let Leadtime start work. When someone assigns or mentions the bot on a task, Leadtime creates a session, shows it in task history, and sends one signed webhook to your wrapper.
The wrapper verifies the webhook, deduplicates retries, starts the runtime, appends session activity, updates session status, and keeps raw credentials away from untrusted model logic unless you explicitly choose otherwise.
Do not use session APIs for normal task changes. Session APIs are for the session feed and status. Normal task work should use the regular Public API with the bot token.
Use manual setup when you are building your own runtime or you do not want to use an OpenClaw/Hermes setup helper.
Create or open a self-hosted bot in Workspace settings -> Bots.
Create a bot personal access token with the API scopes your wrapper needs. Store the raw token in your wrapper secret storage.
Open Agent sessions, enable them, and set your wrapper webhook URL. The URL must be reachable by Leadtime. For Leadtime Cloud this means public HTTPS.
Copy or rotate the webhook signing secret and store it next to the bot token.
Assign or mention the bot on a test task and confirm that a session card appears in task history.
Setup codes automate the same manual settings. The user generates a short-lived code in Leadtime. Your connector claims it through the Public API, and Leadtime returns the bot token, webhook secret, mode, docs URL, and guidance once. OpenClaw and Hermes use this flow so users do not have to copy secrets by hand.
When a session starts, Leadtime sends an HTTP POST to the bot webhook URL. The body is JSON. Verify the raw request body before processing it.
Header: Leadtime-Event-Id - stable id for deduplication.
Header: Leadtime-Event-Type - currently usually session.created.
Header: Leadtime-Timestamp - webhook creation time. Reject old timestamps to reduce replay risk.
Header: Leadtime-Signature - HMAC-SHA256 signature of the raw body using the bot webhook signing secret.
The payload contains the session id, workspace, bot, trigger source, task context, guidance, API base URL, docs URL, and session API paths. Treat agentRunId as the canonical session id.
For task mentions, the triggering comment is the current request. Older task comments, task description, and previous sessions are context only.
Your wrapper uses the session API to report what is happening in the run. The authenticated bot must own the session. Use the bot PAT in the Authorization: Bearer <token> header.
GET /api/public/agent-sessions/:runId/context - read full session context
POST /api/public/agent-sessions/:runId/activities - append progress, tool events, logs, final text, or errors
PATCH /api/public/agent-sessions/:runId/status - set running, done, failed, or canceled state
GET /api/public/tasks/:identifier/agent-sessions - list sessions shown on a task
GET /api/public/agent-sessions/:runId/activities - read session feed for debugging
Use idempotency keys when writing repeated activity/status updates. This keeps retries from creating duplicate feed rows.
The agent or wrapper should use the regular Public API for actual Leadtime work. Common examples are reading the current task, writing a task comment, changing task status, or updating records related to the task.
The safest pattern is to expose a small controlled tool set to the model and keep session reporting inside the wrapper. Full API mode is useful for trusted automation, but it should be a deliberate configuration choice.
Keep the bot PAT and webhook signing secret in server-side secret storage. Do not paste them into task comments or model-visible prompts unless you explicitly trust that runtime.
Verify webhook signatures against the raw body before parsing or starting work.
Deduplicate by Leadtime-Event-Id before starting a run.
Use the narrowest bot role and token scopes that still allow the required actions.
Make connector webhook URLs public only when Leadtime Cloud must call them. For private networks, use a stable HTTPS reverse proxy, Cloudflare Tunnel, Tailscale Funnel, or a similar controlled ingress.
Each assignment or mention creates a separate session card in the task history. The card shows the bot, trigger, status, timing, and latest activity. Opening it shows the full session feed your wrapper reported. Finished sessions stay in history so later users can understand what happened.