---
summary: Agent-oriented end-to-end guide for integrating SigID into a third-party application–login, tokens, webhooks, commerce, OpenAPI, and package choice. Two supported login shapes: drop-in/SDK for browser apps, and authorization-code+PKCE for confidential servers with their own sessions.
tags:
  - developers
  - agents
  - integration
  - third-party
  - openapi
categories:
  - For Developers
---

# Integrate SigID Into A Third-Party App

<!-- agent:page
You are a coding agent wiring SigID into a third-party codebase (not SigID itself).
CRITICAL defaults:
1. Browser/SPA login: prefer hosted login via @sigid/start (https://cdn.sigid.org/v1/sigid.js) or framework package. Do NOT hand-roll authorize URLs, PKCE, callback exchange, or JWKS in the browser. Confidential server apps with their own sessions MAY use authorization-code+PKCE by hand against /oauth/authorize – that is the supported path, not a workaround (see "Login For A Confidential Server / Existing Session").
2. Cold start: npx @sigid/cli setup --name <app> --redirect-uri <exact-callback> then paste start_snippet + env_block.
3. Production OpenAPI is the *public* document only (openapi.exposure=public or committed openapi-public.json). Never assume full admin OpenAPI is public.
4. Backend must validate access tokens (issuer, audience, exp, tenant, scope, subject_type). Frontend session alone is not authorization.
5. Commerce fulfillment is webhooks + your DB, not a remote entitlements GET.
6. Sandbox bootstrap returns fixture_end_user (once-only password) for hosted authorize E2E. Do not use agent identities as end-user stand-ins; no general test-user mint API.
Follow the decision tree on this page; then deep-link to add-login, verify-tokens, protect-apis, webhooks, commerce, agent-quickstart as needed.
-->

Use this page when an AI agent or human is integrating **SigID into another
product** (SaaS, agent, CLI, or API). It is the ordered checklist; deep pages
carry the exact steps.

## Decision Tree

```text
Need interactive human login?
  Browser app / SPA / no existing server session?
    → Prefer drop-in script or framework SDK (below). Do not hand-roll OIDC for the browser.
  Confidential server with its own session (B2B SaaS, existing cookie auth)?
    → Prefer @sigid/backend (confidential code exchange, ID-token verification,
      RP-initiated logout, webhooks). See "Login For A Confidential Server /
      Existing Session" below. Hand-rolled authorization-code+PKCE remains a
      valid fallback.
  Backend API only (no interactive login)?
    → verify-tokens + protect-apis
  Autonomous agent?
    → agent-quickstart

Need to sell paid access?
  yes → commerce.md (payment links + webhooks). Not identity billing entitlements.

Need async events (membership, payment, security)?
  yes → webhooks.md + webhook-events.md (suite sigid-webhook-v1)
```

## Login For A Confidential Server / Existing Session

Many real apps already run a confidential server with their own session
store (B2B SaaS, server-rendered apps, an existing cookie/auth boundary that
must stay authoritative). The recommended path is the **`@sigid/backend`** SDK
([Backend SDK For Confidential Servers](backend-sdk.md)), which removes the
footguns of hand-rolling – PKCE/state/nonce handling, confidential code
exchange, JWKS caching, ID-token verification, and RP-initiated logout.

A hand-rolled **authorization-code + PKCE** flow against `/oauth/authorize`
remains a valid fallback when you cannot use the SDK. The "don't hand-roll
OIDC" guidance above is scoped to **browser/SPA** apps, where the drop-in
script and framework packages remove real footguns (PKCE/state handling, JWKS
caching, popup/redirect UX).

When hand-rolled code flow is right:

- Your server is a **confidential** OAuth client (it can hold a client secret
  or use a public client with PKCE and a single exact redirect URI).
- You already issue and validate your own app session cookie and do **not**
  want a second session authority.
- You need fine-grained control over the authorize request (audience, `prompt`,
  AAL, organization, login hints) per route.

Minimal shape (your server owns every step):

```text
GET  {issuer}/oauth/authorize?response_type=code
     &client_id=...&redirect_uri=<exact>&scope=openid+profile+email
     &audience=<your-api>&state=<random>&code_challenge=<S256>&code_challenge_method=S256
GET  {issuer}/.well-known/openid-configuration   # endpoints + JWKS
GET  {issuer}/.well-known/jwks.json               # verify id_token/access_token
POST {issuer}/oauth/token                          # exchange code + code_verifier
```

Then on your callback route: exchange the code, **verify the `id_token` and
`access_token`** (issuer, audience, exp, tenant, scope – see
[Verify Access Tokens](verify-tokens.md)), mint your own app session cookie,
and discard the OAuth artifacts. Use `/oauth/revoke` on logout. This is exactly
the pattern production B2B integrations use; it is not treated as suspect.

Do **not** hand-roll the *browser* flow (popup/redirect choreography, PKCE in
the browser, JWKS in the browser) – for that, use the drop-in script or a
framework package.


| Value | Example | Notes |
|---|---|---|
| Issuer | `https://auth.sigid.org` | OIDC discovery base |
| Client ID | public app id | From Dashboard Applications |
| Client secret | confidential only | Never in browser code |
| Redirect URI | `https://app.example.com/auth/callback` | **Exact** match (scheme, host, port, path, slash) |
| Scopes | `openid profile email` | Add API scopes only if issued for your audience |
| Audience | your API identifier | Backend token validation |
| Webhook secret | ≥ 32 chars | Optional until you subscribe events |

Cold agent without a human-precreated app:

```bash
npx @sigid/cli setup --name my-app --redirect-uri http://localhost:5173/auth/callback
```

Paste `start_snippet` and `env_block` from the output. Sandbox orgs have
activation limits until a human co-owner activates production features.

**Testing hosted end-user login:** cold `setup` / workspace bootstrap returns
`fixture_end_user` – ordinary human `@test.sigid.dev` + once-only
password on the sandbox environment (outbound mail to that domain is suppressed).
Run the app’s authorize round trip with those credentials. Agents are not
end-user stand-ins. More users: signup, invite, or AAL2 admin create. Fixture is
retired when the sandbox org is activated.

## 2. Choose The Login Package

| Situation | Use | Avoid |
|---|---|---|
| Plain HTML / marketing site / quick demo | **`@sigid/start`** / `https://cdn.sigid.org/v1/sigid.js` | Hand-rolled OAuth |
| React SPA | `@sigid/react` on `@sigid/client`, or start for static shells | Inventing vue/solid packages |
| Next.js App Router | `@sigid/next` (route handlers, cookies) | Copying Auth0 snippets blindly |
| Svelte SPA | `@sigid/svelte` | Missing README → use this page + package source |
| SvelteKit | `@sigid/sveltekit` (hooks/cookies) | Assuming `@sigid/vue` exists |
| Confidential server with own session | **`@sigid/backend`** (confidential exchange, ID-token verify, logout, webhooks) | Hand-rolling OAuth/OIDC |
| Server token validation only | `@sigid/client` `validateAccessToken` or backend SDKs | Trusting frontend “is logged in” |

**Integration layers:** start → framework adapter → `@sigid/client` for full protocol
control. Framework packages wrap the client for SSR/cookies; they do **not**
replace the drop-in script’s “two-line HTML” path. Use start when you only need
browser login UI without a build.

```html
<script src="https://cdn.sigid.org/v1/sigid.js"
  data-client-id="YOUR_CLIENT_ID"
  data-issuer="https://auth.sigid.org"></script>
<a href="#" data-sigid="login">Sign in</a>
```

## 3. Backend Token Validation

After login, APIs must validate the **access token**:

- signature (JWKS from discovery)
- `iss`, `aud`, `exp` / `nbf`
- `tenant_id` (or your deployment’s tenant claim)
- required `scope`
- allowed `subject_type` (`human`, `agent`, …)
- for delegated agents: `act` chain

See [Verify Access Tokens](verify-tokens.md) and
[Protect Backend APIs](protect-apis.md).

## 4. OpenAPI (What Is Public)

| Document | Where | Contents |
|---|---|---|
| **Public** | `GET /openapi.json` when `openapi.enabled=true` and `openapi.exposure=public`; also committed **`openapi-public.json`** | OIDC/OAuth protocol, health, capabilities, agent auth, public commerce buyer routes |
| **Internal** | Same path when `exposure=internal` | Full operator surface – **rejected in production** |

Do **not** expect production to expose control-plane, billing admin, or full
commerce manage schemas. For commerce integration paths, use
[Sell Access With SigID Commerce](commerce.md) and the workflow specs.

Discovery remains always public:

```text
GET {issuer}/.well-known/openid-configuration
```

Authorize endpoint is **`/oauth/authorize`** (not bare `/authorize`). Prefer the
SDK so you never hard-code it.

## 5. Webhooks

1. HTTPS receiver
2. Dashboard subscription + signing secret
3. Verify suite `sigid-webhook-v1` (HKDF-HMAC, timestamp, max-age, delivery id)
4. Idempotent handling

See [Receive Webhooks](webhooks.md).

## 6. Commerce (Optional)

If you sell access: payment link → public `/pay/{token}` → webhook grant in
**your** DB. Details: [Sell Access With SigID Commerce](commerce.md).

## 7. Agents And MCP

- Human-delegated tools: [Agent And MCP Auth](agents-mcp.md)
- Cold autonomous agent: [Agent Self-Serve Quickstart](agent-quickstart.md)

## Package Reality Check

**Published / in-repo today:** `@sigid/start`, `@sigid/client`, `@sigid/react`,
`@sigid/next`, `@sigid/svelte`, `@sigid/sveltekit`, `@sigid/backend`, `@sigid/cli`,
plus Go/Rust/Elixir under `sdks/`.

**Do not invent:** `@sigid/vue`, `@sigid/solid`, `@sigid/solidstart`, `@sigid/expo`,
`@sigid/electron` – they are not shipping packages. Use `@sigid/client` or start
until a first-party adapter exists.

## Done When

- [ ] Sign-in works: drop-in script/SDK for browser apps, or authorization-code+PKCE for confidential servers
- [ ] Logout clears app session
- [ ] Backend rejects invalid/missing tokens
- [ ] Redirect URI exact-match in Dashboard
- [ ] Webhooks verified if subscribed
- [ ] Commerce grants only after verified payment events (if selling)
- [ ] Secrets never logged or shipped to the browser

## Next Pages

| Goal | Page |
|---|---|
| Login details | [Add Login](add-login.md) |
| Framework pick | [SDKs And Examples](sdks-examples.md) |
| Tokens | [Verify Access Tokens](verify-tokens.md) |
| Commerce | [Sell Access With SigID Commerce](commerce.md) |
| OAuth reference | [OAuth And OIDC](../reference/oauth-oidc.md) |
| API map | [API And SDK Reference](../reference/api-sdk-reference.md) |
