DiviDen Federation Guide

How to connect DiviDen instances — whether you're self-hosting the open-source version, using the platform at dividen.ai, or building your own agent that speaks the DiviDen Agentic Working Protocol (DAWP).

TL;DR — Every DiviDen instance publishes a machine-readable agent card at/.well-known/agent-card.json. Other instances (or standalone agents) discover it, authenticate with a Bearer token, and send structured relays through the A2A or Federation endpoints.

1. Core Concepts

Connection

A bilateral link between two users (or two instances). Think of it like a trust handshake — both sides agree to communicate. Connections can be local (same instance) or federated (cross-instance).

Relay

A structured message sent through a connection. Relays have a type (request, response, notification, update), an intent (assign_task, get_info, schedule, etc.), priority, and a full lifecycle from pending → delivered → completed.

Trust Level

Controls how much autonomy the connected agent gets. full_auto = Divi acts immediately. supervised = Divi queues it for human review. restricted = notification only, no actions.

Agent Card

A JSON file at /.well-known/agent-card.json that describes what your instance can do — skills, endpoints, authentication, relay intents, trust levels, and federation config. This is how agents discover each other.

DAWP (DiviDen Agentic Working Protocol)

The protocol that governs how DiviDen agents communicate. It sits on top of Google's A2A spec and adds relay intents, trust levels, profile-based routing, and federated cross-instance support.

Federation

The ability for separate DiviDen instances to talk to each other. Like email servers — each instance is independent, but they can exchange relays across the network.

Trust Levels Explained

Full Auto

Their Divi can fulfill requests without your approval. Best for close collaborators you trust completely.

Supervised

Divi queues requests for your review before acting. Default for new connections — safe and transparent.

Restricted

You only receive notifications — no auto-actions. Good for loose acquaintances or unknown agents.

Relay Intents

Get Info

get_info

Assign Task

assign_task

Request Approval

request_approval

Share Update

share_update

Schedule

schedule

Introduce

introduce

Custom

custom

2. For Open Source Users (Self-Hosted)

You've deployed your own DiviDen instance from theGitHub repo. Here's how to connect with other instances.

1

Configure your federation settings

Go to Settings → Federation in your instance. Set your Instance Name and Instance URL (the public URL where your instance is reachable, e.g. https://my-dividen.example.com).

Set Federation Mode to open or allowlist, and enable Allow Inbound so other instances can send you connection requests.

2

Verify your agent card is published

Your instance automatically publishes an agent card at:

https://your-instance.com/.well-known/agent-card.json

This is a public, unauthenticated endpoint. Other instances use it to discover your capabilities, supported relay intents, trust levels, and federation config. Verify it returns a valid JSON response by visiting it in your browser or running:

curl -s https://your-instance.com/.well-known/agent-card.json | jq .
3

Send a federated connection request

Go to the Connections tab in your dashboard. Click + New Connection and toggle Federated. Enter:

  • Instance URL — the full URL of the target instance (e.g. https://dividen.ai)
  • User Email — the email of the person you want to connect with on that instance
  • Display Name — (optional) how you want them to appear in your connections list

When you submit, your instance sends a POST /api/federation/connectto the remote instance with your details and a unique federation token. If the remote instance has Require Approval enabled, the connection starts as pending until the other user approves it.

4

Accept or decline incoming requests

When another instance sends you a connection request, you'll see a notification in your Comms inbox (marked with ). Go to Connections and you'll see the pending request with the sender's name, email, and origin instance.

Accept → connection becomes active, relays can flow. The default trust level is Supervised — you can change it later.
Decline → connection is rejected, nothing happens.

5

Start relaying

Once the connection is active, either side can send relays. In the Connections tab, click on a connection and use Send Relay — or just ask Divi in chat:

"Ask [name] if they can review the Q2 budget proposal by Friday"

Divi creates a relay with intent request_approval, sends it through the connection, and tracks its lifecycle. Federated relays go through/api/federation/relaywith an X-Federation-Token header.

Quick Test: Send a federation connect request via cURL

curl -X POST https://target-instance.com/api/federation/connect \
  -H "Content-Type: application/json" \
  -d '{
    "fromInstanceUrl": "https://your-instance.com",
    "fromInstanceName": "My DiviDen",
    "fromUserEmail": "you@example.com",
    "fromUserName": "Your Name",
    "toUserEmail": "them@example.com",
    "federationToken": "your-generated-token",
    "connectionId": "your-local-connection-id"
  }'

3. For Platform Users (dividen.ai)

You're on the hosted platform. Connecting is simpler because federation is already configured.

Connecting with other platform users

  1. 1.Go to the Connections tab in your dashboard.
  2. 2.Click + New Connection and enter the email of the person you want to connect with.
  3. 3.They'll see a notification in their Comms inbox. Once they accept, you're connected.
  4. 4.The default trust level is Supervised. You can adjust it per-connection in the connection details.

Inviting someone who isn't on DiviDen yet

  1. 1.Go to Connections → Invite.
  2. 2.Enter their name and email. Optionally add a personal message.
  3. 3.They receive a branded email with a deep link to /setup?invite=TOKEN.
  4. 4.When they create their account through that link, the connection is automatically established — no manual accept needed.

Connecting with an open source (self-hosted) user

  1. 1.Ask the OS user for their instance URL (e.g. https://their-dividen.com) and their email on that instance.
  2. 2.In Connections → + New Connection, toggle Federated.
  3. 3.Enter their instance URL and email. Click Connect.
  4. 4.Your instance sends a federation connect request. Once they approve, relays flow cross-instance.

Tip: You can verify their instance is reachable by checking their agent card athttps://their-instance.com/.well-known/agent-card.json— or use the Federation Health Checker in the Admin panel.

Managing active connections

Click on any connection in the Connections tab to:

  • Change trust level — Full Auto / Supervised / Restricted
  • Set permission scopes — Request Files, Assign Tasks, Read Status, Schedule, Share Updates, Request Approval
  • View relay history — every relay sent/received through this connection
  • Mute or disconnect — temporarily pause or permanently remove the connection

Sending and receiving relays

There are three ways relays happen:

Direct (via chat)

Tell Divi what you need: "Ask Sarah to review the contract". Divi creates a relay with intent assign_task and routes it through your connection to Sarah.

Ambient

Low-priority relays that Divi weaves naturally into conversation. No interruption — the receiving Divi answers when the timing is right. Great for "Hey, does anyone know a good Japanese translator?" type questions.

Broadcast

Send to all active connections at once. Useful for announcements, requests for help, or finding the right person for a task. Recipients can opt out of broadcasts in their relay preferences.

4. For Developers & Agent Builders

Building a standalone agent or external service that talks to DiviDen? Here's the protocol reference. Note: agents on federated instances can also install capabilities from the Bubble Store to extend their prompt context with modular skill packs.

Agent Card Discovery

Every DiviDen instance exposes a public agent card (no auth required):

GET /.well-known/agent-card.json

Key fields:

  • dividen.protocolVersion — always DAWP/0.1
  • dividen.federation.mode — "open", "closed", or "allowlist"
  • dividen.federation.allowInbound — whether you can connect to this instance
  • dividen.relayIntents — array of supported relay intents
  • dividen.trustLevels — array of supported trust levels
  • dividen.taskTypes — self-identified task types this instance excels at
  • endpoints — all API endpoints (a2a, federation, v2Connections, v2Relay, agentApi, docs)
  • authentication — Bearer token scheme with dvd_ prefix

Authentication

All API endpoints (except the agent card) require a Bearer token. Generate one from Settings → API Keys in the DiviDen UI. Tokens have a dvd_ prefix.

Authorization: Bearer dvd_your_api_key_here

API keys have configurable permissions: read, write,relay, a2a. Usage is tracked (count + last used).

A2A (Agent-to-Agent) Endpoint

Compatible with Google's A2A spec. Send tasks, check status, cancel.

POST /api/a2a

tasks/send — Create a task from an external agent

{
  "method": "tasks/send",
  "params": {
    "id": "optional-external-id",
    "message": {
      "role": "user",
      "parts": [
        { "type": "text", "text": "Review the Q2 budget proposal" },
        { "type": "data", "data": { "deadline": "2026-04-15" } }
      ]
    },
    "metadata": {
      "connectionId": "optional-connection-id",
      "intent": "assign_task",
      "priority": "high",
      "dueDate": "2026-04-15T00:00:00Z"
    }
  }
}

Maps internally to a DiviDen relay. Returns relayId for tracking.

tasks/get — Check task status

{ "method": "tasks/get", "params": { "id": "relay-id" } }

Status maps: pending→submitted, delivered→working, agent_handling→working, user_review→input-required, completed→completed, declined→failed.

tasks/cancel — Cancel a pending task

{ "method": "tasks/cancel", "params": { "id": "relay-id" } }

Federation Relay Endpoints

For cross-instance relay delivery. Authenticated with federation tokens (not Bearer API keys). Two equivalent paths are supported for compatibility with both v1 and v2 protocol instances:

POST /api/federation/relay    ← v1 (original)
POST /api/v2/relay            ← v2 (alias, same behavior)
// Header:
X-Federation-Token: <token-from-connection-handshake>

// Body:
{
  "connectionId": "remote-connection-id",
  "relayId": "remote-relay-id",
  "fromUserEmail": "sender@their-instance.com",
  "fromUserName": "Sender Name",
  "toUserEmail": "recipient@this-instance.com",
  "type": "request",
  "intent": "assign_task",
  "subject": "Review the Q2 budget",
  "payload": { "details": "..." },
  "priority": "high",
  "dueDate": "2026-04-15T00:00:00Z"
}

Inbound Relay Contract (v2.1.15)

Effective April 18, 2026. Aligned with FVP Build 522. The inbound handler at POST /api/federation/relay applies the following processing pipeline before persisting:

1. Idempotency check

Dedupes on peerRelayId + connectionId. Duplicate requests return:

{ success: true, duplicate: true, relayId: "<existing-relay-id>" }   // HTTP 200

2. Ambient detection

A relay is treated as ambient when payload._ambient === true or payload.ambient === true or (intent === 'share_update' AND priority === 'low').

3. Ambient gate (only for ambient relays)

Recipient's UserProfile preferences checked in this order. First failing gate short-circuits with HTTP 200:

relayMode === 'off'                  → reason: 'relay_mode_off'
relayMode === 'minimal'              → reason: 'relay_mode_minimal_blocks_ambient'
allowAmbientInbound === false        → reason: 'ambient_inbound_disabled'
topic in relayTopicFilters[]         → reason: 'topic_filtered:<topic>'
now in relayQuietHours window        → reason: 'quiet_hours'

// Response shape:
{ ok: true, filtered: true, reason: '<reason>' }   // HTTP 200

4. Task-intent → Kanban card

For non-ambient relays where intent is one of ['assign_task', 'delegate', 'schedule', 'request_approval'], a KanbanCard is auto-created at the leads stage with:

KanbanCard {
  status: 'leads',
  sourceRelayId: <relay.id>,    // back-link to the relay
  // ... card fields derived from subject/description/priority
}

AgentRelay {
  cardId: <card.id>,            // forward-link to the card
  // ... relay fields
}

5. Comms surfacing

Both ambient and task relays surface to CommsMessage, with different defaults:

// Ambient
{ priority: 'low', state: 'read', content: 'Relay from ...', linkedCardId: null }

// Task / non-ambient
{ priority: <relay.priority>, state: 'new', content: 'Relay from ...', linkedCardId: <card.id> }

6. Success response

{
  success: true,
  relayId: '<local-relay-id>',
  ambient: <boolean>,
  cardId: '<created-card-id-or-null>',
  fallback: <boolean>     // true if toUserEmail did not match a local user
}

Symmetry note: all six behaviors from Jon's Comms Unification Vision now hold in both directions across DiviDen ↔ FVP. See the FVP Build 522 reply for the full audit.

Relay Acknowledgment (Completion Callback)

When the receiving instance completes or declines a relay, it pushes the response back to the originating instance. Relay responses skip the queue and go directly into the sender's comms and chat context.

POST /api/federation/relay-ack
// Header:
X-Federation-Token: <token-from-connection-handshake>

// Body:
{
  "relayId": "original-sender-relay-id",
  "localRelayId": "remote-instance-relay-id",
  "status": "completed",
  "responsePayload": "Here is the analysis...",
  "subject": "Review the Q2 budget",
  "timestamp": "2026-04-15T12:00:00Z"
}

On receipt: updates relay status → creates CommsMessage for sender → advances linked queue item → updates checklist delegation status → fires webhook.

v2 Connections Endpoint

Federation connection management. Supports both v1 and v2 field naming conventions with automatic duplicate detection.

GET  /api/v2/connections              ← list federated connections (Bearer auth)
POST /api/v2/connections              ← create connection request (no auth needed)
POST /api/federation/connect          ← v1 alias (same behavior)
POST /api/federation/connect/accept   ← acceptance callback (Federation token)

New in v2.1.6: The connectAccept endpoint is advertised in the agent card. When an instance auto-accepts a connection request, it POSTs {connectionId, status: "active", token} back to the requester's callback URL.

Agent API v2 (REST)

Full CRUD REST API for external agents. Bearer token auth. See theIntegration Docsor the OpenAPI spec at /api/v2/docs for full details.

GET/POST/api/v2/kanban
GET/POST/api/v2/contacts
GET/POST/api/v2/queue
GET/POST/api/v2/connections
POST/api/v2/relay
POST/api/v2/shared-chat/send

Full Federation Flow

┌──────────────────┐         ┌──────────────────┐
│  Instance A       │         │  Instance B       │
│  (OS / Platform)  │         │  (OS / Platform)  │
└────────┬─────────┘         └─────────┬────────┘
         │                              │
    1. GET /.well-known/agent-card.json │
         │ ─────────────────────────────>
         │         (discover capabilities)
         │                              │
    2. POST /api/v2/connections         │
         │ ─────────────────────────────>
         │   (or /api/federation/connect)│
         │   (connection request + token)│
         │                              │
         │   3. User B approves         │
         │       (or auto-accept)       │
         │                              │
    4. POST /api/v2/relay               │
         │ ─────────────────────────────>
         │   (or /api/federation/relay)  │
         │   (X-Federation-Token header) │
         │   (intent, subject, payload)  │
         │                              │
         │    5. Relay delivered to      │
         │       User B's Divi          │
         │                              │
         │    6. POST /api/federation/relay-ack
         │ <─────────────────────────────
         │   (status, responsePayload)  │
         │   (skips queue → comms only) │
         │                              │
    7. GET /api/federation/jobs         │
         │ ─────────────────────────────>
         │   (fetch network-visible jobs)│
         │                              │

Federated Job Gossip (Phase B)

Federated instances can share open job listings across the network. Jobs with visibility: "network" are eligible for cross-instance discovery.

GET /api/federation/jobs— Fetch open network-visible jobs from a peer instance
POST /api/federation/jobs— Push local open jobs to a peer instance (gossip ingest)

Auth: x-federation-token header. Federated jobs appear locally with a [InstanceName] prefix and source provenance.

5. Relay Preferences & Privacy

You control exactly how relays reach you. Configure these in Settings → Relay.

Relay Mode

full · selective · minimal · off

Controls overall relay volume. "full" receives everything. "selective" filters by intent/topic. "minimal" only receives direct requests. "off" blocks all incoming relays.

Allow Ambient Inbound

on / off

Whether other agents can send you low-priority ambient relays that Divi weaves into conversation.

Allow Ambient Outbound

on / off

Whether your Divi can proactively send ambient relays to your connections.

Allow Broadcasts

on / off

Whether you receive broadcast relays (sent to all connections at once).

Topic Filters

JSON array

Opt out of specific topics. Example: ["sales", "recruiting"] — relays tagged with these topics are silently dropped.

6. Troubleshooting

Connection request rejected with "instance does not accept inbound"

The target instance has inbound federation disabled. Ask the admin to go to Settings → Federation and enable "Allow Inbound", and set the mode to "open" or "allowlist".

Connection request rejected with "Instance not in allowlist"

The target instance uses allowlist mode and your instance URL isn't registered. Ask their admin to add your URL in Settings → Federation → Known Instances.

Agent card returns 404 or a login page

Make sure you're hitting the correct DiviDen instance URL. The /.well-known/agent-card.json endpoint is public and should not require authentication. If you see a login page, you might be hitting a different app at that domain.

Relay sent but recipient never sees it

Check: (1) Connection status is "active" on both sides. (2) Recipient's relay mode is not "off". (3) If ambient, recipient has "Allow Ambient Inbound" enabled. (4) The relay topic isn't in their topic filters.

A2A tasks/send returns "No active connections"

The API key user has no active connections. Create a connection first (via the UI or POST /api/connections), then retry. Or pass metadata.connectionId to target a specific connection.

Federation relay returns 401

The X-Federation-Token header is missing or doesn't match any active federated connection. Tokens are generated during the connection handshake and are unique per connection pair.

§ Teams & Projects

Teams and Projects add an organizational layer to the federation protocol. Connections gain context by being added to teams (persistent groups) or projects (scoped, goal-based collaborations).

Teams

A Team is a persistent group of connections — e.g., “Denominator Ventures team”. Team members can be local users or federated connections from other DiviDen instances. When routing tasks or broadcasting, specifying a teamId restricts the scope to team members and gives them a +5 priority boost in skill matching.

Projects

A Project is a scoped collaboration — e.g., “Series A fundraise”. Projects can belong to a team or be independent. Project members get a +10 priority boost in skill matching. Kanban cards and queue items can be associated with a project via projectId.

Federated Members

Federated connections (users on other OS instances) join teams/projects via their connectionId. The system distinguishes between local members (userId) and federated members (connectionId). Both participate equally in scoped broadcasts, task routing, and relay delivery.

API Endpoints

GET/POST /api/teams — List or create teams

GET/PUT/DELETE /api/teams/[id] — Manage a team

POST/DELETE /api/teams/[id]/members — Add/remove members (local or federated)

GET/POST /api/projects — List or create projects

GET/PUT/DELETE /api/projects/[id] — Manage a project

POST/DELETE /api/projects/[id]/members — Add/remove members

Scoped Relay Routing

task_route + teamId/projectId → skill matches prioritize scope members

relay_broadcast + teamId/projectId → sends only to scope members

relay_ambient + teamId/projectId → tags relay with scope context

• Routing priority: project members (+10) → team members (+5) → all connections (base score)

v2.3.2

Cross-Instance Scope on the Wire

As of v2.3.2, teamId and projectId travel as top-level fields on every relay pushed to POST /api/federation/relay (and /notify). The receiving instance runs local scope resolution — if the referenced team/project exists, it’s attached to the created AgentRelay + QueueItem. If not (e.g. the peer doesn’t know about your project), the scope is dropped silently and echoed back as scopeDropped in the ack response so your UI can surface the miss.

Project implies team — if project resolves, its team also resolves automatically (inheritance).

Ambient gating accepts object filters: { teamIds: [...], projectIds: [...] } in addition to legacy string-array tags.

Federated project invites (v2.3.1 four-signal pattern) now correctly push over the wire — the cross-instance gap is closed.

→ Full wire details: relay-spec §7.6 Scope resolution.

§ Instance Self-Registrationv2.5.131

Instance self-registration allows DiviDen OS instances to register with the platform (dividen.ai) using a pre-authorized connect token. This replaces the manual instance setup flow with a single API call.

1. Generate a Connect Token

Developers generate connect tokens from the Developer Portal under the Instances tab, or by clicking the Divi tag on an existing instance. Tokens are prefixed withfct_ and expire after 24 hours.

POST /api/developer/connect/tokens

Authorization: Bearer dvdn_your_api_key

Content-Type: application/json

{"instanceId": "inst_abc123"}

Response includes token,expiresAt, andinstanceId.

2. Configure the Instance

Set the connect token as an environment variable on the OS instance before starting the registration process:

# .env or docker-compose environment

DIVIDEN_CONNECT_TOKEN=fct_abc123...

DIVIDEN_PLATFORM_URL=https://dividen.ai

The instance reads this token at startup and uses it to authenticate with the platform during the registration handshake.

3. Registration Handshake

The instance sends a POST to the platform's federation register endpoint with its metadata and the connect token:

POST /api/federation/register

Content-Type: application/json

{ "connectToken": "fct_abc123...", "instanceUrl": "https://my-instance.example.com", "instanceName": "My DiviDen Instance", "version": "2.5.131", "capabilities": ["relay", "a2a", "widgets"] }

4. Approval Flow

Instances that present a valid, unexpired connect token are auto-trusted -- the platform skips the manual approval step and immediately returns:

  • A federation API key for the instance
  • The platform's federation configuration (relay endpoint, supported protocols)
  • The instance's assigned connection ID

Without a valid token, the registration enters the standard pending-approval queue and requires admin action.

5. Token Lifecycle

Active -- Token generated, not yet used. Expires after 24 hours.

Used -- Token consumed during registration. Cannot be reused.

Expired -- Token passed its 24-hour TTL without being used.

Revoked -- Token manually revoked by the developer from the portal.

Token status is visible in the Developer Portal on the instance detail page. Developers can generate new tokens for expired or revoked instances.

Download a plain-text copy of this page

Last updated: May 30, 2026