Build on Scrubbe
Official clients for the Scrubbe Operational Intelligence Platform — across five runtimes and the command line . Create incidents, stream live events, run governed playbooks, and query the knowledge base against api.scrubbe.com.
A single governed surface for incident operations
Most teams reach for an incident platform when manual coordination stops scaling — when the cost of a missed signal, an unapproved change, or an unrecorded decision becomes material . Scrubbe is built for that moment . Every client below speaks to one platform, enforces one governance model, and writes to one audit trail .
Governed by default
Every mutating call passes the policy gate . When human approval is required, the SDK raises a typed error carrying the approval id .
One surface, five runtimes
The same logical API across Python, TypeScript, Java, C#, and Go — plus the CLI . Learn the model once and apply it wherever your stack runs .
Auditable end to end
Every state transition is recorded . Incident IDs are stable (SI-XXXXXX), and the audit module exports the full trail on demand .
From first call to governed production
Authenticate, read incidents, and open your first one. No writes to production systems.
Ingest signals, enrich timelines, and stream live events into your own tooling.
Run governed playbooks behind named-operator approval. Gates surface as typed errors.
Close the loop at scale: audit, postmortems, and knowledge queries across the corpus.
Choose the SDK that matches your stack
Data, ML, and automation scripts; async-first incident bots built on httpx.
PyPI · scrubbe-sdkWeb apps, serverless, and edge runtimes — Node 18+, Deno, and Cloudflare Workers.
npm · @scrubbe/sdkJVM services and existing enterprise platforms on JDK 17 with Jackson binding.
Maven Central · com.scrubbe:scrubbe-sdk.NET 8 services wanting first-class dependency injection and IAsyncEnumerable streaming.
NuGet · Scrubbe.SdkHigh-throughput services and CLIs that need zero external dependencies and channel-based streaming.
pkg.go.dev · github.com/scrubbe/sdk-goOperators and CI pipelines — full platform control from the terminal, no code required.
Homebrew · scrubbeInstallation
Install from PyPI. No build step required.
| 1 | pip install scrubbe-sdk |
Quick start
An async client built on httpx. Paginate lazily and subscribe to live event streams.
| 1 | import asyncio |
| 2 | from scrubbe import Scrubbe |
| 3 | |
| 4 | async def main(): |
| 5 | async with Scrubbe(api_key="sk-...") as client: |
| 6 | # Create an incident |
| 7 | incident = await client.incident.create( |
| 8 | title="Payment gateway degraded", |
| 9 | priority="P1", |
| 10 | service="payment-api", |
| 11 | ) |
| 12 | print(incident["incident_id"]) # SI-000042 |
| 13 | |
| 14 | # List open incidents (lazy pagination) |
| 15 | async for inc in client.incident.list(state="INVESTIGATING"): |
| 16 | print(inc["incident_id"], inc["title"]) |
| 17 | |
| 18 | # Subscribe to live events |
| 19 | async for event in client.incident.subscribe(incident["incident_id"]): |
| 20 | print(event["type"], event["data"]) |
| 21 | |
| 22 | asyncio.run(main()) |
Authentication
Resolution paths: explicit key, OAuth2 client credentials, or environment configs.
| 1 | # 1. Explicit API key |
| 2 | client = Scrubbe(api_key="sk-...") |
| 3 | |
| 4 | # 2. OAuth2 client credentials (auto-refresh) |
| 5 | client = Scrubbe(client_id="...", client_secret="...") |
| 6 | |
| 7 | # 3. Environment variables (recommended for CI) |
| 8 | client = Scrubbe() |
| 9 | |
| 10 | # 4. Named profile in ~/.scrubbe/credentials |
| 11 | client = Scrubbe(profile="production") |
Configuration
Tune connection timeouts and jitter retry distributions.
| 1 | from scrubbe import Scrubbe |
| 2 | from scrubbe.utils.retry import RetryOptions |
| 3 | |
| 4 | client = Scrubbe( |
| 5 | api_key="sk-...", |
| 6 | base_url="https://api.scrubbe.com", # default |
| 7 | connect_timeout_ms=5_000, |
| 8 | read_timeout_ms=30_000, |
| 9 | retry=RetryOptions( |
| 10 | max_attempts=3, |
| 11 | base_delay_ms=500, |
| 12 | max_delay_ms=30_000, |
| 13 | respect_retry_after=True, # honour 429 headers |
| 14 | ), |
| 15 | ) |
Error handling
Governance gates raise GovernanceApprovalRequiredError — never a silent null.
| 1 | from scrubbe import ( |
| 2 | GovernanceApprovalRequiredError, |
| 3 | RateLimitedError, |
| 4 | UnauthenticatedError, |
| 5 | ScrubbeAPIError, |
| 6 | ) |
| 7 | |
| 8 | try: |
| 9 | await client.playbook.run("PB-0001", incident_id="SI-000042") |
| 10 | except GovernanceApprovalRequiredError as e: |
| 11 | print(f"Approval required: {e.approval_id}") |
| 12 | print(f"Approve at: {e.approval_url}") |
| 13 | except RateLimitedError as e: |
| 14 | print(f"Rate limited. Retry after {e.retry_after}s") |
Incident operations
The full core lifecycle: create, annotate timeline logs, and resolve.
| 1 | async with Scrubbe(api_key="sk-...") as client: |
| 2 | inc = await client.incident.create( |
| 3 | title="DB replica lag spike", |
| 4 | priority="P2", |
| 5 | service="orders-db", |
| 6 | ) |
| 7 | await client.timeline.add( |
| 8 | incident_id=inc["incident_id"], |
| 9 | message="Replica lag reached 42s at 14:03 UTC", |
| 10 | source="monitoring", |
| 11 | ) |
| 12 | await client.incident.resolve( |
| 13 | incident_id=inc["incident_id"], |
| 14 | resolution="Replica re-synced after network blip.", |
| 15 | ) |
MCP queries
Ask the knowledge base in natural language; responses cite source incidents.
| 1 | async with Scrubbe(api_key="sk-...") as client: |
| 2 | answer = await client.mcp.query( |
| 3 | q="What caused the payment outages in Q2?", |
| 4 | ) |
| 5 | print(answer["answer"]) |
Development
Set up local developer orchestration packages safely.
| 1 | pip install -e ".[dev]" |
| 2 | ruff check src/ tests/ # lint |
| 3 | mypy src/scrubbe # type-check |
| 4 | pytest --cov=scrubbe tests/ # tests |
Scrubbe pushes real-time event payloads to any HTTPS endpoint you register . Signatures are verified securely with HMAC-SHA256 filters using your generated webhook secret .
| 1 | import hashlib, hmac |
| 2 | |
| 3 | def verify_signature(payload: bytes, sig: str, secret: str) -> bool: |
| 4 | expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest() |
| 5 | return hmac.compare_digest(f"sha256={expected}", sig) |
| Event Name | Description Context | Payload Schema |
|---|---|---|
| incident.created | A new incident was opened. | IncidentCreatedPayload |
| incident.updated | Priority, state, or service assignment changed. | IncidentUpdatedPayload |
| incident.resolved | Incident marked resolved with an optional summary. | IncidentResolvedPayload |
| playbook.executed | A playbook run completed (executed, parked, blocked). | PlaybookExecutedPayload |
| playbook.approval_required | Execution gated pending human approval. | ApprovalRequiredPayload |
| approval.granted | A pending approval was approved by an operator. | ApprovalGrantedPayload |
| handover.created | A new shift handover was generated. | HandoverCreatedPayload |
| postmortem.published | A post-mortem was finalised and published. | PostmortemPublishedPayload |
| agent.investigation_completed | An AI investigation finished. | InvestigationPayload |
| Capability | Python | TS / JS | Java | C# | Go |
|---|---|---|---|---|---|
| Lazy cursor pagination | ✓ | ✓ | Planned | ✓ | ✓ |
| Event streaming (SSE) | ✓ | ✓ | Planned | ✓ | ✓ |
| OAuth2 client credentials | ✓ | ✓ | ✓ | ✓ | ✓ |
| Credential configuration profiles | ✓ | ✓ | — | ✓ | ✓ |
| Retry logic with full jitter | ✓ | ✓ | ✓ | ✓ | ✓ |
| Automatic idempotency keys | ✓ | ✓ | Planned | ✓ | ✓ |
| Governance approval error types | ✓ | ✓ | ✓ | ✓ | ✓ |
| MCP knowledge query modules | ✓ | ✓ | Planned | ✓ | ✓ |
| Native Dependency injection | — | — | — | ✓ | — |
| Edge serverless runtime support | — | ✓ | — | — | — |
- —Public GA of Python, TypeScript, Java, C# / .NET, and Go SDKs
- —C# SDK adds first-class dependency injection and IAsyncEnumerable streaming
- —Go SDK ships with zero external dependencies and channel-based SSE
- —Scrubbe CLI v0.9.2 for macOS, Linux, and Windows WSL2
- —MCP module for knowledge-base queries across all GA SDKs
- —Added client.mcp module to Python and TypeScript SDKs
- —Retry now supports respect_retry_after to honour 429 headers
- —Fixed OAuth2 token refresh race condition under concurrent requests
- —CLI: added scrubbe incident stream for live SSE output
- —[Breaking] playbook.run() now raises a typed GovernanceApprovalRequired error instead of returning null on gated executions — update all catch blocks
- —Added approval_url and eal_required fields to the governance error
- —New client.approval module for polling approval state
- —Typed exception hierarchy — all SDK errors now derive from a common base
Cookie preferences
We use essential cookies to keep Scrubbe secure and functional. You can choose whether to allow analytics, preferences, and marketing cookies, and update your choices at any time.
Essential cookies
Required for security, session continuity, consent state, and core site functionality. These are always on.
Analytics cookies
Help us understand usage patterns so we can improve product pages, onboarding paths, and documentation quality.
Preference cookies
Remember selected settings such as region, UI preferences, and previously chosen site options.
Marketing cookies
Enable campaign measurement and more relevant follow-up communications across trusted channels.
Your choices are stored locally in this browser and can be updated at any time from the cookie settings button.
