Back to Docs
SDKs & Libraries

SDKs & Libraries

Official client libraries for the PulseGuard API. Install, configure, and start monitoring in minutes with your language of choice.

Overview

PulseGuard provides official SDKs for the most popular programming languages. Each SDK wraps our REST API with idiomatic interfaces, built-in retries, type safety, and comprehensive error handling.

FeatureNode.jsPythonGoRuby
Type SafetyTypeScriptType HintsStructsSorbet
Auto RetriesYesYesYesYes
Pagination HelpersYesYesYesYes
Webhook VerificationYesYesYesYes
Async SupportNativeasyncioGoroutinesAsync

Node.js / TypeScript SDK

Full TypeScript support with auto-generated types from the PulseGuard API schema. Works with Node.js 18+, Bun, and Deno.

Installation

# npm
npm install @pulseguard/sdk

# yarn
yarn add @pulseguard/sdk

# pnpm
pnpm add @pulseguard/sdk

Configuration

import { PulseGuard } from "@pulseguard/sdk";

const client = new PulseGuard({
  apiKey: process.env.PULSEGUARD_API_KEY,  // Required
  baseUrl: "https://www.pulseguard.floelife.com/api/v1", // Optional (default)
  timeout: 30_000,                          // Optional: request timeout in ms
  retries: 3,                               // Optional: max retries on failure
});

Security: Never hardcode API keys. Use environment variables or a secrets manager like AWS Secrets Manager or Vault.

Working with Monitors

// List all monitors
const monitors = await client.monitors.list();
console.log(monitors.data); // Monitor[]

// Create a monitor
const monitor = await client.monitors.create({
  name: "Production API",
  type: "http",
  url: "https://api.example.com/health",
  intervalSeconds: 60,
  regions: ["us-east-1", "eu-west-1"],
  assertions: [
    { type: "status_code", operator: "eq", value: "200" },
    { type: "response_time", operator: "lt", value: "2000" },
  ],
});

// Get a specific monitor
const detail = await client.monitors.get("mon_abc123");
console.log(detail.uptime["30d"]); // 99.95

// Update a monitor
await client.monitors.update("mon_abc123", {
  intervalSeconds: 30,
  regions: ["us-east-1", "eu-west-1", "ap-southeast-1"],
});

// Delete a monitor
await client.monitors.delete("mon_abc123");

// Get check results (last 24 hours)
const checks = await client.monitors.getCheckResults("mon_abc123", {
  hours: 24,
  limit: 100,
});

// Get uptime stats
const stats = await client.monitors.getUptimeStats("mon_abc123", {
  days: 30,
});
console.log(stats.uptimePercent);    // 99.95
console.log(stats.avgResponseTime);  // 142
console.log(stats.p95ResponseTime);  // 385

Managing Incidents

// List active incidents
const incidents = await client.incidents.list({ status: "active" });

// Create an incident
const incident = await client.incidents.create({
  title: "Database Maintenance Window",
  severity: "minor",
  monitorId: "mon_abc123",
});

// Post an update
await client.incidents.addUpdate(incident.id, {
  status: "identified",
  message: "Root cause identified. Deploying fix.",
});

// Resolve an incident
await client.incidents.update(incident.id, {
  status: "resolved",
});

Webhook Verification

import { verifyWebhookSignature } from "@pulseguard/sdk";

// Express.js middleware example
app.post("/webhooks/pulseguard", (req, res) => {
  const signature = req.headers["x-pulseguard-signature"];
  const isValid = verifyWebhookSignature(
    req.body,
    signature,
    process.env.PULSEGUARD_WEBHOOK_SECRET,
  );

  if (!isValid) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const event = req.body;
  switch (event.type) {
    case "monitor.down":
      console.log(`Monitor ${event.monitor.name} is down!`);
      break;
    case "monitor.up":
      console.log(`Monitor ${event.monitor.name} recovered.`);
      break;
    case "incident.created":
      console.log(`New incident: ${event.incident.title}`);
      break;
  }

  res.json({ received: true });
});

Python SDK

Fully typed Python client with both synchronous and async support. Compatible with Python 3.8+ and includes type hints for all models.

Installation

# pip
pip install pulseguard

# poetry
poetry add pulseguard

# With async support (includes aiohttp)
pip install pulseguard[async]

Configuration

from pulseguard import PulseGuard

# Sync client
client = PulseGuard(
    api_key="pg_live_abc123def456",  # Or set PULSEGUARD_API_KEY env var
    timeout=30,                       # Optional: request timeout in seconds
    max_retries=3,                    # Optional: max retries on failure
)

# Async client
from pulseguard import AsyncPulseGuard

async_client = AsyncPulseGuard(
    api_key="pg_live_abc123def456",
)

Working with Monitors

# List all monitors
monitors = client.monitors.list()
for monitor in monitors.data:
    print(f"{monitor.name}: {monitor.current_status}")

# Create a monitor
monitor = client.monitors.create(
    name="Production API",
    type="http",
    url="https://api.example.com/health",
    interval_seconds=60,
    regions=["us-east-1", "eu-west-1"],
    assertions=[
        {"type": "status_code", "operator": "eq", "value": "200"},
        {"type": "response_time", "operator": "lt", "value": "2000"},
    ],
)
print(f"Created monitor: {monitor.id}")

# Get uptime stats
stats = client.monitors.get_uptime_stats(monitor.id, days=30)
print(f"Uptime: {stats.uptime_percent}%")
print(f"Avg Response: {stats.avg_response_time}ms")
print(f"P95 Response: {stats.p95_response_time}ms")

# Update a monitor
client.monitors.update(monitor.id, interval_seconds=30)

# Delete a monitor
client.monitors.delete(monitor.id)

Async Usage

import asyncio
from pulseguard import AsyncPulseGuard

async def main():
    client = AsyncPulseGuard(api_key="pg_live_abc123")

    # Concurrent operations
    monitors, incidents = await asyncio.gather(
        client.monitors.list(),
        client.incidents.list(status="active"),
    )

    print(f"Monitors: {len(monitors.data)}")
    print(f"Active incidents: {len(incidents.data)}")

    # Context manager for automatic cleanup
    async with AsyncPulseGuard(api_key="pg_live_abc123") as client:
        monitor = await client.monitors.get("mon_abc123")
        print(f"Status: {monitor.current_status}")

asyncio.run(main())

Managing Incidents

# Create an incident
incident = client.incidents.create(
    title="Scheduled Maintenance",
    severity="minor",
    monitor_id="mon_abc123",
)

# Post an update
client.incidents.add_update(
    incident_id=incident.id,
    status="identified",
    message="Maintenance in progress. ETA: 30 minutes.",
)

# Resolve
client.incidents.update(incident.id, status="resolved")

Go SDK

Idiomatic Go client with strongly typed structs, context support for cancellation, and built-in rate limiting. Requires Go 1.21+.

Installation

go get github.com/pulseguard/go-sdk

Configuration

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    pulseguard "github.com/pulseguard/go-sdk"
)

func main() {
    client := pulseguard.NewClient(
        pulseguard.WithAPIKey(os.Getenv("PULSEGUARD_API_KEY")),
        pulseguard.WithTimeout(30 * time.Second), // Optional
        pulseguard.WithRetries(3),                  // Optional
    )

    ctx := context.Background()

    // List all monitors
    monitors, err := client.Monitors.List(ctx, &pulseguard.ListOptions{
        Page:  1,
        Limit: 20,
    })
    if err != nil {
        log.Fatal(err)
    }

    for _, m := range monitors.Data {
        fmt.Printf("%s: %s\n", m.Name, m.CurrentStatus)
    }
}

Working with Monitors

// Create a monitor
monitor, err := client.Monitors.Create(ctx, &pulseguard.CreateMonitorInput{
    Name:            "Production API",
    Type:            pulseguard.MonitorTypeHTTP,
    URL:             "https://api.example.com/health",
    IntervalSeconds: 60,
    Regions:         []string{"us-east-1", "eu-west-1"},
    Assertions: []pulseguard.Assertion{
        {Type: "status_code", Operator: "eq", Value: "200"},
        {Type: "response_time", Operator: "lt", Value: "2000"},
    },
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Created: %s\n", monitor.ID)

// Get uptime stats
stats, err := client.Monitors.GetUptimeStats(ctx, monitor.ID, &pulseguard.UptimeStatsOptions{
    Days: 30,
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Uptime: %.2f%%\n", stats.UptimePercent)
fmt.Printf("P95: %dms\n", stats.P95ResponseTime)

// Update a monitor
_, err = client.Monitors.Update(ctx, monitor.ID, &pulseguard.UpdateMonitorInput{
    IntervalSeconds: pulseguard.Int(30),
})

// Delete a monitor
err = client.Monitors.Delete(ctx, monitor.ID)

Managing Incidents

// Create an incident
incident, err := client.Incidents.Create(ctx, &pulseguard.CreateIncidentInput{
    Title:     "API Degradation",
    Severity:  pulseguard.SeverityMajor,
    MonitorID: "mon_abc123",
})

// Post an update
_, err = client.Incidents.AddUpdate(ctx, incident.ID, &pulseguard.IncidentUpdateInput{
    Status:  pulseguard.StatusIdentified,
    Message: "Root cause identified. Scaling up servers.",
})

// Resolve
_, err = client.Incidents.Update(ctx, incident.ID, &pulseguard.UpdateIncidentInput{
    Status: pulseguard.StatusResolved,
})

Ruby SDK

Clean, Ruby-idiomatic client with method chaining, Sorbet type signatures, and Faraday-based HTTP transport. Compatible with Ruby 3.0+.

Installation

# Gemfile
gem "pulseguard"

# Or install directly
gem install pulseguard

Configuration

require "pulseguard"

# Global configuration
PulseGuard.configure do |config|
  config.api_key = ENV["PULSEGUARD_API_KEY"]
  config.timeout = 30       # Optional: seconds
  config.max_retries = 3    # Optional
end

client = PulseGuard::Client.new

# Or pass config directly
client = PulseGuard::Client.new(api_key: "pg_live_abc123")

Working with Monitors

# List all monitors
monitors = client.monitors.list
monitors.data.each do |monitor|
  puts "#{monitor.name}: #{monitor.current_status}"
end

# Create a monitor
monitor = client.monitors.create(
  name: "Production API",
  type: "http",
  url: "https://api.example.com/health",
  interval_seconds: 60,
  regions: ["us-east-1", "eu-west-1"],
  assertions: [
    { type: "status_code", operator: "eq", value: "200" },
    { type: "response_time", operator: "lt", value: "2000" },
  ]
)
puts "Created: #{monitor.id}"

# Get uptime stats
stats = client.monitors.get_uptime_stats(monitor.id, days: 30)
puts "Uptime: #{stats.uptime_percent}%"
puts "Avg Response: #{stats.avg_response_time}ms"

# Update
client.monitors.update(monitor.id, interval_seconds: 30)

# Delete
client.monitors.delete(monitor.id)

Managing Incidents

# Create an incident
incident = client.incidents.create(
  title: "Database Maintenance",
  severity: "minor",
  monitor_id: "mon_abc123"
)

# Post an update
client.incidents.add_update(
  incident.id,
  status: "identified",
  message: "Maintenance in progress."
)

# Resolve
client.incidents.update(incident.id, status: "resolved")

Rails Integration

# config/initializers/pulseguard.rb
PulseGuard.configure do |config|
  config.api_key = Rails.application.credentials.pulseguard_api_key
end

# app/controllers/webhooks_controller.rb
class WebhooksController < ApplicationController
  skip_before_action :verify_authenticity_token

  def pulseguard
    unless PulseGuard::Webhook.verify(
      payload: request.raw_post,
      signature: request.headers["X-PulseGuard-Signature"],
      secret: ENV["PULSEGUARD_WEBHOOK_SECRET"]
    )
      return head :unauthorized
    end

    event = JSON.parse(request.raw_post)
    case event["type"]
    when "monitor.down"
      SlackNotifier.alert(event["monitor"]["name"])
    when "incident.created"
      PagerDuty.trigger(event["incident"]["title"])
    end

    head :ok
  end
end

Error Handling

All SDKs provide structured error types that map to API error codes. Handle errors gracefully to build resilient integrations.

Node.js / TypeScript

import {
  PulseGuardError,
  AuthenticationError,
  RateLimitError,
  NotFoundError,
} from "@pulseguard/sdk";

try {
  await client.monitors.get("invalid");
} catch (err) {
  if (err instanceof NotFoundError) {
    console.log("Monitor not found");
  } else if (err instanceof RateLimitError) {
    console.log(`Retry after ${err.retryAfter}s`);
  } else if (err instanceof AuthenticationError) {
    console.log("Check your API key");
  }
}

Python

from pulseguard.exceptions import (
    PulseGuardError,
    AuthenticationError,
    RateLimitError,
    NotFoundError,
)

try:
    client.monitors.get("invalid")
except NotFoundError:
    print("Monitor not found")
except RateLimitError as e:
    print(f"Retry after {e.retry_after}s")
except AuthenticationError:
    print("Check your API key")
except PulseGuardError as e:
    print(f"API error: {e.message}")
Exception ClassHTTP CodeWhen
AuthenticationError401Invalid or missing API key
ForbiddenError403Insufficient permissions
NotFoundError404Resource does not exist
ValidationError400Invalid request parameters
RateLimitError429Too many requests (has retryAfter)
ServerError500PulseGuard internal error

Best Practices

Use Environment Variables for API Keys

Never hardcode API keys in source code. Use environment variables, .env files (excluded from version control), or a secrets manager.

# .env
PULSEGUARD_API_KEY=pg_live_abc123def456

# .gitignore
.env
.env.local

Implement Exponential Backoff

All SDKs include built-in retries with exponential backoff, but if you're using the REST API directly, implement your own retry logic for 429 and 5xx errors.

Use Pagination for Large Datasets

When listing monitors or incidents, always paginate. The default limit is 20, maximum is 100.

// Auto-paginate through all monitors
for await (const monitor of client.monitors.listAutoPaginate()) {
  console.log(monitor.name);
}

Verify Webhook Signatures

Always verify the X-PulseGuard-Signature header on incoming webhooks to ensure requests are authentic and haven't been tampered with.

Handle Rate Limits Gracefully

The API returns a 429 status with a Retry-After header. SDKs handle this automatically, but respect rate limits in your application logic.

Use Specific Scopes for API Keys

Create API keys with only the permissions your integration needs. Use read-only keys for dashboards and monitoring, write keys only where needed.

Need Help?

Check the API Reference for complete endpoint documentation, or reach out to support@pulseguard.floelife.com for assistance.