# Configuration

YCCaster reads caster.yml from its working directory. Paths to other YAML files are resolved relative to that file. Restart YCCaster after changing its main configuration or authorization files.

  • caster.yml — listener, authorization, events, API and license settings.

  • mountpoints.yml — optional incoming-base credentials and source descriptions.

  • clients.yml — optional rover credentials.

  • relays.yml — standalone pull relay settings, persisted automatically by the relay HTTP API. See Pull relays.

  • caster.yml - The main configuration file

caster:
  host: yccaster.com
  address: 0.0.0.0:2101
  identifier: Demo caster
  operator: Hedgehack OU
  nmea: 0
  country: EST
  latitude: 59.44
  longitude: 24.74
  fallback_host: 0.0.0.0
  fallback_port: 0
  misc: ""

# Same name client limit

configuration:
  same-name-client-limit: 10

This limits simultaneous rover connections to each mountpoint, not to each username. The default 0 means no per-mountpoint limit; license limits still apply. Existing rovers continue to count toward this limit after a pull relay reconnects.

# Authorization

By default, YCCaster accepts any valid NTRIP connections. There are several strategies that you may employ to protect your caster.

# File

File strategie depends on 2 files that contain a list of mount points and a list of clients that are allowed to connect to the caster.

To enable it, you should specifile these files in caster.yml

caster:
  host: caster.de
  address: 0.0.0.0:2101
  identifier: YCCaster v1
  operator: MYNET
  nmea: 0
  country: JPN
  latitude: 10.12
  longitude: 10.12
  fallback_host: 0.0.0.0
  fallback_port: 0
  misc: ''
configuration:
  auth:
  - type: file
    options:
      mount-points: mountpoints.yml
      clients: clients.yml

And create respected files

mountpoints.yml

- mount-point: BCEP00BKG0
  password: "12345"
  description:
    identifier: Barcelona
    format: RTCM 3.2
    format-details: 1006(15),1008(15),1013(60),1019,1020,1033(15),1075(1),1085(1),1095(1),1230(15)
    carrier: 2
    nav-system: GPS+GLO+GAL
    network: EUREF
    country: ESP
    latitude: 41.41
    longitude: 2.00
    nmea: 0
    solution: 0
    generator: LEICA GR10
    compr-encryp: none
    authentication: B
    fee: N
    bitrate: 6200
    misc: RGP, Ville de Cannes

clients.yml

- username: myrover
  password: "12345"

Now, only NTRIP server and client that are listed will be allowed. You may restrict only server or only client connections, by specifying only one of the files in config.

caster.yml

configuration:
  auth:
  - type: file
    options:
      mount-points: mountpoints.yml

# Http

If you are building something bigger, local files may limit your flexibility. Http starategie will allow implement complex authorization logic. Caster will send http requests to an API and will allow or reject NTRIP connections depending on server responses.

To enable this strategie, specify url of your server endpoint and secret that will confirm that request came from your caster.

caster.yml

configuration:
  auth:
  - type: http
    options:
      url: http://api.mycompany.com/ntrip_auth
      secret: super_secret

When the caster receives a request from the NTRIP server or client, it in turn will send a request API.

Server connection authorization request example:

POST / HTTP/1.1
Host: 127.0.0.1:3000
Content-Length: 170
Accept: application/json
Content-Type: application/json
X-Api-Key: super_secret
Accept-Encoding: gzip

{
   "method":"SOURCE",
   "password":"test",
   "uri":"/Test",
   "http_version":"HTTP/1.0",
   "headers":[
      {
         "name":"User-Agent",
         "value":"NTRIP YCServer"
      }
   ],
   "type":"server",
   "ntrip_version":1
}

Client connection authorization request example:

POST / HTTP/1.1
Host: 127.0.0.1:3000
Content-Length: 203
Accept: application/json
Content-Type: application/json
X-Api-Key: super_secret
Accept-Encoding: gzip

{
   "method":"GET",
   "uri":"/Test",
   "http_version":"HTTP/1.0",
   "headers":[
      {
         "name":"User-Agent",
         "value":"NTRIP YCServer"
      },
      {
         "name":"Authorization",
         "value":"Basic cGFrOjEyMzQ1"
      }
   ],
   "type":"client",
   "ntrip_version":1
}

Caster will authorize NTRIP connection if it gets 2XX http response code and rejects with any other. In case of server connection, the caster will also expect to receive mount point description in the response body.

{
  "description": {
    "identifier": "Barcelona",
    "format": "RTCM 3.2",
    "format-details": "1006(15),1008(15),1013(60),1019,1020,1033(15),1075(1),1085(1),1095(1),1230(15)",
    "carrier": 2,
    "nav-system": "GPS+GLO+GAL",
    "network": "EUREF",
    "country": "ESP",
    "latitude": 41.41,
    "longitude": 2,
    "nmea": 0,
    "solution": 0,
    "generator": "LEICA GR10",
    "compr-encryp": "none",
    "authentication": "B",
    "fee": "N",
    "bitrate": 6200,
    "misc": "RGP, Ville de Cannes"
  }
}

# Mixed

It's possible to use a mixed authorization strategy. For example, you can list some mount points and clients in text files, and use http for the rest of them.

caster.yml

configuration:
  auth:
  - type: file
    options:
      mount-points: mountpoints.yml
      clients: clients.yml
  - type: http
    options:
      url: http://api.mycompany.com/ntrip_auth
      secret: super_secret

YCCaster will check files first, and if it does not find a match in files, it will send http request.

# Nearest group

The Nearest group feature allows NTRIP clients to connect to the geographically closest base station within a defined group, instead of selecting a specific mount point manually. This is especially useful for mobile clients that change location frequently.


# 🔧 How It Works

  1. Mount Point Grouping
    Base stations are grouped into Nearest Groups, which are named collections of mount points. Each group has a unique name (e.g., FloridaRTCM3), and each base can be assigned to a group either:

    • In the mountpoints.yml config file
    • Or dynamically via HTTP authentication response
    • For pull relays, through nearest_group and description in relay settings
  2. Client Connection
    Clients can connect to the group by requesting the group name instead of a mount point:

    GET /FloridaRTCM3 HTTP/1.1
    Host: ntrip.example.com
    Ntrip-Version: Ntrip/2.0
    User-Agent: NTRIP ExampleClient/2.0
    Authorization: Basic base64credentials
    
  3. Sending Location
    Clients must send their current GPS position using an NMEA GGA sentence. This can be provided:

    • In the Ntrip-GGA header during connection, or
    • As a plain line within the first 30 seconds after connecting

    Example:

    $GNGGA,123610.00,0405.1171,N,07323.2386,E,4,49,0.4,-91.6814,M,0.0000,M,5.0,1024*7D
    
  4. Automatic Base Selection
    YCCaster reads the GGA message, determines the client's location, and selects the closest available base station within the group. The connection is then redirected to that base.

  5. Live Position Updates
    If the client sends new GGA messages (e.g., it moved), YCCaster will:

    • Check if the currently selected base is still the closest
    • If not, it will switch to a closer base and send:
      • ntrip-session-ended
      • ntrip-session-started

# 🗂 Configuring Nearest Groups

In your mountpoints.yml, you can define the group using the nearest-group field:

- mount-point: BCEP00BKG0
  password: "12345"
  nearest-group: FloridaRTCM3
  description:
    identifier: Barcelona
    format: RTCM 3.2
    latitude: 41.41
    longitude: 2.00

Or provide it dynamically in your authentication response:

{
   "nearest-group":"FloridaRTCM3",
   "description":{
      "latitude":41.41,
      "longitude":2.00
   }
}

# Group Name Rules:

  • May include letters, numbers, dashes (-), and underscores (_)
  • Must be unique

# Source availability

Pull relay sources join the group after receiving their first bytes and leave when their upstream connection ends or times out. Use the fixed base coordinates in the relay description; optional upstream GGA coordinates are independent. Existing nearest-group switching is driven by rover GGA messages, not an immediate source-loss trigger.

# ❗️Error Handling

If the client connects to a Nearest Group but fails to provide a GGA message within 30 seconds, it will be disconnected with the message:

NMEA position not provided

# Events

Things happen. And YCCaster can report about such events.

Event name Description
caster-ready Emits when caster is ready to accept incoming connections.
caster-terminate Emits when caster get termination signal.
connection-accepted Emits when incoming TCP connection received.
connection-terminated Emits when incoming TCP connection terminated.
ntrip-request-accepted Emits when NTRIP request was authorized.
ntrip-request-rejected Emits when NTRIP request was rejected.
ntrip-session-started Emits when NTRIP session was started.
ntrip-session-ended Emits when NTRIP session was was ended.
ntrip-session-server-data Emits when data from NTRIP server connection received. Data is encoded in base64.
ntrip-session-client-data Emits when data from NTRIP client connection received. Data is encoded in base64.
caster-status-10 Emits when every 10 seconds. Valid interval is between 1 and 3600.
ntrip-session-status-25 Session status every 25 seconds. Valid interval is between 1 and 3600 seconds.
relay Sender filter for all relay lifecycle events, including relay-status every 10 seconds.

See relay events and status for the full relay lifecycle, reasons and payload fields. Event delivery is best effort; periodic status snapshots help recover current state after missed events.

Caster event example:

{
  "name": "ntrip-session-ended",
  "timestamp": 1789488000,
  "data": {
    "name": "LOCAL_BASE",
    "type": "server",
    "connection_id": "218bd351-f4a7-4528-b810-4c74e687f060",
    "relay_id": "9a132980-b753-4f64-89af-412216f34c40",
    "direction": "pull",
    "source_kind": "relay",
    "reason": "remote_closed",
    "bytes_transferred": 66560
  }
}

# File

Events can be saved to local file.

caster.yml

configuration:
  events:
  - type: file
    options:
      path: /var/caster/session.log
      types:
        - caster-ready
        - caster-terminate
        - connection-accepted
        - connection-terminated
        - ntrip-request-accepted
        - ntrip-request-rejected
        - ntrip-session-started
        - ntrip-session-ended
        - relay

# Http

Or they can be send to remote server via http.

caster.yml

configuration:
  events:
  - type: http
    options:
      url: https://api.example.com/caster/events
      secret: super_secret
      interval: 1000
      limit: 100
      types: 
        - caster-ready
        - caster-terminate
        - connection-accepted
        - connection-terminated
        - ntrip-request-accepted
        - ntrip-request-rejected
        - ntrip-session-started
        - ntrip-session-ended
        - relay

The HTTP sender flushes queued events every interval milliseconds, in batches of at most limit events. The interval is clamped to 1 second–1 hour and the batch limit to 1–1000 events.

# API

YCCaster has a built-in HTTP API for monitoring and relay management. It starts only when at least one API key is configured. The default listen address is :8080; specify host and port together in address.

GET /health is public. All other endpoints require X-API-Key. Use a trusted network or a TLS reverse proxy when accessing the HTTP API remotely.

caster.yml

configuration:
  api:
    address: 127.0.0.1:8080
    api-keys:
      - secret

# Endpoints

GET /health

Health endpoint return response code 200 with empty body if caster is up and running and is ready to accept incoming NTRIP connections.

Request example:

GET /health HTTP/1.1
Accept: */*
Host: yccaster.com:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

Response example:

HTTP/1.1 200 OK
Server: fasthttp
Date: Wed, 26 May 2021 17:34:17 GMT
Content-Length: 0

GET /status

Status endpoint responds with current caster status.

Request example:

GET /status HTTP/1.1
X-API-Key: secret
Accept: */*
Host: yccaster.com:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

Response example:

HTTP/1.1 200 OK
Server: fasthttp
Date: Wed, 26 May 2021 17:39:48 GMT
Content-Type: application/json
Content-Length: 144

{
   "data":{
      "address":"[::]:2101",
      "version":"2.1.0",
      "server_connections":1,
      "client_connections":0,
      "started_at":1622050431
   }
}

GET /mountpoints

Mount points endpoint return list of active server sessions.

Request example:

GET /mountpoints HTTP/1.1
X-API-Key: secret
Accept: */*
Host: yccaster.com:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
 

Response example:

HTTP/1.1 200 OK
Server: fasthttp
Date: Wed, 26 May 2021 17:43:33 GMT
Content-Type: application/json
Content-Length: 131

{
   "data":[
      {
         "name":"Test",
         "address":"62.228.76.148:49220",
         "bytes_transferred":43008,
         "started_at":1622051009
      }
   ]
}

GET /clients

Clients endpoint return list of active client sessions.

Request example:

GET /clients HTTP/1.1
X-API-Key: secret
Accept: */*
Host: yccaster.com:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
 

Response example:

HTTP/1.1 200 OK
Server: fasthttp
Date: Wed, 26 May 2021 17:55:25 GMT
Content-Type: application/json
Content-Length: 117

{
   "data":[
      {
         "address":"62.228.76.148:43952",
         "bytes_transferred":53248,
         "started_at":1622051720
      }
   ]
}

# Relay endpoints

YCCaster 2.1.0 adds the following authenticated routes:

Method Endpoint Purpose
GET /relays List relay configuration without passwords and current status
POST /relays Create a relay with a generated UUID
GET /relays/{id} Read one relay
PUT /relays/{id} Save the full configuration, including enabled/disabled state
DELETE /relays/{id} Stop and remove a relay
POST /relays/{id}/reconnect Reconnect an enabled relay

See Pull relays for request fields, password handling, persistence and errors.

# License key

To run YCCaster with a commercial license, specify the signed license supplied for your installation. The setting is license-key at the top level of caster.yml:

license-key: "YOUR_SIGNED_LICENSE"

Established pull relay sessions count toward the same source connection limit as direct bases. There is no separate limit on the number of configured relays. An enabled relay waiting to connect reserves its mountpoint but does not consume a source connection slot.