Skip to documentation content

Ruby SDK

A small, Ruby-native client for applications and jobs.

In this guide
  1. 1Understand the package contract
  2. 2Run or resume jobs
  3. 3Handle native errors
  4. 4Verify webhooks
In this guide
  1. 1Understand the package contract
  2. 2Run or resume jobs
  3. 3Handle native errors
  4. 4Verify webhooks

Package contract

The planned gem is nordic_devhouse and the top-level module is NordicDevhouse. It provides small immutable result objects and a reusable connection-pooled client.

DistributionNamespace or importRuntime
nordic_devhouseNordicDevhouseSupported Ruby release lines

Create and reuse the client

The Ruby interface favors keyword arguments and explicit result objects. One run call hides job polling and retry details without converting responses into loosely structured hashes.

Ruby
require "nordic_devhouse"

client = NordicDevhouse::Client.new(
  api_key: ENV.fetch("NORDIC_DEVHOUSE_API_KEY"),
  timeout: 30,
  max_retries: 3
)

result = client.scrape.run(
  url: "https://example.com/products",
  formats: [:json],
  idempotency_key: "catalog-2026-08-11"
)

puts [result.job_id, result.records].join(" ")

Control a durable job

Start and wait fit Sidekiq, Active Job, and other worker systems without coupling the core gem to them. Fiber scheduling may be supported by the transport implementation.

Ruby
job = client.scrape.start(
  url: "https://example.com/products",
  formats: [:json]
)

result = client.jobs.wait(
  job.id,
  timeout: 600
)

Public models

Names follow the language conventions, but every SDK preserves the same fields and job-state semantics.

ConceptContract
Client optionsAPI key, base URL, request timeout, retry budget, and optional test transport
Scrape requestURL, output formats, webhook URL, metadata, and idempotency key
JobStable ID, status, timestamps, progress, and warnings
Job resultJob ID, record count, typed data, metadata, and request ID
Webhook eventVerified event ID, type, timestamp, and typed data

Handle errors idiomatically

All exceptions inherit NordicDevhouse::Error and expose code, request_id, status, attempts, and cause. RateLimited adds retry_after and ValidationError adds issues.

Ruby
begin
  client.scrape.run(url: url, formats: [:json])
rescue NordicDevhouse::RateLimited => error
  logger.warn("rate limited",
    request_id: error.request_id,
    retry_after: error.retry_after)
  raise
rescue NordicDevhouse::ValidationError => error
  render_validation(error.issues)
rescue NordicDevhouse::Error => error
  logger.error("SDK failure", request_id: error.request_id)
  raise
end

Verify the raw webhook body

Verification uses the exact request bytes, validates HMAC-SHA256 and timestamp tolerance, and returns a typed event. Persist the verified event ID to prevent duplicate processing.

Ruby
event = client.webhooks.verify(
  payload: request.raw_post,
  signature: request.get_header("HTTP_NORDIC_SIGNATURE"),
  secret: ENV.fetch("NORDIC_WEBHOOK_SECRET")
)

import_result(event.data.job_id) if event.type == "scrape.completed"

Runtime and lifecycle rules

  1. 1
    Support maintained Ruby release lines and publish typed RBS declarations
  2. 2
    Use keyword arguments at the caller seam
  3. 3
    Return immutable value objects instead of OpenStruct values
  4. 4
    Reuse pooled connections and make close idempotent
  5. 5
    Keep Rails and Sidekiq helpers in optional integration files
Was this page helpful?