Register a Connector

Documentation

Register a Connector

One registration for apps and sources — client auth, source declarations, scopes

Updated July 4, 2026

Register a Connector with Dialogues

A Connector is the single registration object for anything that brings data into, or uses data from, a person's Topos. It replaces the old split between "apps" and "sources": a connector has an optional client facet (auth: PKCE or client secret, redirect URIs) and an optional sources facet (data contracts: schema, parser, delivery). Your app_id from the old model is your connector_id — nothing is renamed.

Before any user clicks Attach Dialogues, your connector must exist in the registry with the right policy. Skipping scopes, sources, or redirect setup is the most common reason attach fails.

Next: Add Dialogues auth

Section A — Decide what you're building

Answer two questions; they decide which facets you configure:

  1. Does it bring data into a Topos?

- The owner uploads files or types entries themselves → sources facet only, delivery: owner_upload (or owner_ui). No auth configuration, ever. - Your software pushes data → sources facet with delivery: client_push plus a client facet (Section B).

  1. Does it read data?

- A person reading a friend's datastop — no connector needed. The owner shares directly from Topos → Sharing (permission ticket → approval → token). - An app or service → client facet with read scopes. Sources facet may be empty (read-only services write nothing back).

ConfigurationExampleFacets
Owner-mediated data inCSV export uploadsources only
Software pushes databrowser extensionclient + sources
Read-only servicesimulations appclient only

Checkpoint: You know which facets your connector needs.

Section B — Choose client shape (client facet only)

Use the Integration Modes table in Tutorial 2 — Add Dialogues auth to pick your auth path. When registering, set client_auth_mode to match:

  1. Browser extensionintegration_profile: chrome_extension, client_auth_mode: public_pkce
  2. Web or mobile with backendintegration_profile: web, client_auth_mode: client_secret_required (issue cas_* in App Sheaf)
  3. Public SPA or mobile without backendpublic_pkce with PKCE in the client
  4. legacy_none — local dev only; not for production

Checkpoint: Your registry row matches the Integration Mode you will follow in Tutorial 2.

Section C — Declare sources and scopes before registration

  1. Write your allowed_scopes list (what Grant Access may request). Examples: activity:write, activity:read.
  2. Declare every source you will write. Each declaration carries source_id, schema, and

delivery (owner_upload | owner_ui | local_sync | client_push). Every source_id must be an active source that already exists on the platform (public catalog or your organization's created sources) — do not invent new source IDs here. Examples: browser_visits, browser_events, starred_websites.

  1. If you need a new stream, create and activate the source first (see

Tutorial 3 — Create sources), then declare it on your connector.

  1. Register first, validate at ingest: at app_ingest time the payload source_id must

be declared on your connector. Undeclared sources are logged today and will be rejected once enforcement is on (CONNECTOR_SOURCE_ENFORCEMENT=enforce).

Checkpoint: Scope list and source declarations are written down.

Section D — Register in App Sheaf (recommended)

  1. Open App SheafConnectorsCreate. The wizard walks the Section A decision

tree: intent → data path → client shape → source declarations.

  1. Enter connector_id (your stable app_id) and display name.
  2. Owner-mediated connectors go straight to the source wizard — no auth steps are shown.
  3. Software-push and read-only connectors configure the client facet: integration profile,

auth mode, redirect URIs, scopes.

  1. For Chrome extension: enable automatic per-install redirect registration if you distribute unpacked/dev builds.
  2. Save. Confirm the connector shows public_pkce when the profile is Chrome extension.

Checkpoint: Connector appears in Sheaf; production public clients are not left on legacy_none.

Section E — Register via Control Plane API

POST /v1/connectors is the primary endpoint. (POST /v1/apps still works as a deprecated alias with identical behavior — responses carry Deprecation/Sunset headers.)

curl -sS -X POST "https://cp.logu3s.com/v1/connectors" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "connector_id": "my-extension",
    "name": "My Extension",
    "active": true,
    "integration_profile": "chrome_extension",
    "client_auth_mode": "public_pkce",
    "extension_redirect_auto_register": true,
    "allowed_scopes": ["activity:write"],
    "sources": [
      { "source_id": "browser_visits", "delivery": "client_push" }
    ],
    "allowed_redirect_uris": []
  }'
  1. Requires owner or admin bearer token.
  2. If you omit client_auth_mode, the default may be legacy_none — set public_pkce explicitly for public clients.
  3. sources[] declarations keep allowed_source_ids in sync automatically (and vice versa

for legacy writes). Each declared source_id must refer to an existing, active source.

  1. Add or update declarations later with POST /v1/connectors/{connector_id}/sources;

remove one with DELETE /v1/connectors/{connector_id}/sources/{source_id} (declaration only — never deletes ingested data).

  1. Confirm with GET /v1/connectors/{connector_id}.

Checkpoint: API response shows the facets and declarations from Sections A–C.

Section F — Redirect URIs (client facet)

  1. Web apps: Add exact callback URLs to allowed_redirect_uris at create/edit time. They must match the redirect_uri you send on /connect byte-for-byte.
  2. Extension (load unpacked / GitHub): Each install gets a new chrome.runtime.id. Register redirects per install via POST /v1/apps/{app_id}/extension-install/redirects. This registers chrome-extension://<id>/… and https://<id>.chromiumapp.org/.
  3. Extension (Chrome Web Store): One fixed extension ID for all users. Register that ID once in Sheaf or via the redirect API; pin it in metadata if supported.
  4. Optional erk_*: Third-party extensions can issue an extension register key (POST /v1/apps/{app_id}/extension-register-key/issue) and send X-Topos-Extension-Register-Key on redirect registration. Store erk_* in private build config — not in public GitHub. Do not rely on any special-case behavior of the reference browser-history-plugin for your own app_id.

Checkpoint: Redirect strategy matches how you ship the client (web vs unpacked vs store).

Section G — Verify registration

curl -sS "https://cp.logu3s.com/v1/connectors/my-extension" \
  -H "Authorization: Bearer $TOKEN"
  1. Confirm facets shows the shape you intended ({"client": true, "sources": true} for a data-pushing app).
  2. Confirm client.client_auth_mode is public_pkce (or client_secret_required for confidential web) via GET /v1/connectors/{connector_id}/client-auth.
  3. Compare allowed_scopes and sources[] to Section C; each declared source must still map to an active source.

Checkpoint: Ready for Tutorial 2 — Add Dialogues auth.

Reference — browser-history-plugin

FieldValue
connector_idbrowser-history-plugin
Facetsclient (public_pkce, chrome_extension) + sources
Sourcegithub.com/dialoguesai/browser-history-plugin
Scopesactivity:write
Declared sourcesbrowser_visits, browser_events, starred_websites (all client_push)

Reference implementation: github.com/dialoguesai/browser-history-plugin.