API overview

The concepts behind every Hedgehog API call — authentication, organization scoping, content resolution, and pagination.

Authentication

Viewers sign in through the widget's built-in OAuth flow — there are no tokens for you to manage. If your web host already manages member sessions (SSO), comments, reactions, notifications, and both live widgets accept a pre-issued member access token through their token property or attribute. The profile custom element has no token input; it uses the shared cached session or its own OAuth sign-in button. Programmatic and native integrations inject host-managed sessions through the client constructor. All authenticated requests send the token as a Bearer token in the Authorization header.

Organization scoping

Hedgehog is multi-tenant: every request is scoped to your organization, and every organization's data is fully isolated. IDs are typed UUIDs — an organization ID looks like Organization:550e8400-e29b-41d4-a716-446655440000, a comment ID like Comment:<uuid>.

Content resolution

Content-scoped widgets (comments, reactions, live comments, and live reactions) take any stable external identifier — a slug or URL — as their id attribute and deterministically resolve it to a Content:<uuid> via UUID v5, namespaced to your organization. Notifications and profile are account-scoped and take no id. SDKs retain the external ID for convenience APIs and use the derived typed ID for reads, writes, state, socket topics, and SSE subscriptions. Derive the typed ID yourself only when calling a typed-target API directly:

TypeScript
import { generateUuidV5, stripTypePrefix } from '@hedgehog/sdk-web'

const organizationUuid = stripTypePrefix(client.organizationId)
const contentId = `Content:${await generateUuidV5(organizationUuid, 'my-article-slug')}`

Content, comment, and live-comment mutations carry the organization in the path, and the bearer token must belong to that organization. A client-derived UUID provides identity, not authorization: storage, caches, streams, and broadcasts are all qualified by the path organization, and comment targets are resolved inside that tenant before any write is queued. SDKs can also register the page URL hosting content via PUT /api/organizations/:organizationId/comments/:contentId/link, driven by the comments widget's page-url attribute. The URL must be on your registered site origin; the first registration wins and repeats are no-ops. Registered pages power the article context shown on notifications and profile comment feeds, with deep links back to the comment.

Pagination

List endpoints use key-based pagination: each page's paging.next is an opaque key you pass back to fetch the next page. No page numbers, no offsets.

TypeScript
const page = await client.comments.list(contentId)

const nextPage = page.paging.next
   ? await client.comments.list(contentId, { next: page.paging.next })
   : null

Client API surface

client.comments

List, create, edit, and delete threaded comments; fetch edit history and your own comments.

client.reactions

Fetch the reaction manifest, add and remove reactions, and read aggregated reaction metrics.

client.notifications

Unread counts and the account-scoped notification feed, with per-item and mark-all read.

client.liveComments / client.liveReactions

Flat live-chat threads and live reaction taps, hydrated over REST and streamed over SSE.

Interactive API reference

Enterprise plans with API access get an interactive API reference in the dashboard — every endpoint your plan can call, with schemas and a built-in request runner. See Enterprise for identity federation and the control-plane API.