30817:image-proxy-list
Image Proxy List
This NIP defines a list of image proxies that a user would like clients to use when fetching images on their behalf.
Fetching images directly from their original hosts exposes the user's IP address to every host and often wastes bandwidth on full-size originals. Publishing a list of preferred proxies lets the user choose who sees their requests once, and have every client respect it.
Event
A kind:15734 replaceable event holds one or more proxy tags. Tags are ordered by preference, with the most preferred proxy first.
["proxy", "<url-template>", "<flag>", ...]
{
"kind": 15734,
"content": "",
"tags": [
["proxy", "https://imgproxy.example.com/insecure/rs:fit:{width}:{height}[/f:{format}]/{url_b64}", "resize", "format=image/webp,image/avif,image/png"],
["proxy", "https://wsrv.nl/?url={url}[&w={width}][&h={height}][&output={format}]", "resize", "format"],
["proxy", "https://simple-proxy.example.com/?u={url}"]
],
// other fields...
}
URL templates
A URL template is a URL containing placeholders in curly braces. Clients build the proxied URL by replacing each placeholder with its value. Substitution is plain string replacement: there are no escapes, expressions or nested placeholders. Placeholder names consist of lowercase a-z, 0-9 and _.
The following placeholders are always available:
| Placeholder | Value |
|---|---|
{url} |
The original image URL, percent-encoded (as with encodeURIComponent) |
{url_b64} |
The original image URL, base64url-encoded (RFC 4648 §5) without padding |
A template MUST contain exactly one of {url} or {url_b64}.
Additional placeholders become available through feature flags. If a template contains a placeholder the client does not know, or a placeholder whose flag is not listed in the tag, the client MUST NOT use that proxy.
Optional sections
Square brackets [ ] mark an optional section of the template. A section is included (without its brackets) only if the client has a value for every placeholder inside it. Otherwise the whole section is removed.
For example, given the template:
https://wsrv.nl/?url={url}[&w={width}][&h={height}][&output={format}]
A client that only wants to resize the image to a width of 300 pixels produces:
https://wsrv.nl/?url=https%3A%2F%2Fexample.com%2Fcat.jpg&w=300
Placeholders outside of an optional section are required. If the client can't provide a value for one of them, it MUST NOT use that proxy.
Optional sections MUST NOT be nested and MUST contain at least one placeholder. Literal [ and ] characters are not allowed anywhere else in a template (use a hostname instead of an IPv6 literal).
Feature flags
Elements after the template are feature flags. Each flag declares a capability of the proxy and makes a set of placeholders available to the template. A proxy that lists a flag MUST use that flag's placeholders in its template. Clients MUST ignore unknown flags.
resize
Adds {width} and {height}: the target size in pixels, as integers.
The proxy SHOULD scale the image to fit within the given box, preserve its aspect ratio, and not upscale it.
When the placeholders are inside optional sections the client can omit either dimension. When the proxy's URL format requires both (as in the imgproxy example above), the client MUST provide both and uses 0 for a dimension it does not want to constrain.
format
Adds {format}: the image format the proxy should re-encode the image to.
{format} is replaced with the lowercase MIME subtype of the requested format, for example webp for image/webp or jpeg for image/jpeg.
The flag MAY include a comma-separated list of the MIME types the proxy can encode to:
"format=image/webp,image/avif,image/png"
A bare format flag means the supported formats are unknown. The list only declares output formats. It does not describe which input formats can be converted into which output formats.
If the proxy can't produce the requested format for a given image it MUST respond with a 4xx or 5xx HTTP status code.
Client behavior
Clients SHOULD pick the first proxy in the list that supports the features they need. A proxy without any flags can still be used to fetch images unmodified.
If a request to a proxy fails, clients SHOULD try the next suitable proxy in the list. If every proxy fails, clients MAY fetch the original URL directly. Since that reveals the user's IP address to the original host, clients SHOULD let the user decide whether to fall back.
Clients SHOULD NOT proxy data: or blob: URIs, URLs whose scheme is not http or https, or URLs that already point to the chosen proxy.
A resized or re-encoded image will not match the hash of the original file, so clients SHOULD NOT verify NIP-B7 hashes against proxied responses.
Security considerations
The proxy operator can see every image the user loads through it. Clients SHOULD only send images through proxies the user has chosen.
Cited links
Discussion
Connect a key to comment.