LocalSend Protocol Documentation

repository·main·Indexed 19 days ago

https://github.com/localsend/protocol

A lightweight, serverless REST protocol for peer-to-peer file transfers on local networks. Version 2.1 supports device discovery via Multicast UDP and HTTP, and features two transfer modes: an Upload API (receiver hosts the server) and a Download API (sender hosts the server). Includes specifications for network configuration, API endpoints, error codes, and device type enums.

Tokens
3.9K
Snippets
9
Records
20
Agent score
66%

What's inside LocalSend Protocol

  1. LocalSend Protocol v2.1 Overview

    main
    The LocalSend Protocol is a simple REST-based protocol designed for peer-to-peer file transfers without relying on external servers. It uses multiple methods for discovery (Multicast UDP and HTTP) and two primary transfer modes: Upload API (receiver hosts the server) and Download API (sender hosts the server).
  2. How device fingerprints work

    main

    Fingerprints are used to uniquely identify devices within the protocol:

    • When using HTTPS: The fingerprint is the SHA-256 hash of the certificate.
    • When using HTTP: The fingerprint is a random string.

    Note that in many registration and discovery payloads, the fingerprint field is ignored if the protocol is set to https.

  3. Discover devices using Multicast UDP

    main

    To discover other members on the network, a device sends an announcement message to the multicast group.

    Announcement Payload Send the following JSON structure to the multicast group:

    {
      "alias": "Nice Orange",
      "deviceModel": "Samsung", // nullable
      "deviceType": "mobile", // mobile | desktop | web
      "fingerprint": "random string",
      "announcement": true
    }

    Handling Responses When a device receives an announcement where announcement is true, it will respond in one of two ways:

    1. HTTP/TCP (Primary): A POST request to /api/localsend/v1/register.
    2. Multicast/UDP (Fallback): A UDP message sent back to the group with announcement: false.

    Note: The fingerprint field is used to prevent a device from discovering itself.

    {
      "alias": "Nice Orange",
      "deviceModel": "Samsung",
      "deviceType": "mobile",
      "fingerprint": "random string",
      "announcement": true
    }
  4. Download files via Reverse HTTP (Receiver Client)

    main

    When the receiver cannot act as an HTTP server, the sender sets up an HTTP server and provides a URL for the receiver to download files via a browser.

    Note: This uses unencrypted HTTP because browsers reject self-signed certificates.

    1. Browser URL

    The receiver opens: http://<sender_ip>:<sender_port>

    2. Prepare Download

    To get the list of available files, the downloader sends a request to the sender.

    Endpoint: POST /api/localsend/v2/prepare-download (Optional: Add ?sessionId=<sessionId> to resume/refresh a specific session).

    Response Body:

    {
      "info": {
        "alias": "Nice Orange",
        "version": "2.0",
        "deviceModel": "Samsung",
        "deviceType": "mobile",
        "fingerprint": "random_string",
        "download": true
      },
      "sessionId": "mySessionId",
      "files": {
        "file_id_1": {
          "id": "file_id_1",
          "fileName": "image.png",
          "size": 324242,
          "fileType": "image/jpeg",
          "sha256": "hash",
          "preview": "data"
        }
      }
    }

    3. Receive File

    Download the actual binary data.

    Endpoint: GET /api/localsend/v2/download?sessionId=<sessionId>&fileId=<fileId>

    Response Body: Raw binary data.

  5. Use the Upload API to send files

    main

    The Upload API is the default file transfer method where the receiver hosts the HTTP server and the sender uploads files.

    1. Preparation (Metadata Only)

    Before sending, the sender must POST metadata to the receiver to get permission and session tokens.

    Endpoint: POST /api/localsend/v2/prepare-upload Query Param: Add ?pin=123456 if a PIN is required.

    Request Body:

    {
      "info": { /* device info */ },
      "files": {
        "file_id_1": {
          "id": "file_id_1",
          "fileName": "image.png",
          "size": 1024,
          "fileType": "image/png"
        }
      }
    }

    Response:

    {
      "sessionId": "mySessionId",
      "files": {
        "file_id_1": "file_token_1"
      }
    }

    2. Send File

    Once you have the sessionId, fileId, and token, perform the actual binary upload.

    Endpoint: POST /api/localsend/v2/upload?sessionId=mySessionId&fileId=file_id_1&token=file_token_1 Body: Binary data

    3. Cancel

    To abort a session: Endpoint: POST /api/localsend/v2/cancel?sessionId=mySessionId

    {
      "sessionId": "mySessionId",
      "files": {
        "someFileId": "someFileToken"
      }
    }
  6. Discover devices via UDP Multicast

    main

    To discover other members, an application sends a multicast message to the UDP multicast address. Other members respond with their device information.

    Announcement Payload An announcing device sends a JSON payload containing its identity and capabilities:

    {
      "alias": "Nice Orange",
      "version": "2.0",
      "deviceModel": "Samsung",
      "deviceType": "mobile",
      "fingerprint": "random_string",
      "port": 53317,
      "protocol": "https",
      "download": true,
      "announce": true
    }

    Responses Responding members can reply in two ways:

    1. HTTP/TCP Request: Sending a POST /api/localsend/v2/register to the announcer's port.
    2. UDP Multicast: Sending a multicast message back with "announce": false to avoid infinite loops.
  7. Use the Download API for reverse file transfer

    main

    The Download API is used when the receiver does not have the LocalSend app. The sender hosts an HTTP server, and the receiver (e.g., a web browser) downloads files via a URL.

    Note: This uses unencrypted HTTP because browsers reject self-signed certificates for HTTPS.

    1. Browser URL

    The receiver accesses the sender via: http://<sender-ip>:<sender-port>

    2. Receive Request (Metadata Only)

    To get the list of available files, the receiver calls: POST /api/localsend/v2/prepare-download

    Query Params:

    • ?sessionId=mySessionId: Use this if the user refreshes the page to maintain the session.
    • ?pin=123456: Use this if a PIN is required.

    Response: Returns a JSON object containing info, sessionId, and a files map (containing id, fileName, size, etc.).

    3. Receive File

    To download a specific file: GET /api/localsend/v2/download?sessionId=mySessionId&fileId=someFileId Response: Binary data

  8. Default LocalSend Protocol v1 configuration

    main

    LocalSend v1 uses specific default ports and multicast addresses. While these can be configured in app settings, the following defaults are used for standard operation:

    Multicast (UDP)

    • Port: 53317
    • Address: 224.0.0.167 (Note: The multicast group 224.0.0.0/24 is used to ensure compatibility with Android devices).

    HTTP (TCP)

    • Port: 53317
  9. Upload files via HTTP (Sender Client)

    main

    In the standard file transfer flow, the receiver acts as the HTTP server and the sender acts as the client.

    1. Prepare Upload (Metadata Only)

    Before sending files, the sender must send metadata to the receiver to get permission and session tokens.

    Endpoint: POST /api/localsend/v2/prepare-upload

    Request Body:

    {
      "info": {
        "alias": "Nice Orange",
        "version": "2.0",
        "deviceModel": "Samsung",
        "deviceType": "mobile",
        "fingerprint": "random_string",
        "port": 53317,
        "protocol": "https",
        "download": true
      },
      "files": {
        "file_id_1": {
          "id": "file_id_1",
          "fileName": "image.png",
          "size": 324242,
          "fileType": "image/jpeg",
          "sha256": "hash",
          "preview": "data"
        }
      }
    }

    Response Body:

    {
      "sessionId": "my_session_id",
      "files": {
        "file_id_1": "file_token_1"
      }
    }

    Prepare Upload Error Codes:

    • 204: Completed (No files need to be transferred).
    • 400: Invalid request body.
    • 403: Rejected.
    • 500: Unknown receiver error.

    2. Send File

    Once you have the sessionId, fileId, and token, upload the binary data.

    Endpoint: POST /api/localsend/v2/upload?sessionId=<sessionId>&fileId=<fileId>&token=<token>

    Request Body: Raw binary data.

    Response: No response body.

    Send File Error Codes:

    • 400: Missing parameters.
    • 403: Invalid token or IP address.
    • 409: Blocked by another session.
    • 500: Unknown receiver error.

    3. Cancel Session

    To cancel an ongoing session, use the sessionId obtained during preparation.

    Endpoint: POST /api/localsend/v2/cancel?sessionId=<sessionId>

    Response: No response body.

  10. Default LocalSend Network Configuration

    main

    By default, LocalSend uses the following configuration for network communication. These can be overridden in app settings if ports or addresses are unavailable.

    Multicast (UDP)

    • Port: 53317
    • Address: 224.0.0.167 (Note: The default multicast group is 224.0.0.0/24 to ensure compatibility with Android devices).

    HTTP (TCP)

    • Port: 53317
  11. LocalSend Protocol v2 Default Configuration

    main

    LocalSend uses specific default ports and multicast addresses. While these can be modified in the application, the following defaults are used:

    UDP Multicast

    • Port: 53317
    • Address: 224.0.0.167 (Note: The default multicast group is 224.0.0.0/24 to support Android devices).

    HTTP (TCP)

    • Port: 53317
  12. Upload files using the Send File endpoint

    main

    Once you have received the token for a specific fileId from the /send-request endpoint, you can perform the actual binary upload.

    Endpoint POST /api/localsend/v1/send?fileId=some file id&token=some token

    Request Body

    • Raw binary data.

    Notes

    • Multiple file uploads can be called in parallel using their respective tokens.
    • The response contains no body.
    # Example conceptual invocation
    curl -X POST "http://<receiver-ip>:53317/api/localsend/v1/send?fileId=some_id&token=some_token" --data-binary "@path/to/file.png"