diff --git a/ogn_lib/parser.py b/ogn_lib/parser.py
index abbe761..4df961f 100644
--- a/ogn_lib/parser.py
+++ b/ogn_lib/parser.py
@@ -686,3 +686,31 @@ class Spider(Parser):
             'spider_id': fields[2],
             'gps_status': fields[3]
         }
+
+
+class Skylines(Parser):
+    """
+    Parser for Spider-formatted APRS messages.
+    """
+
+    __destto__ = ['OGSKYL', 'OGSKYL-1']
+
+    @staticmethod
+    def _parse_protocol_specific(comment):
+        """
+        Parses the comment string from Spider's APRS messages.
+        :param str comment: comment string
+        :return: parsed comment
+        :rtype: dict
+        """
+
+        fields = comment.split(' ', maxsplit=1)
+
+        if len(fields) < 2:
+            raise exceptions.ParseError('Skylines comment incorrectly formatted:'
+                                        ' received {}'.format(comment))
+
+        return {
+            'id': fields[0],
+            'vertical_speed': int(fields[1][:3]) * FEET_TO_METERS
+        }

 Implement parser for Skylines messages (OGSKYL)
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 8fd96a5..fa7c7cd 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -466,6 +466,21 @@ class TestSpider:
             parser.Spider._parse_protocol_specific('id300234010617040 +19dB')
 
 
+class TestSkylines:
+    def test_parse_protocol_specific(self):
+        data = parser.Skylines._parse_protocol_specific('id2816 +000fpm')
+        assert data['id'] == 'id2816'
+        assert data['vertical_speed'] == 0
+
+        data = parser.Skylines._parse_protocol_specific('id2816 +159fpm')
+        assert data['id'] == 'id2816'
+        assert abs(data['vertical_speed'] - 4.57) < 0.1
+
+    def test_parse_protocol_specific_fail(self):
+        with pytest.raises(exceptions.ParseError):
+            parser.Skylines._parse_protocol_specific('id1111')
+
+
 class TestServerParser:
 
     def test_parse_message_beacon(self, mocker):

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-mock
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup==1.2.2
iniconfig==2.1.0
-e git+https://github.com/akolar/ogn-lib.git@8321ac10ba83ecf6566956b001b0644c34c7bdf9#egg=ogn_lib
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
pytest-mock==3.14.0
tomli==2.2.1

name: ogn-lib
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-mock==3.14.0
      - tomli==2.2.1
prefix: /opt/conda/envs/ogn-lib

tests/test_parser.py::TestSkylines::test_parse_protocol_specific tests/test_parser.py::TestSkylines::test_parse_protocol_specific_fail
tests/test_parser.py::TestParserBase::test_new_no_id tests/test_parser.py::TestParserBase::test_new_single_id tests/test_parser.py::TestParserBase::test_new_multi_id tests/test_parser.py::TestParserBase::test_no_destto tests/test_parser.py::TestParserBase::test_new_wrong_id tests/test_parser.py::TestParserBase::test_set_default tests/test_parser.py::TestParserBase::test_call tests/test_parser.py::TestParserBase::test_call_server tests/test_parser.py::TestParserBase::test_call_no_parser tests/test_parser.py::TestParserBase::test_call_default tests/test_parser.py::TestParserBase::test_call_failed tests/test_parser.py::TestParser::test_pattern_header tests/test_parser.py::TestParser::test_pattern_header_matches_all tests/test_parser.py::TestParser::test_pattern_location tests/test_parser.py::TestParser::test_pattern_location_matches_all tests/test_parser.py::TestParser::test_pattern_comment_common tests/test_parser.py::TestParser::test_pattern_comment_common_matches_all tests/test_parser.py::TestParser::test_pattern_all tests/test_parser.py::TestParser::test_pattern_all_matches_all tests/test_parser.py::TestParser::test_parse_msg_no_match tests/test_parser.py::TestParser::test_parse_msg_calls tests/test_parser.py::TestParser::test_parse_msg tests/test_parser.py::TestParser::test_parse_msg_full tests/test_parser.py::TestParser::test_parse_msg_delete_update tests/test_parser.py::TestParser::test_parse_msg_comment tests/test_parser.py::TestParser::test_parse_digipeaters tests/test_parser.py::TestParser::test_parse_digipeaters_relayed tests/test_parser.py::TestParser::test_parse_digipeaters_unknown_format tests/test_parser.py::TestParser::test_parse_heading_speed tests/test_parser.py::TestParser::test_parse_heading_speed_both_missing tests/test_parser.py::TestParser::test_parse_heading_speed_null_input tests/test_parser.py::TestParser::test_parse_altitude tests/test_parser.py::TestParser::test_parse_altitude_missing tests/test_parser.py::TestParser::test_parse_attrs tests/test_parser.py::TestParser::test_parse_timestamp_h tests/test_parser.py::TestParser::test_parse_timestamp_z tests/test_parser.py::TestParser::test_parse_time_past tests/test_parser.py::TestParser::test_parse_time_future tests/test_parser.py::TestParser::test_parse_datetime tests/test_parser.py::TestParser::test_parse_location_sign tests/test_parser.py::TestParser::test_parse_location_value tests/test_parser.py::TestParser::test_parse_protocol_specific tests/test_parser.py::TestParser::test_get_location_update_func tests/test_parser.py::TestParser::test_update_location_decimal_same tests/test_parser.py::TestParser::test_update_location_decimal_positive tests/test_parser.py::TestParser::test_update_location_decimal_negative tests/test_parser.py::TestParser::test_call tests/test_parser.py::TestParser::test_update_data tests/test_parser.py::TestParser::test_update_data_missing tests/test_parser.py::TestAPRS::test_parse_protocol_specific tests/test_parser.py::TestAPRS::test_parse_id_string tests/test_parser.py::TestNaviter::test_parse_protocol_specific tests/test_parser.py::TestNaviter::test_parse_id_string tests/test_parser.py::TestSpot::test_parse_protocol_specific tests/test_parser.py::TestSpot::test_parse_protocol_specific_fail tests/test_parser.py::TestSpider::test_parse_protocol_specific tests/test_parser.py::TestSpider::test_parse_protocol_specific_fail tests/test_parser.py::TestServerParser::test_parse_message_beacon tests/test_parser.py::TestServerParser::test_parse_message_status tests/test_parser.py::TestServerParser::test_parse_beacon_comment
ogn_lib/parser.py
ogn_lib/parser.py