What Are the API Endpoints for Bitchat? Understanding Nostr WebSocket Relays

Bitchat does not expose a traditional REST API; instead, all network communication flows through WebSocket connections to Nostr relay servers, with wss://relay.damus.io and wss://relay.primal.net as the built-in default endpoints.

Bitchat is a permissionless messaging application built on the Nostr protocol. Unlike conventional chat apps that rely on HTTP REST endpoints, Bitchat communicates entirely over WebSocket connections to distributed relay servers. This article examines the specific relay URLs that serve as Bitchat's API endpoints and how the source code manages these connections.

Built-In Default Relay Endpoints

The Bitchat source code hard-codes two default relay URLs in bitchat/Nostr/NostrRelayManager.swift (around line 157). These WebSocket endpoints function as Bitchat's primary API surface for publishing and receiving messages:

Relay WebSocket URL
Damus relay wss://relay.damus.io
Primal relay wss://relay.primal.net

These URLs are WebSocket secure (wss://) endpoints, not HTTP URLs. All message traffic—including event publication, feed subscriptions, and real-time message delivery—traverses these connections using the NIP-01 protocol specification.

How Bitchat Manages Relay Connections

The NostrRelayManager class abstracts WebSocket communication into higher-level Swift methods. When initialized, it constructs a merged list of default and user-configured relays, then manages connection lifecycle and message routing.

Core Manager Methods

  • sendEvent(_:to:) — Publishes a Nostr event to specified relays
  • ensureConnections(to:) — Establishes or reuses WebSocket connections to relay URLs
  • subscribe(to:) — Issues NIP-01 REQ messages for feed filtering

All Nostr messages follow strict JSON formats: EVENT for publishing, REQ for subscriptions, EOSE for end-of-stream signals, and OK for acknowledgments. The manager handles encoding, transmission, and response parsing internally.

Working with Relay Endpoints

Publishing to Default Relays

let manager = NostrRelayManager(...)
let event = NostrEvent(kind: 1, content: "Hello Nostr", tags: [])

// Dispatches to both damus.io and primal.net
await manager.sendEvent(event)

Targeting a Specific Custom Relay

let customRelay = "wss://relay.example.com"
await manager.sendEvent(event, to: [customRelay])

Pre-establishing Connections

let urls = ["wss://relay.damus.io", "wss://relay.primal.net"]
await manager.ensureConnections(to: urls)

Subscribing with Filters

let filter = NostrFilter(kinds: [1], authors: nil, tags: nil)
await manager.subscribe(to: filter)

Adding Custom Relay Endpoints

Users can extend Bitchat's API endpoints through the settings interface. The NostrRelaySettings class (in bitchat/Nostr/NostrRelaySettings.swift) handles:

  • URL normalization and validation
  • Persistence to UserDefaults
  • Support for .onion addresses for Tor connectivity

Custom relays are appended to the default list and treated identically by NostrRelayManager. This allows users to route traffic through private or regional relays without modifying source code.

Key Source Files

File Purpose
bitchat/Nostr/NostrRelayManager.swift Core WebSocket connection manager, default relay definitions, message dispatch
bitchat/Nostr/NostrRelaySettings.swift User relay configuration, URL validation, persistence layer
bitchat/Nostr/NostrProtocol.swift NIP-01 message type definitions and JSON codec

These three files constitute Bitchat's entire network API layer. No HTTP routes, no REST controllers, no GraphQL schema—just WebSocket connections to Nostr relays.

Summary

  • Bitchat API endpoints are WebSocket URLs, not HTTP endpoints
  • Default relays: wss://relay.damus.io and wss://relay.primal.net (hard-coded in NostrRelayManager.swift)
  • Protocol: NIP-01 over WebSockets with JSON message frames
  • Extensibility: Users add custom relays via NostrRelaySettings, including Tor .onion addresses
  • Implementation: Three Swift files handle all network communication across the Nostr network

Frequently Asked Questions

Does Bitchat have REST API endpoints?

No. Bitchat does not implement REST, HTTP, or GraphQL APIs. All server communication occurs through WebSocket connections to Nostr relay servers using the decentralized Nostr protocol.

Can I change which relays Bitchat connects to?

Yes. The app supports custom relay configuration through its settings interface. You can add any Nostr-compliant relay URL, including .onion addresses for Tor routing. These are stored via NostrRelaySettings and merged with the built-in defaults.

What protocol does Bitchat use for messaging?

Bitchat implements NIP-01, the foundational Nostr protocol specification. Messages are JSON objects transmitted over WebSocket connections, with message types including EVENT, REQ, EOSE, CLOSE, and OK for acknowledgment.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →