> ## Documentation Index
> Fetch the complete documentation index at: https://www.floe.one/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Turn on request links

> Turn on request links for a self-hosted Floe server with a policy file, switch them off again without a restart, and keep the client and server on one version.

Request links are off on a [self-hosted](/docs/glossary#self-hosted) server until a policy file turns
them on. This page is for the person who runs the server. By the end, anyone whose Floe Desktop
points at your server can make a [request link](/docs/glossary#request-link), and you can switch them
off again without a restart.

<Info>
  Request links need the server and web client images at 1.11.0
  or later, and Floe Desktop 0.3.0 or later. Codes and [share links](/docs/glossary#share-link) work the same whether request
  links are on or off.
</Info>

<h2 id="the-short-version">
  The short version
</h2>

Put `{"requestLinks": true}` in a file, mount its folder into the server container, and name the
file in `POLICY_FILE`. The server reads the file every 60 seconds, so turning links off again is an
edit, not a restart. Unless your instance is on one domain, also tell every Floe Desktop that uses
it where your web app is.

<h2 id="request-links">
  Turn request links on
</h2>

These steps are for the [Docker Compose](/docs/glossary#docker-compose) stack. They need the
`docker-compose.yml` from v1.11.0 or later, which passes `POLICY_FILE` to the server. An older copy
leaves it out without a word, and `/health` keeps listing no features (see
[Moving to 1.11.0](/docs/self-hosting/operations#moving-to-1-11-0)). For a server run with Node directly,
see [Without Docker](#without-docker). On Unraid, the variable and the folder are both template
fields: see [Unraid](/docs/self-hosting/unraid#request-links).

<Steps>
  <Step title="Create the policy file">
    Next to `docker-compose.yml`:

    ```bash Terminal theme={"system"}
    mkdir -p policy
    echo '{"requestLinks": true}' > policy/policy.json
    ```

    The server runs as the unprivileged user `node`, not as root, so that user has to be able to
    read the folder and the file. A file it cannot read counts as unreadable, and request links stay
    off.
  </Step>

  <Step title="Mount the folder and name the file">
    In `docker-compose.yml`, uncomment the server's `volumes` example:

    ```yaml docker-compose.yml theme={"system"}
    volumes:
      - ./policy:/app/policy:ro
    ```

    Then, in `.env`:

    ```dotenv .env theme={"system"}
    POLICY_FILE=/app/policy/policy.json
    ```

    Mount the folder, not the file. Turning links on or off later puts a new file in place of the
    old one, and a mount of the single file keeps showing the old one.
  </Step>

  <Step title="Recreate the server and check">
    ```bash Terminal theme={"system"}
    docker compose up -d
    curl http://localhost:3001/health
    ```

    The answer lists `"features":["request-1"]`, and the server's log has one line,
    `request links: on`. If the log says `policy file not found, request links off` instead, the
    folder is not mounted or the path is wrong.
  </Step>

  <Step title="Point Floe Desktop at the web client">
    Floe Desktop builds each link from its **Share link address** setting. When that is blank, it
    builds the link from **Server address**, where `http://localhost:3001` becomes
    `http://localhost:3000` and any other address is used as it is. The link has to open your web
    client, which serves the page a sender sees. In Floe Desktop, open Settings and, under
    **Advanced**, expand **Server**, then set the field for your layout:

    | Your layout | Share link address |
    | - | - |
    | One domain, as in [Run behind one domain](/docs/self-hosting/reverse-proxy) | Leave it blank. |
    | The default Compose ports, with Floe Desktop on the same machine and **Server address** `http://localhost:3001` | Leave it blank. |
    | The default Compose ports, reached at any other address | The client's address, such as `http://<host>:3000`. |
    | Two hostnames, as in [Production deployment](/docs/self-hosting/production) | The client's address, such as `https://app.your-domain.com`. |

    Wherever the table says to fill it in, a link built from the server address opens a page the
    [signaling server](/docs/glossary#signaling-server) does not serve. Every Floe Desktop that uses
    your server needs this setting, so hand it out together with the server address. A link that
    is already open keeps the address it was made with.

    To check, choose **Receive**, then **Request link**, click **Make link**, and open the link in
    Chrome or Edge on a computer: the page reads "SEND FILES THROUGH THIS LINK".
  </Step>
</Steps>

<h3 id="without-docker">
  Without Docker
</h3>

A server started with Node reads `POLICY_FILE` from its environment, or from `server/.env` when you
start it from the `server/` folder. Put the file in any folder the server's user can read, and give
the absolute path:

```bash Terminal theme={"system"}
mkdir -p /srv/floe/policy
echo '{"requestLinks": true}' > /srv/floe/policy/policy.json
```

```dotenv server/.env theme={"system"}
POLICY_FILE=/srv/floe/policy/policy.json
```

Then restart the server and check `/health` as in step 3. The restart is needed only this once: the
server reads the path at startup, and the file's content every 60 seconds after that.

<h2 id="turn-request-links-on-or-off">
  Turn request links on or off later
</h2>

No restart is needed. Write the new content to a temporary file and rename it over the old one,
rather than editing the file in place, so the server never reads a half-written file:

```bash Terminal theme={"system"}
echo '{"requestLinks": false}' > policy/policy.json.tmp
mv policy/policy.json.tmp policy/policy.json
```

Then wait up to 60 seconds. The log says `request links: off` (or `request links: on`), and
`/health` follows.

Turning request links off ends every link that is waiting for a sender. Floe Desktop shows "Request
links are off on this server" on such a link, and a sender who tries it sees "Request links are
turned off right now".

Two kinds of link are left alone: one whose drop is under way, which is left to finish, and one
whose request is on its owner's screen or was declined. If the owner of a declined link then clicks
**Keep waiting** while links are off, that link ends too, with the same message. A server image of
version 1.11.0 or earlier leaves that link waiting with no sender able to reach it, until request
links are on again or the owner's Floe Desktop reconnects.

Turning them back on does not bring ended links back, so each owner makes a new link. A link that
was ended this way while its Floe Desktop was connected answers "This link has ended" for 24 hours.

<h3 id="how-the-server-reads-the-file">
  How the server reads the file
</h3>

* Only `true`, the JSON boolean, turns request links on. `"true"` in quotes, any other value, and a
  missing `requestLinks` key all mean off. Other keys are ignored.
* The server cannot use a file that it cannot read, that is not a JSON object, or that is larger
  than 64 KB. A folder or any other thing that is not a plain file at the path counts the same way.
* Then the server keeps its last good setting and logs `policy file unreadable, keeping previous
  policy` once, until the file reads cleanly again. A server that has read no good file since it
  started stays off.
* A missing file means off, even if request links were on. While a set `POLICY_FILE` stays missing,
  the server logs `policy file not found, request links off` once.
* UTF-8 works, and so does the UTF-16 that Windows PowerShell writes by default (little-endian,
  with a byte-order mark). Any other encoding, such as UTF-16 big-endian or UTF-16 without a mark,
  counts as unreadable.
* The path in `POLICY_FILE` is read once, when the server starts. Pointing it at another file takes
  `docker compose up -d`, or a restart without Docker.

<h2 id="request-link-limits">
  Limits
</h2>

The server keeps three counts, each per network or for the whole server. A network is one IPv4
address, or one IPv6 /64.

| Limit | Value |
| - | - |
| New links from one network | 20 in any 24 hours |
| Links open at once from one network | 10 |
| Links open at once on the whole server | 5,000 |

These limits are fixed in the server and have no setting. What Floe Desktop shows at each one is in
[What Floe Desktop shows](#what-floe-desktop-shows). A link that ends frees its place among the open
ones but still counts toward the 20, and a restart clears all three counts. Behind a
[reverse proxy](/docs/glossary#reverse-proxy), set `TRUSTED_PROXY_COUNT` to match it (see
[Configuration](/docs/self-hosting/configuration#trusted-proxy-count)), or every user counts as the same
network.

Two more fixed guards protect an open link. One connection can ask to join at most 30 times a
minute, and one link lets a sender connect at most 6 times in any minute. A request past the first
is dropped without an answer, and one past the second is answered as if the link were taken.
Neither is logged.

The limits a link's owner meets, such as how long a link lasts, are in
[Request links](/docs/desktop/request-links#limits).

<h2 id="matching-versions">
  Keep the client and server on one version
</h2>

The page a sender opens comes from the web client, not from the signaling server, so run the two
images at the same version. Compose does that by default, because `FLOE_IMAGE_TAG` picks both. An
older client in front of a newer server lets Floe Desktop make links whose page does not exist.

How the server holds a request link's [room](/docs/glossary#room) is described in
[Architecture](/docs/reference/architecture#request-rooms).

<h2 id="sending-to-a-link-on-your-server">
  Sending to a link on your server
</h2>

In a browser, a sender opens the link and nothing else is needed. See
[Sending through a request link](/docs/web-app/request-links) for what the page does and which browsers
it supports.

From the [CLI](/docs/glossary#cli), a sender has to name your signaling server as well as the link, with
`--server` or `FLOE_SERVER`. Without it the send ends with
`Couldn't connect to their computer. Nothing was sent.` before it contacts any server. See
[floe send](/docs/cli/send#send-through-a-request-link).

The page a sender opens shows **Report this link** only when you give the web client an address for
reports, in [`REQUEST_REPORT_EMAIL`](/docs/self-hosting/configuration#request-report-email): under
Compose, a line in `.env` and a `docker-compose.yml` from 1.11.1 or later (an older copy does not
pass the variable on), then `docker compose up -d`. The link then starts an email to that
address, carrying the link's id and never the part after the `#`. Without an address the page shows
no report link, so tell the people you share links with how to reach you. The variable needs a web
client newer than version 1.11.0: see
[What an older web app shows](/docs/self-hosting/operations#older-web-app-versions). The one switch you
have is the policy file, which ends every waiting link at once.

<h2 id="what-floe-desktop-shows">
  What Floe Desktop shows
</h2>

**Request link** always shows under **Receive** in Floe Desktop, whatever the server offers. The app
asks the server nothing until someone clicks **Make link**, which first checks that `/health` lists
`request-1` in its `features`.

| Message | What it means | What to do |
| - | - | - |
| “Request links are off on this server” | `/health` does not list `request-1`: there is no policy file, or the file says off. It also replaces an open link when you turn request links off. | Follow [Turn request links on](#request-links). |
| “This Floe server doesn't offer request links” | `/health` has no `features` list at all: the server is older than 1.11.0. Earlier versions of Floe Desktop said “Request links are off on this server” here. | Update the server, then [turn request links on](#request-links). |
| “This network reached today's link limit” | 20 links were made from that network in the last 24 hours. | Wait. The limit has no setting. |
| “Couldn't make a link” | The server could not be reached, that network already has 10 links open, or the server holds 5,000. | Run **Test** under Settings, then close links that are no longer needed. |

Every other message on a link's own screen is in
[Request links](/docs/desktop/request-links#messages-on-your-pc).

## If something goes wrong

* A link opens a page that is not Floe's send page: **Share link address** is blank, or names the
  signaling server, where step 4 says to fill it in. See
  [The link opens a page that is not Floe's send page](/docs/troubleshooting#the-link-opens-a-page-that-is-not-floes-send-page).
* **Make link** answers "Request links are off on this server": see
  [Request links are off on this server](/docs/troubleshooting#request-links-are-turned-off-on-this-server).
* **Make link** answers "This Floe server doesn't offer request links": the server predates them. See
  [This Floe server doesn't offer request links](/docs/troubleshooting#this-floe-server-doesnt-offer-request-links).
* A sender sees "Their computer is not connected right now" after you restarted the server: see
  [Their computer is not connected right now](/docs/troubleshooting#their-computer-is-not-connected-right-now).


## Related topics

- [Troubleshooting: fixes by error message](/docs/troubleshooting.md)
- [Request links: let someone send files to your PC](/docs/desktop/request-links.md)
- [Self-hosting overview](/docs/self-hosting/overview.md)
- [Day-to-day operations](/docs/self-hosting/operations.md)
- [Use a self-hosted server](/docs/cli/self-hosted-server.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.