Skip to content

Extension API

Extensions are third-party services that connect to a tulpa agent to provide additional functionality (e.g., scheduling assistants, CRM integrations, network analysis tools). They operate under a strict delegation model: the owner grants an extension specific permissions and layer access, and the extension acts within those bounds.

Key Concepts

  • Extension Manifest: A JSON declaration of what the extension does, what it needs and how to reach it. Submitted to the marketplace for review before listing.
  • Installation: A per-user binding between an extension and a tulpa agent. Creates a scoped grant of permissions and layer access.
  • Delegation Token: A signed credential issued to an installed extension, proving it has been authorized by the owner. Signed with the agent’s Ed25519 private key.
  • Request Signing: Every API call from an extension carries the extension’s own Ed25519 signature over the request, binding it to a specific method, path, nonce and timestamp.
  • Autonomy Tiers: Control how much freedom an extension has — from fully autonomous (“transactional”) to owner-must-approve (“personal”).
  • Dunbar Layers: Extensions only see contacts in the layers the owner granted. A scheduling extension might see your “active” network but never your “inner” circle.

Request Flow

Extension Tulpa API (/ext/v1/*)
| |
| Authorization: Bearer <delegation-token>
| X-Request-Nonce: <uuid>
| X-Request-Timestamp: <iso8601>
| X-Extension-Signature: <ed25519-sig>
| ─────────────────────────────────► |
| |
| extension-auth middleware: |
| 1. Verify token Ed25519 sig |
| 2. Check token not expired |
| 3. Hash token, verify hash |
| matches installation |
| 4. Check installation active|
| 5. Check timestamp ±5 min |
| 6. Check nonce not replayed |
| 7. Verify request signature |
| (extension's Ed25519 key)|
| |
| ◄───── JSON response ──────────── |

Authentication

All /ext/v1/* routes use the extensionAuth middleware. Required headers on every request:

HeaderDescription
AuthorizationBearer <delegation-token> — the token issued during installation
X-Request-NonceUnique string (UUID recommended). Must not be reused within 10 minutes.
X-Request-TimestampISO 8601 timestamp of request creation. Must be within ±5 min / +30s.
X-Extension-SignatureBase64url-encoded Ed25519 signature over the request message.

Delegation Token Payload

{
"installationId": "uuid",
"extensionId": "com.example",
"ownerTulpaId": "tulpa:z...",
"permissions": ["connections:list", "layers:read"],
"layers": ["active", "sympathy"],
"maxAutonomyTier": "social",
"expiresAt": "2026-06-01T00:00:00Z",
"issuedAt": "2026-03-01T00:00:00Z"
}

Request Signature

The signature message is: method + "\n" + path + "\n" + nonce + "\n" + timestamp + "\n" + bodyHash where bodyHash is hex(SHA-256(requestBody)).

Public keys are encoded as multibase (base58btc, z prefix).

Extension API Endpoints — /ext/v1/*

All endpoints require extension auth. Permission checks are enforced per-endpoint. Layer filtering is applied automatically.

Connections

GET /ext/v1/connections

List connections visible to this extension, filtered by granted Dunbar layers.

Permission: connections:list

GET /ext/v1/connections/:contactId

Get a specific connection. Returns 404 if the contact is not in a granted layer.

Permission: connections:list

Dunbar Layers

GET /ext/v1/layers

Get all layer assignments, filtered to granted layers.

Permission: layers:read

GET /ext/v1/layers/:contactId

Get the layer assignment for a specific contact.

Permission: layers:read

Network Health

GET /ext/v1/health

Network health diagnostic. Layer-level health scores are filtered to granted layers only.

Permission: layers:read

Decaying Contacts

GET /ext/v1/decaying

Contacts at risk of relationship decay, filtered by granted layers.

Permission: layers:read

Graph Intelligence

GET /ext/v1/clusters

Network clusters. If the extension has graph:read:clusters:summary but not graph:read:clusters:members, member lists are stripped.

Permission: graph:read:clusters:summary (required), graph:read:clusters:members (optional)

GET /ext/v1/bridges

Bridge risk assessments — contacts who serve as sole connectors between clusters.

Permission: graph:read:bridges

Events

GET /ext/v1/events

Poll for events since a sequence number.

Permission: events:subscribe

Query params: since (sequence number), limit (max events, default 100)

Profile

GET /ext/v1/profile

Get the owner’s public profile snapshot.

Permission: profile:read

Intents

POST /ext/v1/intents

Send an intent on behalf of the owner. Subject to autonomy tier checks and layer access. The to field must reference a contact in the extension’s granted layers.

Permission: intents:send

Audit Log

GET /ext/v1/audit

Get the extension’s own audit log entries. Scoped to the calling installation automatically.

Query params: limit (default 50, max 200), offset

Agent API Endpoints

Agent Card — GET /agents/:agentId/agent.json

Fetch an agent’s public Agent Card — the discovery/capability document.

Inbox — POST /agents/:agentId/inbox

Deliver a signed intent to an agent’s inbox. Rate limited to 60 requests/minute per IP. Messages carry Ed25519 signatures in the envelope.

Marketplace API

GET /marketplace/extensions

Search or browse listed extensions. Public, no auth required.

Query params: q (search query, min 2 chars), limit (default 20, max 50)

GET /marketplace/extensions/:extensionId

Get full extension details including manifest, publisher and review stats.

POST /marketplace/submit

Submit a new extension for review. Requires owner auth.

Owner Extension Management

Routes under /api/tulpa/extensions/* for managing installed extensions:

  • GET /extensions — list installed extensions
  • POST /extensions/install — install an extension (creates delegation token)
  • DELETE /extensions/:installationId — uninstall (revokes token)
  • GET /extensions/:installationId — get installation details
  • PUT /extensions/:installationId/permissions — update granted permissions/layers