Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.devhelm.io/llms.txt

Use this file to discover all available pages before exploring further.

The devhelm Python package is a typed, synchronous client for the DevHelm REST API. It’s built on httpx, ships full Pydantic models for every request and response, and has full mypy strict-mode type coverage.
The Python SDK is synchronous. There’s no AsyncDevhelm client in v0.4.0 — for concurrent usage, run the sync client in a thread pool (see async usage).

Install

pip install devhelm
Requires Python 3.11 or later.

Initialize

import os
from devhelm import Devhelm

client = Devhelm(token=os.environ["DEVHELM_API_TOKEN"])
Constructor parameterTypeDefaultDescription
tokenstr""API token. Required for all calls except hosted MCP.
base_urlstrhttps://api.devhelm.ioAPI base URL — override for self-hosted.
org_idstr | NoneNoneSets x-phelm-org-id header. Required when your token grants access to multiple orgs.
workspace_idstr | NoneNoneSets x-phelm-workspace-id header. Required when the org has multiple workspaces.
timeoutfloat30.0Per-request timeout in seconds.

Create a monitor

The SDK accepts request bodies as plain dicts (validated against the Pydantic request model) or as Pydantic instances. Both produce the same MonitorDto response:
monitor = client.monitors.create({
    "name": "API Health",
    "type": "HTTP",
    "config": {"url": "https://api.example.com/health", "method": "GET"},
    "frequencySeconds": 60,
    "regions": ["us-east", "eu-west"],
})

print(f"Created monitor: {monitor.id}")
managedBy is optional — omit it (defaults to API server-side) or set it explicitly to one of API, DASHBOARD, CLI, TERRAFORM, or MCP to record the provenance for drift detection. Or using the typed request class:
from devhelm import CreateMonitorRequest

monitor = client.monitors.create(
    CreateMonitorRequest(
        name="API Health",
        type="HTTP",
        config={"url": "https://api.example.com/health", "method": "GET"},
        frequencySeconds=60,
    )
)

List monitors

monitors = client.monitors.list()  # auto-paginates through every page

for monitor in monitors:
    print(f"{monitor.name}: {monitor.current_status}")
For manual pagination control:
page = client.monitors.list_page(page=0, size=50)
print(f"Total: {page.total_elements}")
for monitor in page.data:
    ...

Get check results

results = client.monitors.results(monitor.id, limit=10)

for check in results.data:
    status = "OK" if check.passed else "FAIL"
    print(f"{check.region}: {status} ({check.response_time_ms}ms)")
results() returns a CursorPage — call it with cursor=results.next_cursor to fetch the next batch.

Manage incidents

incidents = client.incidents.list()  # auto-paginates

for incident in incidents:
    if incident.status == "OPEN":
        print(f"Open: {incident.title}")

client.incidents.resolve(incident.id)
# or with a resolution note:
client.incidents.resolve(incident.id, {"resolutionNote": "fixed by deploy"})

Create an alert channel

channel = client.alert_channels.create({
    "name": "Slack Alerts",
    "type": "slack",
    "config": {
        "webhookUrl": os.environ["SLACK_WEBHOOK_URL"],
    },
})

Error handling

from devhelm import (
    Devhelm,
    DevhelmError,
    DevhelmAuthError,
    DevhelmNotFoundError,
    DevhelmRateLimitError,
)

try:
    client.monitors.get("nonexistent-id")
except DevhelmNotFoundError:
    print("Monitor not found")
except DevhelmRateLimitError as e:
    print(f"Rate limited — retry after {e.retry_after}s")
except DevhelmAuthError:
    print("Bad token or insufficient permissions")
except DevhelmError as e:
    print(f"{e.status}: {e}")
Full taxonomy in the Error handling guide.

Next steps

Client reference

Every resource and method available on the client.

Concurrency patterns

Run the sync client concurrently with thread pools and asyncio.