The SwarmAPI Reference

Swarm API Reference

Public Endpoints

GET /api/swarm/users/[handle]

Returns a user’s profile and recent posts. Used by other nodes to display remote user profiles.

Query Parameters:

  • limit (number, default: 25, max: 50) - Max posts to return

Response:

{
  "profile": {
    "handle": "alice",
    "displayName": "Alice",
    "bio": "Building cool stuff",
    "avatarUrl": "https://cdn.example.com/avatar.jpg",
    "headerUrl": "https://cdn.example.com/header.jpg",
    "website": "https://alice.dev",
    "followersCount": 150,
    "followingCount": 75,
    "postsCount": 342,
    "createdAt": "2024-01-15T12:00:00Z",
    "isBot": false,
    "nodeDomain": "example.synapsis.social"
  },
  "posts": [
    {
      "id": "abc123",
      "content": "Hello world!",
      "createdAt": "2024-01-20T15:30:00Z",
      "isNsfw": false,
      "likesCount": 12,
      "repostsCount": 3,
      "repliesCount": 5,
      "media": [
        {
          "url": "https://cdn.example.com/image.jpg",
          "mimeType": "image/jpeg",
          "altText": "A photo"
        }
      ],
      "linkPreviewUrl": "https://example.com/article",
      "linkPreviewTitle": "Article Title",
      "linkPreviewDescription": "Article description",
      "linkPreviewImage": "https://example.com/og-image.jpg"
    }
  ],
  "nodeDomain": "example.synapsis.social",
  "timestamp": "2024-01-20T16:00:00Z"
}

GET /api/swarm/timeline

Returns recent public posts from this node for the swarm-wide timeline.

Query Parameters:

  • limit (number, default: 20, max: 50) - Max posts to return

Response:

{
  "posts": [
    {
      "id": "abc123",
      "content": "Hello from this node!",
      "createdAt": "2024-01-20T15:30:00Z",
      "author": {
        "handle": "alice",
        "displayName": "Alice",
        "avatarUrl": "https://...",
        "isNsfw": false
      },
      "nodeDomain": "example.synapsis.social",
      "nodeIsNsfw": false,
      "isNsfw": false,
      "likeCount": 12,
      "repostCount": 3,
      "replyCount": 5,
      "media": [],
      "linkPreviewUrl": null
    }
  ],
  "nodeDomain": "example.synapsis.social",
  "nodeIsNsfw": false,
  "timestamp": "2024-01-20T16:00:00Z"
}

GET /.well-known/synapsis-swarm

Returns this node’s swarm information and known nodes.

Query Parameters:

  • nodes (boolean, default: true) - Include list of known nodes
  • limit (number, default: 50, max: 200) - Max nodes to return

Response:

{
  "node": {
    "domain": "example.synapsis.social",
    "name": "Example Node",
    "description": "A Synapsis node",
    "publicKey": "-----BEGIN PUBLIC KEY-----...",
    "softwareVersion": "0.1.0",
    "capabilities": ["handles", "gossip"]
  },
  "swarm": {
    "totalNodes": 42,
    "activeNodes": 38,
    "totalUsers": 1250,
    "totalPosts": 15000,
    "seeds": ["node.synapsis.social"]
  },
  "nodes": [
    {
      "domain": "other.synapsis.social",
      "name": "Other Node",
      "lastSeenAt": "2024-01-15T12:00:00Z"
    }
  ]
}

GET /api/swarm/info

Returns this node’s swarm information.

Query Parameters:

  • stats (boolean) - Include swarm statistics

Response:

{
  "domain": "example.synapsis.social",
  "name": "Example Node",
  "description": "A Synapsis node",
  "publicKey": "-----BEGIN PUBLIC KEY-----...",
  "softwareVersion": "0.1.0",
  "userCount": 150,
  "postCount": 2500,
  "capabilities": ["handles", "gossip"]
}

GET /api/swarm/nodes

Returns list of known swarm nodes.

Query Parameters:

  • limit (number, default: 100, max: 500) - Max nodes to return
  • stats (boolean) - Include swarm statistics

Response:

{
  "nodes": [
    {
      "domain": "node1.synapsis.social",
      "name": "Node One",
      "userCount": 100,
      "postCount": 1500,
      "lastSeenAt": "2024-01-15T12:00:00Z"
    }
  ],
  "stats": {
    "totalNodes": 42,
    "activeNodes": 38,
    "totalUsers": 1250,
    "totalPosts": 15000
  }
}

POST /api/swarm/announce

Receive an announcement from another node.

Request Body:

{
  "domain": "new-node.synapsis.social",
  "name": "New Node",
  "description": "A new Synapsis node",
  "publicKey": "-----BEGIN PUBLIC KEY-----...",
  "softwareVersion": "0.1.0",
  "userCount": 10,
  "postCount": 50,
  "capabilities": ["handles", "gossip"],
  "timestamp": "2024-01-15T12:00:00Z"
}

Response: Returns this node’s info (same format as request).


POST /api/swarm/gossip

Exchange node and handle information with another node.

Request Body:

{
  "sender": "other-node.synapsis.social",
  "nodes": [
    {
      "domain": "node1.synapsis.social",
      "name": "Node One",
      "lastSeenAt": "2024-01-15T12:00:00Z"
    }
  ],
  "handles": [
    {
      "handle": "alice",
      "did": "did:key:z6Mk...",
      "nodeDomain": "node1.synapsis.social",
      "updatedAt": "2024-01-15T12:00:00Z"
    }
  ],
  "timestamp": "2024-01-15T12:00:00Z",
  "since": "2024-01-14T00:00:00Z"
}

Response:

{
  "nodes": [...],
  "handles": [...],
  "received": {
    "nodes": 5,
    "handles": 25
  }
}

Admin Endpoints

POST /api/swarm/nodes (Admin)

Trigger swarm operations. Requires admin authentication.

Actions:

Announce to Seeds

{ "action": "announce" }

Announce to Specific Node

{ "action": "announce", "domain": "target-node.com" }

Discover a Node

{ "action": "discover", "domain": "new-node.com" }

Run Gossip Round

{ "action": "gossip" }

Gossip with Specific Node

{ "action": "gossip", "domain": "target-node.com" }

Add Seed Node

{ "action": "addSeed", "domain": "new-seed.com", "priority": 50 }

Database Schema

swarm_nodes

ColumnTypeDescription
iduuidPrimary key
domaintextNode domain (unique)
nametextDisplay name
descriptiontextNode description
logo_urltextLogo URL
public_keytextNode’s public key
software_versiontextSynapsis version
user_countintegerNumber of users
post_countintegerNumber of posts
discovered_viatextHow we found this node
discovered_attimestampWhen discovered
last_seen_attimestampLast successful contact
last_sync_attimestampLast gossip sync
consecutive_failuresintegerFailed contact attempts
is_activebooleanCurrently reachable
trust_scoreintegerReputation (0-100)
capabilitiestextJSON array of capabilities

swarm_seeds

ColumnTypeDescription
iduuidPrimary key
domaintextSeed domain (unique)
priorityintegerConnection order (lower = first)
is_enabledbooleanWhether to use this seed
last_contact_attimestampLast successful contact
consecutive_failuresintegerFailed contact attempts

swarm_sync_log

ColumnTypeDescription
iduuidPrimary key
remote_domaintextNode we synced with
directiontext’push’ or ‘pull’
nodes_receivedintegerNodes received
nodes_sentintegerNodes sent
handles_receivedintegerHandles received
handles_sentintegerHandles sent
successbooleanWhether sync succeeded
error_messagetextError if failed
duration_msintegerSync duration

Interaction Endpoints

These endpoints enable direct node-to-node social interactions with instant delivery.

GET /api/swarm/posts/[id]

Returns a single post with author info.

Response:

{
  "id": "abc123",
  "content": "Hello world!",
  "createdAt": "2024-01-20T15:30:00Z",
  "author": {
    "handle": "alice",
    "displayName": "Alice",
    "avatarUrl": "https://...",
    "isNsfw": false
  },
  "nodeDomain": "example.synapsis.social",
  "isNsfw": false,
  "likesCount": 12,
  "repostsCount": 3,
  "repliesCount": 5,
  "media": [],
  "linkPreviewUrl": null,
  "replyToId": null,
  "repostOfId": null
}

POST /api/swarm/interactions/like

Receive a like from another swarm node.

Request Body:

{
  "postId": "uuid-of-target-post",
  "like": {
    "actorHandle": "bob",
    "actorDisplayName": "Bob",
    "actorAvatarUrl": "https://other-node.com/avatar.jpg",
    "actorNodeDomain": "other-node.com",
    "interactionId": "unique-uuid",
    "timestamp": "2024-01-20T15:30:00Z"
  },
  "signature": "base64url-encoded-ecdsa-signature"
}

Response:

{
  "success": true,
  "message": "Like received"
}

POST /api/swarm/interactions/unlike

Receive an unlike from another swarm node.

Request Body:

{
  "postId": "uuid-of-target-post",
  "unlike": {
    "actorHandle": "bob",
    "actorNodeDomain": "other-node.com",
    "interactionId": "unique-uuid",
    "timestamp": "2024-01-20T15:30:00Z"
  },
  "signature": "base64url-encoded-ecdsa-signature"
}

Response:

{
  "success": true,
  "message": "Unlike received"
}

POST /api/swarm/interactions/repost

Receive a repost notification from another swarm node.

Request Body:

{
  "postId": "uuid-of-target-post",
  "repost": {
    "actorHandle": "bob",
    "actorDisplayName": "Bob",
    "actorAvatarUrl": "https://other-node.com/avatar.jpg",
    "actorNodeDomain": "other-node.com",
    "repostId": "uuid-of-repost-on-actors-node",
    "interactionId": "unique-uuid",
    "timestamp": "2024-01-20T15:30:00Z"
  },
  "signature": "base64url-encoded-ecdsa-signature"
}

Response:

{
  "success": true,
  "message": "Repost received"
}

POST /api/swarm/interactions/follow

Receive a follow from another swarm node.

Request Body:

{
  "targetHandle": "alice",
  "follow": {
    "followerHandle": "bob",
    "followerDisplayName": "Bob",
    "followerAvatarUrl": "https://other-node.com/avatar.jpg",
    "followerBio": "Hello, I'm Bob",
    "followerNodeDomain": "other-node.com",
    "interactionId": "unique-uuid",
    "timestamp": "2024-01-20T15:30:00Z"
  }
}

Response:

{
  "success": true,
  "message": "Follow received"
}

POST /api/swarm/interactions/unfollow

Receive an unfollow from another swarm node.

Request Body:

{
  "targetHandle": "alice",
  "unfollow": {
    "followerHandle": "bob",
    "followerNodeDomain": "other-node.com",
    "interactionId": "unique-uuid",
    "timestamp": "2024-01-20T15:30:00Z"
  }
}

Response:

{
  "success": true,
  "message": "Unfollow received"
}

POST /api/swarm/interactions/mention

Receive a mention notification from another swarm node.

Request Body:

{
  "mentionedHandle": "alice",
  "mention": {
    "actorHandle": "bob",
    "actorDisplayName": "Bob",
    "actorAvatarUrl": "https://other-node.com/avatar.jpg",
    "actorNodeDomain": "other-node.com",
    "postId": "uuid-of-post-with-mention",
    "postContent": "Hey @alice@this-node.com check this out!",
    "interactionId": "unique-uuid",
    "timestamp": "2024-01-20T15:30:00Z"
  }
}

Response:

{
  "success": true,
  "message": "Mention received"
}

POST /api/swarm/replies

Receive a reply from another swarm node.

Request Body:

{
  "postId": "uuid-of-parent-post",
  "reply": {
    "id": "uuid-of-reply-on-senders-node",
    "content": "Great post!",
    "createdAt": "2024-01-20T15:30:00Z",
    "author": {
      "handle": "bob",
      "displayName": "Bob",
      "avatarUrl": "https://other-node.com/avatar.jpg"
    },
    "nodeDomain": "other-node.com",
    "mediaUrls": []
  }
}

Response:

{
  "success": true,
  "replyId": "uuid-of-created-reply"
}

GET /api/swarm/replies

Get replies to a post on this node.

Query Parameters:

  • postId (required) - UUID of the post

Response:

{
  "replies": [
    {
      "id": "reply-uuid",
      "content": "Great post!",
      "createdAt": "2024-01-20T15:30:00Z",
      "author": {
        "handle": "bob@other-node.com",
        "displayName": "Bob",
        "avatarUrl": "https://..."
      },
      "likesCount": 2,
      "repostsCount": 0,
      "repliesCount": 1
    }
  ],
  "nodeDomain": "this-node.com"
}