1. Get the module
go get github.com/RealUptimeHQ/realuptime-errors-go. It installs from GitHub today with plain go get; unlike the JS and Python SDKs, there is no separate registry step coming later, because that is simply how Go modules work. The module is MIT and has zero runtime dependencies: standard library only, enforced by its own test suite, so it cannot drag a transitive dependency into your binary.
2. Create a client
client := realuptimeerrors.NewClient(realuptimeerrors.Config{DSN: "...", Release: "v2.4.1", Environment: "production"}), using the ingest URL from your project's dashboard. NewClient never returns nil and never panics: a missing DSN logs once and yields an inert client whose methods are safe no-ops, so a typo in configuration cannot be the reason your program fails to start.
3. Wire it into net/http
handler := realuptimeerrors.Middleware(client)(mux) wraps your existing mux. It stashes the client into each request's context (reach it downstream with realuptimeerrors.FromContext(r.Context())) and recovers a panic escaping the handler below it: it reports the panic with minimal request context, method and path, never headers, cookies or bodies by default, answers with a 500, and does not re-panic, so one broken handler cannot take the whole server down.
4. Report from a goroutine you supervise yourself
defer func() { client.Recover(recover()) }() reports a panic and then re-panics with the original value, so a supervisor further up still sees it. Use client.RecoverWithoutRePanic(recover()) instead when the goroutine should keep the process alive after reporting.
5. Hook it into log/slog
slog.New(realuptimeerrors.SlogHandler(client, slog.LevelError, base)) reports every record at or above the given level as a message, with its attributes riding as tags, while still passing every record through to the wrapped handler unchanged. This is a hook on your existing logger, not a replacement for it.
6. Know what gets scrubbed
Scrubbing runs inside your process before anything is serialized, and there is no switch to turn it off. Authorization, Proxy-Authorization and Cookie headers are replaced whole. Card-shaped digit runs that pass a Luhn check, JWTs, prefixed API keys and long high-entropy strings are replaced with [scrubbed] anywhere they appear. user.email and user.username are removed unless you name them: AllowFields: []string{"user.email"} in Config, per field, in code. The module is tested against the same scrub vector file as the JavaScript and Python SDKs, byte for byte, so all three behave identically.
7. Understand the buffer and the drop count
Events go into a bounded in-memory buffer (200 events) and ship on a background goroutine by default. Delivery backs off exponentially from 5 seconds to 5 minutes, pauses when you are over quota, and disables itself for the client's lifetime if the key is revoked. If the buffer overflows, the oldest event is evicted and counted, and the count rides the next successful batch, so client-side drops show on your dashboard instead of vanishing. Call client.Flush() before a process exits deliberately, and client.Close() to stop the background goroutine.
Go deeper
The full reference lives in the docs: Getting started documentation. Error codes named above are each explained in the error-code reference.