> ## 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.

# Python Client Reference

> DevHelm Python SDK client reference — all methods, types, and pagination shapes

Complete reference for the `devhelm` Python SDK (v1.3.0). Every list/get returns a Pydantic model; every body parameter accepts either a dict or the corresponding Pydantic request class.

## Client initialization

```python theme={null}
from devhelm import Devhelm

client = Devhelm(
    token="dh_live_xxxxxxxx",
    base_url="https://api.devhelm.io",
    org_id=None,
    workspace_id=None,
    timeout=30.0,
)
```

| Parameter | Type | Default | Description |
| - | - | - | - |
| `token` | `str` | `""` | API token. Falls back to the `DEVHELM_API_TOKEN` env var when empty. |
| `base_url` | `str` | `https://api.devhelm.io` | API base URL. |
| `org_id` | `str \| None` | `None` | Sets `x-phelm-org-id`. Falls back to `DEVHELM_ORG_ID` env var, then `"1"`. |
| `workspace_id` | `str \| None` | `None` | Sets `x-phelm-workspace-id`. Falls back to `DEVHELM_WORKSPACE_ID` env var, then `"1"`. |
| `timeout` | `float` | `30.0` | Per-request timeout in seconds. |

The client is built on `httpx.Client`. It is **synchronous** and **thread-safe**; share one instance across threads (see [concurrency patterns](/sdk/python/async-usage)).

## Resource namespaces

The client exposes 17 resources. List/get/delete signatures return Pydantic DTOs from `devhelm.types`; mutations accept `RequestBody[...]` (dict or model instance).

### client.monitors

| Method | Signature | Returns |
| - | - | - |
| `list(**filters)` | `(...) -> list[MonitorDto]` | Auto-fetches all pages |
| `list_page(page, size, **filters)` | `(int, int, ...) -> Page[MonitorDto]` | Single page |
| `get(id)` | `(int \| str) -> MonitorDto` | |
| `create(body)` | `(RequestBody[CreateMonitorRequest]) -> MonitorDto` | |
| `update(id, body)` | `(int \| str, RequestBody[UpdateMonitorRequest]) -> MonitorDto` | |
| `delete(id)` | `(int \| str) -> None` | |
| `pause(id)` | `(int \| str) -> MonitorDto` | |
| `resume(id)` | `(int \| str) -> MonitorDto` | |
| `test(id)` | `(int \| str) -> AssertionTestResultDto` | |
| `results(id, cursor?, limit?)` | `(int \| str, str?, int?) -> CursorPage[CheckResultDto]` | Cursor pagination |
| `versions(id, page=0, size=20)` | `(int \| str, int, int) -> Page[MonitorVersionDto]` | |

Both `list()` and `list_page()` accept optional server-side filter kwargs: `enabled`, `type`, `managed_by`, `tags` (comma-separated), `search`, and `environment_id`.

### client.incidents

| Method | Signature | Returns |
| - | - | - |
| `list()` | `() -> list[IncidentDto]` | |
| `list_page(page, size)` | `(int, int) -> Page[IncidentDto]` | |
| `get(id)` | `(int \| str) -> IncidentDetailDto` | |
| `create(body)` | `(RequestBody[CreateManualIncidentRequest]) -> IncidentDetailDto` | |
| `resolve(id, body=None)` | `(int \| str, RequestBody[ResolveIncidentRequest]?) -> IncidentDetailDto` | Body optional |

<Note>
  Incidents have no `delete` method — they are resolved, not deleted.
</Note>

### client.alert\_channels

| Method | Signature |
| - | - |
| `list()` | `() -> list[AlertChannelDto]` |
| `list_page(page, size)` | `(int, int) -> Page[AlertChannelDto]` |
| `get(id)` | `(int \| str) -> AlertChannelDto` |
| `create(body)` | `(RequestBody[CreateAlertChannelRequest]) -> AlertChannelDto` |
| `update(id, body)` | `(int \| str, RequestBody[UpdateAlertChannelRequest]) -> AlertChannelDto` |
| `delete(id)` | `(int \| str) -> None` |
| `test(id)` | `(int \| str) -> TestChannelResult` |

### client.notification\_policies

| Method | Signature |
| - | - |
| `list()` / `list_page(page, size)` | `list[NotificationPolicyDto]` / `Page[NotificationPolicyDto]` |
| `get(id)` | `NotificationPolicyDto` |
| `create(body)` / `update(id, body)` | `NotificationPolicyDto` |
| `delete(id)` / `test(id)` | `None` / `None` |

### client.tags

| Method | Signature |
| - | - |
| `list()` / `list_page(page, size)` | `list[TagDto]` / `Page[TagDto]` |
| `get(id)` | `TagDto` |
| `create(body)` / `update(id, body)` | `TagDto` |
| `delete(id)` | `None` |

### client.environments

| Method | Signature |
| - | - |
| `list()` / `list_page(page, size)` | `list[EnvironmentDto]` / `Page[EnvironmentDto]` |
| `get(slug)` | `EnvironmentDto` |
| `create(body)` / `update(slug, body)` | `EnvironmentDto` |
| `delete(slug)` | `None` |

### client.secrets

| Method | Signature |
| - | - |
| `list()` / `list_page(page, size)` | `list[SecretDto]` / `Page[SecretDto]` (metadata only — values are never returned) |
| `create(body)` / `update(key, body)` | `SecretDto` |
| `delete(key)` | `None` |

### client.resource\_groups

| Method | Signature |
| - | - |
| `list()` / `list_page(page, size)` | `list[ResourceGroupDto]` / `Page[ResourceGroupDto]` |
| `get(id)` | `ResourceGroupDto` |
| `create(body)` / `update(id, body)` | `ResourceGroupDto` |
| `delete(id)` | `None` |
| `add_member(group_id, body)` | `ResourceGroupMemberDto` |
| `remove_member(group_id, member_id)` | `None` |

### client.webhooks

| Method | Signature |
| - | - |
| `list()` / `list_page(page, size)` | `list[WebhookEndpointDto]` / `Page[WebhookEndpointDto]` |
| `get(id)` / `create(body)` / `update(id, body)` | `WebhookEndpointDto` |
| `delete(id)` | `None` |
| `test(id)` | `WebhookTestResult` |

### client.api\_keys

| Method | Signature |
| - | - |
| `list()` / `list_page(page, size)` | `list[ApiKeyDto]` / `Page[ApiKeyDto]` |
| `create(body)` | `ApiKeyCreateResponse` (full key value returned **once**) |
| `revoke(id)` / `delete(id)` | `None` / `None` |

<Note>
  There is no `get(id)` — fetch the list and filter, or store the ID from `create()`.
</Note>

### client.dependencies

| Method | Signature |
| - | - |
| `list()` / `list_page(page, size)` | `list[ServiceSubscriptionDto]` / `Page[ServiceSubscriptionDto]` |
| `get(id)` | `ServiceSubscriptionDto` |
| `track(slug, *, component_id?, alert_sensitivity?)` | `ServiceSubscriptionDto` |
| `update_alert_sensitivity(subscription_id, alert_sensitivity)` | `ServiceSubscriptionDto` |
| `delete(id)` | `None` |

`alert_sensitivity` is one of `ALL`, `INCIDENTS_ONLY`, `MAJOR_ONLY`, or `AWARENESS` (the API default). `component_id` subscribes to a single component instead of the whole service.

### client.deploy\_lock

| Method | Signature |
| - | - |
| `acquire(body)` | `DeployLockDto` (body must include `lockedBy`; `ttlMinutes` optional, default 30, max 60) |
| `current()` | `DeployLockDto \| None` |
| `release(lock_id)` / `force_release()` | `None` / `None` |

### client.maintenance\_windows

| Method | Signature |
| - | - |
| `list(monitor_id?, status?)` | `list[MaintenanceWindowDto]` |
| `list_page(page, size, ...)` | `Page[MaintenanceWindowDto]` |
| `get(id)` | `MaintenanceWindowDto` |
| `create(body)` / `update(id, body)` | `MaintenanceWindowDto` |
| `cancel(id)` | `None` (alerts resume immediately) |

### client.services

Read-only access to the third-party service status catalog (GitHub, Stripe, AWS, …).

| Method | Signature |
| - | - |
| `list(...)` | `CursorPage[ServiceCatalogDto]` (filters: `query`, `category`, `cursor`, `limit`) |
| `get(slug_or_id, summary?)` | `ServiceDetailDto` |
| `live_status(slug_or_id)` | `ServiceLiveStatusDto` |
| `categories()` / `summary()` | `list[CategoryDto]` / `GlobalStatusSummaryDto` |
| `components(slug_or_id)` | `list[ServiceComponentDto]` |
| `uptime(slug_or_id, period?)` | `ServiceUptimeResponse` |
| `component_uptime(slug_or_id, component_id, period?)` | per-component uptime history |
| `batch_component_uptime(slug_or_id, period?)` | `BatchComponentUptimeDto` |
| `day(slug_or_id, date)` | `ServiceDayDetailDto` |
| `incidents(...)` / `incident(slug_or_id, incident_id)` | `Page[ServiceIncidentDto]` / `ServiceIncidentDetailDto` |
| `maintenances(slug_or_id, status?)` | `list[ScheduledMaintenanceDto]` |

### client.status

| Method | Signature |
| - | - |
| `overview()` | `DashboardOverviewDto` |

### client.status\_pages

The largest namespace; root operations plus five sub-namespaces.

| Method | Signature |
| - | - |
| `list()` | `list[StatusPageDto]` |
| `get(id)` / `create(body)` / `update(id, body)` | `StatusPageDto` |
| `delete(id)` | `None` |
| `reorder_layout(id, body)` | `None` |

Sub-namespaces:

```python theme={null}
client.status_pages.components.list(page_id)
client.status_pages.components.create(page_id, body) / .update(page_id, comp_id, body) / .delete(page_id, comp_id) / .reorder(page_id, body)

client.status_pages.groups.list(page_id) / .create / .update / .delete

client.status_pages.incidents.list(page_id) / .get / .create / .update
client.status_pages.incidents.post_update(page_id, incident_id, body)
client.status_pages.incidents.publish(page_id, incident_id)
client.status_pages.incidents.dismiss(page_id, incident_id)
client.status_pages.incidents.delete(page_id, incident_id)

client.status_pages.subscribers.list(page_id) / .add / .remove

client.status_pages.domains.list(page_id) / .add / .verify / .remove
```

### client.forensics

Read-only audit trail for the detection engine. See [Incident Forensics](/incidents/forensics) for the conceptual overview.

| Method | Signature | Returns |
| - | - | - |
| `incident_timeline(id)` | `(int \| str) -> IncidentTimelineDto` | State transitions, triggering evals, active policy snapshot |
| `check_trace(check_id)` | `(str) -> CheckTraceDto` | Everything recorded for a single check execution |
| `policy_snapshot(hash_hex)` | `(str) -> PolicySnapshotDto` | Fetch policy snapshot by SHA-256 hash |
| `monitor_rule_evaluations(monitor_id, rule_type?, region?, only_matched?, from_?, to?, page=0, size=50)` | `... -> Page[RuleEvaluationDto]` | Paginated rule evaluations |
| `monitor_transitions(monitor_id, from_?, to?, page=0, size=50)` | `... -> Page[IncidentStateTransitionDto]` | Paginated state transitions |

## Pagination types

```python theme={null}
from devhelm import Page, CursorPage
```

### Page

| Attribute | Type | Description |
| - | - | - |
| `data` | `list[T]` | Items in this page |
| `has_next` | `bool` | Whether more pages exist |
| `has_prev` | `bool` | Whether previous pages exist |
| `total_elements` | `int \| None` | Server-reported total |
| `total_pages` | `int \| None` | Server-reported page count |

### CursorPage

| Attribute | Type | Description |
| - | - | - |
| `data` | `list[T]` | Items in this page |
| `next_cursor` | `str \| None` | Cursor for the next page |
| `has_more` | `bool` | Whether more items exist |

## Pydantic models

Every request and response is a `pydantic.BaseModel`. The full set is re-exported from `devhelm`:

```python theme={null}
from devhelm import (
    CreateMonitorRequest, UpdateMonitorRequest, MonitorDto,
    CreateManualIncidentRequest, ResolveIncidentRequest, IncidentDetailDto,
    CreateAlertChannelRequest, AlertChannelDto,
    # ...
)

req = CreateMonitorRequest.model_validate({
    "name": "API Health",
    "type": "HTTP",
    "config": {"url": "https://api.example.com/health"},
    "frequencySeconds": 60,
})
```

The full DTO/request inventory is in [`devhelm/__init__.py`](https://github.com/devhelmhq/sdk-python/blob/main/src/devhelm/__init__.py).

## Next steps

<CardGroup cols={2}>
  <Card title="Error handling" icon="triangle-exclamation" href="/sdk/python/error-handling">
    Exception types and retry patterns.
  </Card>

  <Card title="Concurrency patterns" icon="layer-group" href="/sdk/python/async-usage">
    Run the sync client concurrently in threads or asyncio.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.