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 relaysensureConnections(to:)— Establishes or reuses WebSocket connections to relay URLssubscribe(to:)— Issues NIP-01REQmessages 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
.onionaddresses 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.ioandwss://relay.primal.net(hard-coded inNostrRelayManager.swift) - Protocol: NIP-01 over WebSockets with JSON message frames
- Extensibility: Users add custom relays via
NostrRelaySettings, including Tor.onionaddresses - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →