Using the SDKs

Two read SDKs are published: Errorbird.Client (NuGet) and @errorbird/client (npm). Both only read; the write path is HTTP and is handled by your existing logging setup.

.NET — Errorbird.Client

dotnet add package Errorbird.Client
builder.Services.AddErrorbirdClient(options =>
{
    options.ApiKey = builder.Configuration["Errorbird:ApiKey"]!;
    options.ProjectId = Guid.Parse(builder.Configuration["Errorbird:ProjectId"]!);
});

Using it takes three lines:

app.MapGet("/dashboard", async (IErrorbirdReadClient errorbird, CancellationToken ct) =>
{
    var summary = await errorbird.GetSummaryAsync(ct);
    var issues = await errorbird.ListIssuesAsync(new IssueListQuery(Limit: 10), ct);

    return Results.Ok(new { summary, issues.Items });
});

A working reference application lives in the repository: samples/Errorbird.Sample.AdminPanel.

Surface

Method Maps to
GetSummaryAsync() /projects/{id}/summary
ListIssuesAsync(query) /projects/{id}/issues
ListIssueEventsAsync(issueId, cursor, limit) /issues/{id}/events
SearchLogsAsync(query) /projects/{id}/events
GetUptimeAsync(monitorId, days) /monitors/{id}/uptime
GetSslStatusAsync(monitorId) /monitors/{id}/ssl-status
GetDomainStatusAsync(monitorId) /monitors/{id}/domain-status
ListReleasesAsync(days) /projects/{id}/releases
GetReleaseAsync(release, days) /projects/{id}/releases/details
ListDashboardsAsync() /projects/{id}/dashboards
GetWidgetDataAsync(dashboardId, widgetId, range, timeZone) /projects/{id}/dashboards/{dashboardId}/widgets/{widgetId}/data

Errors arrive as ErrorbirdApiException with StatusCode and Code fields; your dashboard does not need to parse text to tell "quota exceeded" from "invalid key".

JavaScript / TypeScript — @errorbird/client

npm install @errorbird/client
import { ErrorbirdClient } from '@errorbird/client'

const errorbird = new ErrorbirdClient({
  apiKey: 'ebrd_pub_…',
  projectId: '01a01b…',
})

const summary = await errorbird.getSummary()
const issues = await errorbird.listIssues({ limit: 10, status: 'Unresolved' })

// How did the last deploy go?
const [latest] = await errorbird.listReleases(7)
const detail = latest ? await errorbird.getRelease(latest.release) : null

// Draw the dashboard charts from the dashboard on your own page
const [dashboard] = await errorbird.listDashboards()
const chart = dashboard
  ? await errorbird.getWidgetData(dashboard.id, dashboard.widgets[0].id, { range: '7d' })
  : null

Every method accepts an AbortSignal; cancelling the request when a component unmounts prevents leaks in React applications:

useEffect(() => {
  const controller = new AbortController()

  errorbird.getSummary(controller.signal).then(setSummary).catch(() => {})

  return () => controller.abort()
}, [])

Live stream

const stop = errorbird.stream({
  onEvent: (event) => console.log(event.message),
  onError: () => console.warn('Stream dropped; it will reconnect automatically'),
})

// When the component unmounts
stop()

Choosing a key

In code that runs in the browser, always use the publishable key. The secret key belongs on the server: a secret key in a compiled JavaScript bundle means anyone can write fake data on behalf of the project.

That is why the publishable key's domain list is mandatory — Errorbird does not let you create a publishable key without one.

Versions and breaking changes

The SDKs are bound to version v1 of the API. New fields are added in minor versions; fields the SDK does not know are silently ignored. A field is removed only with a new API version.