Nostr is an open protocol, not a website: posts are signed JSON events stored on independent relays, and anyone can read public events by asking a relay over a WebSocket. On 2 October 2026 we sent 33 requests to Nostr surfaces from the US, Germany, Brazil and the UK. Nothing blocked us. What changed was cost: the same public identity weighed 99 bytes as a NIP-05 lookup, 182 KB as an njump profile page and 1.1 MB as a rendered Primal profile. A proxy on Nostr is mostly about privacy and geography, not access.
What people search for
Google has no autocomplete for "nostr proxies", and "nostr scraper" completes to nose-care products. "nostr api" is the useful one: it completes to "nostr rest api", "nostr build api", "nostr band api" and "nostr relay api". The US results page for "nostr proxies" has no proxy-provider page at all. It has a fan-in relay proxy on GitHub, NIP-48 (which uses "proxy" tags for events bridged in from other networks), a Rust proxy-relay crate that filters spam, a Reddit thread asking whether relays see your IP address, a Nostr VPN app, Wikipedia and nostr.com. The related searches are "Nostr proxies free", "Nostr proxies list", "Nostr proxies iphone" and "Nostr security".
So "proxy" means three different things to Nostr users: a relay that aggregates other relays, a tag on bridged content, and a network proxy that hides your IP address from the relays you connect to. This post is about the third one, and about what a data team sees when it reads public Nostr content over HTTP.
Where public Nostr data lives
Nostr has no central site. There are three kinds of surfaces:
- Relays. Servers that store and forward events. You read them by opening a WebSocket and sending a REQ with a filter (authors, kinds, time range, limit), as defined in NIP-01. The same URL answers plain HTTP: a browser gets a small HTML page, and a request with the header
Accept: application/nostr+jsongets the NIP-11 relay information document. - Web gateways. Sites such as njump.me that turn an npub or a note id into an ordinary HTML page, so links work in a browser and in search engines.
- Web clients. Full apps such as Primal's web client, which load a JavaScript bundle and then pull data from their own services.
Plus one tiny HTTP endpoint that matters a lot: NIP-05, the /.well-known/nostr.json?name= file that maps a human-readable address like [email protected] to a public key.
What each surface served to a proxied client
We used the public profile of Jack Dorsey (npub1sg6p...), a public figure and a known Nostr supporter, and one of his public notes. All proxied requests went through residential exits.
| Request (2 October 2026) | Exit | Result | Bytes |
|---|---|---|---|
| njump profile, plain HTTP | US | 200, 1st attempt, 11.8 s, Cloudflare cache hit | 181,837 |
| njump profile, plain HTTP | Germany | 200, 1st attempt, 9.8 s | 181,692 |
| njump profile, no-JS audit | Brazil | 502 Bad gateway | n/a |
| njump profile, plain HTTP retry | Brazil | 200, origin took 8.2 s | 181,837 |
| njump profile, rendered | US | 200, 27.1 s, same title and canonical | 61,434 |
| njump profile, audit with and without JS | US | 200 both, 1,254 vs 1,235 words | n/a |
| njump note page, plain HTTP | UK | 200, 1.4 s, cached for 7 days | 32,367 |
| Primal profile, plain HTTP | US | 200, app shell, 11 words | 5,680 |
| Primal profile, rendered | US | 200, 24.1 s, still 11 words of text captured | 1,098,459 |
| NIP-05 lookup on primal.net | US | 200 JSON, 1.1 s | 99 |
| relay.damus.io, plain HTTP | US | 200, HTML relay page | 6,996 |
| NIP-11 document, relay.damus.io | direct | 200 JSON, 0.37 s | 430 |
| NIP-11 document, nos.lol | direct | 200 JSON, 0.25 s | 458 |
| NIP-11 document, relay.primal.net | direct | 200 JSON, 0.34 s | 497 |
| nostr.band site, API and relay | US and direct | no response on 6 attempts | 0 |
The NIP-11 requests were sent directly, without a proxy, because they need a custom Accept header; we note it so the table is honest about where each number came from.
Four things stand out. First, no surface challenged us: no CAPTCHA, no JavaScript check, no 403 on any of the 33 requests. Second, the one error was a 502 from njump's origin in Brazil, followed by a clean 200 on retry with the origin taking 8.2 seconds. That is a busy gateway building the page from relays, not a block. Third, njump serves real HTML: the profile page has the name, bio, NIP-05 address, the relays the user publishes to and links to recent notes, and rendering adds nothing except 15 seconds. Fourth, Primal's web client is a single-page app. Without JavaScript you get a 5.7 KB shell with the name and bio in the meta tags; with JavaScript the browser pulled 1.1 MB and our capture still held only the shell text, because the app fetches the feed from its own service after the page loads.
The real limits are published by each relay
Relays do not hide their rules behind a bot wall. NIP-11 lets each relay describe itself in a small JSON document, including a limitation block. The three we read on 2 October 2026:
| Relay | max_limit (events per request) | max_subscriptions | max_message_length | Size |
|---|---|---|---|---|
| relay.damus.io | 500 | 200 | 1,000,000 | 430 B |
| nos.lol | 500 | 20 | 131,072 | 458 B |
| relay.primal.net | 500 | 20 | 1,000,000 | 497 B |
All three run the same open-source relay software, and all three cap a single request at 500 events. nos.lol describes itself as accepting notes "except spammy ones" and links a terms-of-service page in the document. The point for anyone collecting public notes is simple: read the NIP-11 document first, keep your subscriptions under the published cap, page by time with until, and stop when the relay sends CLOSED or NOTICE. Spreading one job over many IP addresses to get past a relay's published limit is exactly the behaviour relays write those limits to prevent, and we do not recommend it.
What the gateways and clients say about robots and terms
njump's robots.txt (277 bytes) allows everything to every user agent except seven named crawlers, which it blocks completely: Amazonbot, SemrushBot, meta-externalagent, DataForSeoBot, dotbot, MJ12bot and PetalBot. Its pages carry long cache lifetimes (five hours on profiles, seven days and "immutable" on notes), which tells you the operator expects them to be fetched and cached, not hammered.
primal.net has no robots.txt: the path returns the same 5,204-byte app shell as every other URL, from the US and from Germany. Primal's Terms of Use live at primal.net/terms, but that page is also part of the app, and neither our plain nor our rendered fetches captured the text. If you plan to automate anything against primal.net itself, read those terms in a browser first. For public notes you do not need Primal's site at all: the same signed events are on the relays, including Primal's own public relay.
Relays are run by individuals and small companies, and each one sets its own policy. Some are free and open, some require payment or authentication (NIP-11 has payment_required and auth_required flags for that), and some reject spam aggressively. Treat the NIP-11 document and any linked terms as the rules for that relay. You can check any site's robots.txt against your crawler's user agent with our ../../tools/robots-txt-tester/.
What changes by country
Almost nothing in the content. The njump profile was 181,837 bytes from the US and Brazil and 181,692 from Germany; the small difference is the list of recent notes changing between requests, not localisation. Titles, descriptions and canonicals were identical. Primal's shell was byte-identical from the US and Germany. The differences we did see were operational: Cloudflare cache state (a hit in the US, expired in Germany, a miss in Brazil) and therefore speed, from 1.4 seconds for a cached note to 11.8 seconds for a profile the origin had to build.
Geography matters more at the network level. Wikipedia notes that Damus was removed from the Chinese App Store two days after launch in 2023, and that some users in China reach Nostr through VPNs. Whether a given relay is reachable from a given country is a fair question to test, and a country-targeted exit is how you test it.
Where a proxy actually helps on Nostr
| Job | Proxy type | Notes |
|---|---|---|
| Keep your home or office IP address away from the relays your client connects to | Residential or ISP, one stable address | Relays see the connecting IP, which is the question in the top Reddit result |
| Check whether relays and gateways are reachable and fast from a given country | Residential, country-targeted | Measure the NIP-11 document and an njump page per country; both are tiny |
| Run your own brand or project account from a consistent address | Static ISP | Consistency, not scale; your key is your identity, not your IP |
| Collect public notes on a topic or from known public accounts | Usually none needed | Read relays directly within their NIP-11 limits; add an exit only if your network is the problem |
| Monitor njump or relay pages for SEO or link previews | Residential, plain HTTP | No JavaScript needed on njump; render only adds time |
Every proxied request above used ../../residential-proxies/. We did not test mobile or datacenter exits in this run and make no claim about them. For a single account or a self-hosted client that should always appear from the same place, ../../isp-proxies/ gives you one fixed address. What a proxy does not do on Nostr is protect your identity: every note is signed by your key, so a new IP address does not make you a new person, and creating many keys to amplify content is the spam pattern Wikipedia describes and relays filter.
What it costs
Nostr is cheap to read if you pick the right surface. Take 1,000 public profiles checked once:
- As njump pages: 1,000 x 181,837 B = about 182 MB, which at $0.80/GB on Residential Basic is about $0.15.
- As rendered Primal pages: 1,000 x 1,098,459 B = about 1.1 GB, about $0.88, and 24 seconds per page.
- As NIP-05 checks only (does this address still point to this key?): 1,000 x 99 B = under 0.1 MB, a fraction of a cent.
A daily NIP-11 check of 50 relays from three countries is 150 x about 460 B, roughly 69 KB a day and about 2 MB a month. The lesson from the bars at the top of this post: the gateway page costs about 1,800 times the JSON lookup, and the rendered client about six times the gateway page. Pick the smallest surface that answers your question.
If what you need is a page fetched as structured text without managing exits yourself, our ../../web-scraping-api/ does plain HTTP first and renders only when a page needs it, which on njump it does not. For other open and decentralised networks, see our measurements on ../bluesky-proxies/ and ../mastodon-proxies/.