# 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
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.ymlconfig file - Or dynamically via HTTP authentication response
- For pull relays, through
nearest_groupanddescriptionin relay settings
- In the
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 base64credentialsSending Location
Clients must send their current GPS position using an NMEA GGA sentence. This can be provided:- In the
Ntrip-GGAheader 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- In the
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.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-endedntrip-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.