UBNet Public API

HTTP endpoints currently mounted by the UBNet backend. Paths are relative to the deployed API origin, for example https://my.eth-ub.net.

API version: 2.2.0 SDK version: 3.1.0 Docs version: 3.1.0
Current content model: top-level posts use explicit categories. Categories are set at creation and are immutable afterward. Server allow lists decide which categorized records enter the public post index and the main Feed.

Authentication

Public read routes require no challenge authentication. Write flows use signed SPASM events or a route-specific wallet challenge.

Base, health, and settings

MethodPathUse
GET/healthAPI/database health, API version, and indexer source metadata.
GET/api/versionStable API, SDK, and docs compatibility versions.
GET/api/settingsPublic settings currently exposed to clients.
GET/api/uploads/<relativePath>Static uploaded files such as profile and advertisement images.

Posts and reactions

MethodPathUse
GET/api/posts/feedPublic Feed. Supports limit, cursor, author, post_type, keyword, schema_name, schema_version, media_type, has_cid, and source_instance_host. Rows include server-derived title, preview, complete content, preview_truncated, and card_preview.media.
GET/api/posts/wallet/:walletTop-level posts by wallet. Supports limit, cursor, visibility, and include_private=true for posts hidden from browsing.
GET/api/posts/:idPost detail and first reply page.
GET/api/posts/:id/repliesCursor-paged replies for a post.
POST/api/posts/:id/accessCompatibility access endpoint. Current post reads are open.
GET/api/reactions/:idReaction counts for a post or list target.

The Feed ignores caller-supplied category filters and uses the server Feed category allow list. Use GET /api/events for category-scoped event discovery, or GET /api/events/top-by-category to rank categorized posts and lists by indexed likes.

Signed top-level post shape

{
  "action": "post",
  "schema": { "name": "ubnet-post", "version": "1.0.0" },
  "categories": [{ "name": "example-category" }],
  "post_type": "text",
  "content": "Hello UBNet",
  "post_visibility": "public"
}

At least one explicit category is required. No category is inferred or defaulted. Edit events use edit_of and must not attempt to replace the original categories.

Post media and thumbnails are immutable after creation. Edit events may change content and visibility while the indexer preserves the original media identity.

Profiles and social network

MethodPathUse
GET/api/users/searchSearch profiles with keyword and limit.
GET/api/users/:walletProfile fields, social links, aggregate counts, messaging metadata, and token-access refresh metadata. Use ?profile=business-profile or ?profile_name=business-profile to select a named profile.
GET/api/users/:wallet/followingWallets followed by this wallet.
GET/api/users/:wallet/followersFollowers for this wallet.
GET/api/users/:wallet/follow-exportExport follower/following data.

Named profile values are normalized to lowercase and must match [a-z0-9][a-z0-9_-]{0,63}. Dashes and underscores are accepted. An omitted name selects personal; an invalid value returns HTTP 400 with invalid_profile_name.

Messages and chats

MethodPathUse
GET/api/messages/chats/:walletCursor-paged chat list for a wallet. Supports limit, cursor, and search.
GET/api/messages/activityIncoming chat activity for a wallet.
GET/api/messages/chat-idResolve the deterministic direct-chat ID for two wallets.
GET/api/messages/profile/:walletCanonical messaging profile route.
GET/api/messages/profiles/:walletCompatibility alias for the messaging profile route.
GET/api/messages/key-backup/:walletEncrypted messaging-key recovery backup.
GET/api/messages/chat/:chat_id/stateChat state for participant/visibility checks.
GET/api/messages/chat/:chat_idChat metadata.
GET/api/messages/chats/:chat_id/messagesMessages in a chat.

Current messaging protocol: ubnet-e2ee-v2.

Current public-key prefix: ubnet-ecdh-p256-v2:.

Accepted indexed message encodings: aes-gcm-v2 and group-aes-gcm-v2. Plaintext and legacy message encodings are ignored by the current indexer.

Message rows expose signed created_at and unsigned indexer metadata server_received_at. Message ordering uses server_received_at first, with created_at as the legacy fallback.

Lists

The same router is mounted at both /api/lists and /api/collections. Use “Lists” in user-facing copy; the collection path remains a compatibility route.

MethodPathUse
GET/api/collections or /api/listsPublic list index. Supports limit, cursor, and keyword.
GET/api/collections/owner/:walletOwner list view with visibility filtering.
GET/api/collections/wallet/:walletPublic lists for a wallet.
GET/api/collections/:idList detail metadata.
GET/api/collections/:id/itemsItems for a list.
GET/api/collections/:id/items/:itemIdOne list item.
POST/api/collections/:id/unlock-challengeRequest the wallet message required to unlock a token-gated list.
POST/api/collections/:id/unlockVerify token access and unlock a list.
POST/api/collections/:id/items/:itemId/unlock-challengeRequest the wallet message required to unlock private item media.
POST/api/collections/:id/items/:itemId/unlockVerify token access and return a temporary private-media URL.

NFT galleries

MethodPathUse
GET/api/nft-galleries/editor/:walletEditor data for a wallet NFT gallery.
GET/api/nft-galleries/profile/:walletPublic NFT gallery for a profile.

Uploads

MethodPathUse
POST/api/uploads/avatar/challenge/:walletCreate a wallet challenge for avatar upload.
POST/api/uploads/avatar/:walletUpload an avatar after challenge signing.
POST/api/uploads/banner/challenge/:walletCreate a wallet challenge for banner upload.
POST/api/uploads/banner/:walletUpload a banner after challenge signing.
POST/api/uploads/pinata/presigned-urlOpen public Pinata URL route. Current backend intentionally returns a disabled error.
POST/api/uploads/pinata/token-gated-accessCheck token-gated upload access.
POST/api/uploads/pinata/token-gated-challengeCreate a wallet challenge for gated upload.
POST/api/uploads/pinata/token-gated-presigned-urlCreate a signed upload URL after wallet and token checks.

Public event queries

MethodPathUse
GET/api/eventsList public events using a query object or a numeric limit.
GET/api/events/:idRead one public event.
GET/api/events/summaryRead the public event summary.
GET/api/events/top-by-categoryRank categorized posts and lists by indexed likes.

Use /api/events?category=example-category&latest=true&wallet=0x... for filtered discovery. Supported query fields are limit, cursor, action, author, wallet, category, category_mode, schema_name, schema_version, post_type, source_instance_host, and latest=true.

Support, domain registration, ads, and reserved names

MethodPathUse
POST/api/support/contactCreate a support request.
GET/api/reserved-subdomains/checkCheck whether a normalized subdomain label is reserved.
POST/api/registrations/domain_registrationSubmit a signed domain-registration request.
GET/api/adsRead active ads where enabled.