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:
| Header | Description |
|---|---|
Authorization | Bearer <delegation-token> — the token issued during installation |
X-Request-Nonce | Unique string (UUID recommended). Must not be reused within 10 minutes. |
X-Request-Timestamp | ISO 8601 timestamp of request creation. Must be within ±5 min / +30s. |
X-Extension-Signature | Base64url-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 extensionsPOST /extensions/install— install an extension (creates delegation token)DELETE /extensions/:installationId— uninstall (revokes token)GET /extensions/:installationId— get installation detailsPUT /extensions/:installationId/permissions— update granted permissions/layers