Repository: astropy/astroquery

Issue:
New Splatalogue breaks astroquery interface
Example:
```python
>>> Splatalogue.query_lines(1*u.GHz, 2*u.GHz)
Traceback (most recent call last):
  Cell In[239], line 1
    Splatalogue.query_lines(1*u.GHz, 2*u.GHz)
  File ~/repos/astroquery/astroquery/utils/class_or_instance.py:25 in f
    return self.fn(obj, *args, **kwds)
  File ~/repos/astroquery/astroquery/utils/process_asyncs.py:29 in newmethod
    result = self._parse_result(response, verbose=verbose)
  File ~/repos/astroquery/astroquery/splatalogue/core.py:480 in _parse_result
    result = ascii.read(response.text.split('\n'), delimiter=':',
  File ~/mambaforge/envs/py39forge/lib/python3.9/site-packages/astropy/io/ascii/ui.py:426 in read
    dat = reader.read(table)
  File ~/mambaforge/envs/py39forge/lib/python3.9/site-packages/astropy/io/ascii/core.py:1451 in read
    raise InconsistentTableError(errmsg)
InconsistentTableError: Number of header columns (1) inconsistent with data columns (2) at data line 13
Header values: ['<!-- start of nrao-header.html -->']
Data values: ['<a href="http', '//www.nrao.edu/">']
```

Announced and deployed the same day:
https://science.nrao.edu/enews/17.2/

This is a severely breaking change, such that the existing code is likely now of zero value.  

I used splatalogue a lot, so I may want to write a new module if the upstream interface comes back online (presently, the new splatalogue does not function at all), but in the meantime I recommend people switch to the JPL and CDMS line lists.

Discussion:
pep8speaks: Hello @keflavich! Thanks for opening this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:



* In the file [`astroquery/splatalogue/core.py`](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py):

> [Line 186:22](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L186): [E124](https://duckduckgo.com/?q=pep8%20E124) closing bracket does not match visual indentation
> [Line 303:35](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L303): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 304:38](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L304): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 305:33](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L305): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 306:46](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L306): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 307:44](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L307): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 308:46](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L308): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 309:39](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L309): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 310:32](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L310): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 311:30](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L311): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 312:37](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L312): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 313:35](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L313): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 314:45](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L314): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 315:41](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L315): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 316:57](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L316): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 317:56](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L317): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 318:44](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L318): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 319:63](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L319): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 320:56](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L320): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 321:40](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L321): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 322:41](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L322): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 323:46](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L323): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 324:42](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L324): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 325:43](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L325): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 326:40](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L326): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 327:50](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L327): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 328:45](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L328): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 329:40](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L329): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 330:48](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L330): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 331:47](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L331): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 332:44](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L332): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 333:44](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L333): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 334:49](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L334): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 335:36](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L335): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 336:36](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L336): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 337:38](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L337): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 338:37](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L338): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 339:48](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L339): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 340:49](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L340): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 341:49](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L341): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 342:46](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L342): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 343:47](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L343): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 344:41](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L344): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 345:41](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L345): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 346:53](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L346): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 347:49](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L347): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 348:40](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L348): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 349:46](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L349): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 350:35](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L350): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 351:49](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L351): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 352:55](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L352): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 353:45](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L353): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 354:47](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L354): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 355:32](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L355): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 356:37](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L356): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 357:33](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L357): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 358:33](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L358): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 359:32](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L359): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ':'
> [Line 397:9](https://github.com/astropy/astroquery/blob/ae85780aadcbcfb9bf4397cd0120ee1cbc861472/astroquery/splatalogue/core.py#L397): [E265](https://duckduckgo.com/?q=pep8%20E265) block comment should start with '# '


keflavich: This works locally.  I was even able to reproduce the error that is showing up now about the wrong content type in the mocks, and fix it, but the same error is recurring now.  I can't make sense of it now.  The `content` keyword in the mock is very clearly a `b''` that has a `decode` attribute.
keflavich: ach, nevermind my previous comment; I didn't realize where the mocks were defined (they're in `conftest`)
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/astropy/astroquery/pull/2960?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy) Report
Attention: Patch coverage is `89.18919%` with `8 lines` in your changes are missing coverage. Please review.
> Project coverage is 66.81%. Comparing base [(`b530378`)](https://app.codecov.io/gh/astropy/astroquery/commit/b530378ab24fa2363901437951ebf3d21c96e8a0?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy) to head [(`b3dd420`)](https://app.codecov.io/gh/astropy/astroquery/pull/2960?dropdown=coverage&src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy).

| [Files](https://app.codecov.io/gh/astropy/astroquery/pull/2960?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy) | Patch % | Lines |
|---|---|---|
| [astroquery/splatalogue/core.py](https://app.codecov.io/gh/astropy/astroquery/pull/2960?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy#diff-YXN0cm9xdWVyeS9zcGxhdGFsb2d1ZS9jb3JlLnB5) | 88.13% | [7 Missing :warning: ](https://app.codecov.io/gh/astropy/astroquery/pull/2960?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy) |
| [astroquery/splatalogue/setup\_package.py](https://app.codecov.io/gh/astropy/astroquery/pull/2960?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy#diff-YXN0cm9xdWVyeS9zcGxhdGFsb2d1ZS9zZXR1cF9wYWNrYWdlLnB5) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/astropy/astroquery/pull/2960?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy) |

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##             main    #2960   +/-   ##
=======================================
  Coverage   66.80%   66.81%           
=======================================
  Files         237      236    -1     
  Lines       18321    18293   -28     
=======================================
- Hits        12239    12222   -17     
+ Misses       6082     6071   -11     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/astropy/astroquery/pull/2960?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=astropy).

keflavich: OK, looks like we're green.  The readthedocs failure doesn't seem to be associated with this PR, as far as I can see.
keflavich: @bsipocz this is ready for your review.  Any ideas on the readthedocs issue?
bsipocz: RTD failure is pyvo related and I'll look into it separately.
keflavich: @bsipocz is there anything holding this back from getting merged?
bsipocz: > @bsipocz is there anything holding this back from getting merged?

Sorry, apparently I have a half finished review here with some minor comments. RTD has been fixed, so that is not holding it up.
keflavich: Do I need to rebase or rerun tests to get RTD to pass?
bsipocz: > Do I need to rebase or rerun tests to get RTD to pass?

No need to rebase as not much has changed overall, but also wouldn't hurt once you fixed the docs.
bsipocz: RTD failure is now relevant to this PR.

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 8ac27706..49cc7ddf 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -13,6 +13,11 @@ mpc
 
 - Parse star catalog information when querying observations database [#2957]
 
+splatalogue
+^^^^^^^^^^^
+
+- Fix incompatibilities with the major changes made to the Splatalogue's upstream server in March 2024. [#2960]
+
 vizier
 ^^^^^^
 
diff --git a/astroquery/splatalogue/__init__.py b/astroquery/splatalogue/__init__.py
index 6f863059..46e49a7c 100644
--- a/astroquery/splatalogue/__init__.py
+++ b/astroquery/splatalogue/__init__.py
@@ -21,9 +21,7 @@ class Conf(_config.ConfigNamespace):
         'Splatalogue SLAP interface URL (not used).')
     base_url = 'https://splatalogue.online'
     query_url = _config.ConfigItem(
-        f'{base_url}/c_export.php',
-        # defunct as of Sep 4, 2020?  (keeping because this is likely the true host)
-        # 'https://www.cv.nrao.edu/php/splat/c_export.php',
+        f'{base_url}/splata-slap/advanceded/false',
         'Splatalogue web interface URL.')
     timeout = _config.ConfigItem(
         60,
diff --git a/astroquery/splatalogue/core.py b/astroquery/splatalogue/core.py
index d535b285..49273c2d 100644
--- a/astroquery/splatalogue/core.py
+++ b/astroquery/splatalogue/core.py
@@ -6,10 +6,9 @@ ftp://ftp.cv.nrao.edu/NRAO-staff/bkent/slap/idl/
 
 :author: Adam Ginsburg <adam.g.ginsburg@gmail.com>
 """
-import warnings
-from astropy.io import ascii
+import json
+from astropy.table import Table
 from astropy import units as u
-from astroquery import log
 from ..query import BaseQuery
 from ..utils import async_to_sync, prepend_docstr_nosections
 from . import conf
@@ -23,6 +22,18 @@ __all__ = ['Splatalogue', 'SplatalogueClass']
 # example query of SPLATALOGUE directly:
 # https://www.cv.nrao.edu/php/splat/c.php?sid%5B%5D=64&sid%5B%5D=108&calcIn=&data_version=v3.0&from=&to=&frequency_units=MHz&energy_range_from=&energy_range_to=&lill=on&tran=&submit=Search&no_atmospheric=no_atmospheric&no_potential=no_potential&no_probable=no_probable&include_only_nrao=include_only_nrao&displayLovas=displayLovas&displaySLAIM=displaySLAIM&displayJPL=displayJPL&displayCDMS=displayCDMS&displayToyaMA=displayToyaMA&displayOSU=displayOSU&displayRecomb=displayRecomb&displayLisa=displayLisa&displayRFI=displayRFI&ls1=ls1&ls5=ls5&el1=el1
 
+# for backward-compatibility
+# (As of March 5, this is incomplete, but is enough to make `minimize_table` work)
+colname_mapping_feb2024 = {
+    'Species': 'name',
+    'Chemical Name': 'chemical_name',
+    'Resolved QNs': 'resolved_QNs',
+    'Freq-GHz(rest frame,redshifted)': 'orderedFreq',
+    'Meas Freq-GHz(rest frame,redshifted)': 'measFreq',
+    'Log<sub>10</sub> (A<sub>ij</sub>)': 'aij',
+    'E_U (K)': 'upper_state_energy_K',
+}
+
 
 @async_to_sync
 class SplatalogueClass(BaseQuery):
@@ -33,32 +44,15 @@ class SplatalogueClass(BaseQuery):
     LINES_LIMIT = conf.lines_limit
     versions = ('v1.0', 'v2.0', 'v3.0', 'vall')
     # global constant, not user-configurable
-    ALL_LINE_LISTS = ('Lovas', 'SLAIM', 'JPL', 'CDMS', 'ToyoMA', 'OSU',
-                      'Recomb', 'Lisa', 'RFI')
-    TOP20_LIST = ('comet', 'planet', 'top20', 'ism_hotcore', 'ism_darkcloud',
-                  'ism_diffusecloud')
-    FREQUENCY_BANDS = {"any": "Any",
-                       "alma3": "ALMA Band 3 (84-116 GHz)",
-                       "alma4": " ALMA Band 4 (125-163 GHz)",
-                       "alma5": " ALMA Band 5 (163-211 GHz)",
-                       "alma6": "ALMA Band 6 (211-275 GHz)",
-                       "alma7": "ALMA Band 7 (275-373 GHz)",
-                       "alma8": "ALMA Band 8 (385-500 GHz)",
-                       "alma9": "ALMA Band 9 (602-720 GHz)",
-                       "alma10": "ALMA Band 10 (787-950 GHz)",
-                       "pf1": "GBT PF1 (0.29-0.92 GHz)",
-                       "pf2": "GBT PF2 (0.91-1.23 GHz)",
-                       "l": "GBT/VLA L (1-2 GHz)",
-                       "s": "GBT/VLA S (1.7-4 GHz)",
-                       "c": "GBT/VLA C (3.9-8 GHz)",
-                       "x": "GBT/VLA X (8-12 GHz)",
-                       "ku": " GBT/VLA Ku (12-18 GHz)",
-                       "kfpa": "GBT KFPA (18-27.5 GHz)",
-                       "k": "VLA K (18-26.5 GHz)",
-                       "ka": " GBT/VLA Ka (26-40 GHz)",
-                       "q": "GBT/VLA Q (38-50 GHz)",
-                       "w": "GBT W (67-93.3 GHz)",
-                       "mustang": "GBT Mustang (80-100 GHz)", }
+    ALL_LINE_LISTS = ('LovasNIST', 'SLAIM', 'JPL', 'CDMS', 'ToyaMA', 'OSU',
+                      'TopModel', 'Recombination', 'RFI')
+    VALID_LINE_STRENGTHS = ('CDMSJPL', 'SijMu2', 'Sij', 'Aij', 'LovasAST')
+    VALID_ENERGY_LEVELS = {'One': 'EL_cm-1',
+                           'Two': 'EL_K',
+                           'Three': 'EU_cm-1',
+                           'Four': 'EU_K'}
+    VALID_ENERGY_TYPES = ('el_cm1', 'eu_cm1', 'eu_k', 'el_k')
+    VALID_INTENSITY_TYPES = ('CDMS/JPL (log)', 'Sij-mu2', 'Aij (log)')
 
     def __init__(self, **kwargs):
         """
@@ -76,7 +70,7 @@ class SplatalogueClass(BaseQuery):
         Modify the default options.
         See `query_lines`
         """
-        self.data.update(self._parse_kwargs(**kwargs))
+        self.data.update(json.loads(self._parse_kwargs(**kwargs)['body']))
 
     @deprecated_renamed_argument("restr", "species_regex", since="0.4.7")
     def get_species_ids(self, species_regex=None, *, reflags=0, recache=False):
@@ -150,8 +144,8 @@ class SplatalogueClass(BaseQuery):
                       max_frequency=100 * u.THz,
                       chemical_name='',
                       line_lists=self.ALL_LINE_LISTS,
-                      line_strengths=('ls1', 'ls2', 'ls3', 'ls4', 'ls5'),
-                      energy_levels=('el1', 'el2', 'el3', 'el4'),
+                      line_strengths=self.VALID_LINE_STRENGTHS,
+                      energy_levels=self.VALID_ENERGY_LEVELS.keys(),
                       exclude=('potential', 'atmospheric', 'probable'),
                       version='v3.0',
                       only_NRAO_recommended=None,
@@ -162,10 +156,10 @@ class SplatalogueClass(BaseQuery):
                       show_qn_code=False, show_lovas_labref=False,
                       show_lovas_obsref=False, show_orderedfreq_only=False,
                       show_nrao_recommended=False,)
-        return self._parse_kwargs(**kwargs)
+        return json.loads(self._parse_kwargs(**kwargs)['body'])
 
     def _parse_kwargs(self, *, min_frequency=None, max_frequency=None,
-                      band='any', top20=None, chemical_name=None,
+                      chemical_name=None,
                       chem_re_flags=0, energy_min=None, energy_max=None,
                       energy_type=None, intensity_lower_limit=None,
                       intensity_type=None, transition=None, version=None,
@@ -179,7 +173,9 @@ class SplatalogueClass(BaseQuery):
                       show_qn_code=None, show_lovas_labref=None,
                       show_lovas_obsref=None, show_orderedfreq_only=None,
                       show_nrao_recommended=None,
-                      parse_chemistry_locally=True):
+                      parse_chemistry_locally=True,
+                      export_start=0,
+                      export_stop=250):
         """
         The Splatalogue service returns lines with rest frequencies in the
         range [min_frequency, max_frequency].
@@ -190,13 +186,6 @@ class SplatalogueClass(BaseQuery):
             Minimum frequency (or any spectral() equivalent)
         max_frequency : `astropy.units`
             Maximum frequency (or any spectral() equivalent)
-        band : str
-            The observing band.  If it is not 'any', it overrides
-            minfreq/maxfreq.
-        top20: str
-            One of ``'comet'``, ``'planet'``, ``'top20'``, ``'ism_hotcore'``,
-            ``'ism_darkcloud'``, ``'ism_diffusecloud'``.
-            Overrides chemical_name
         chemical_name : str
             Name of the chemical to search for. Treated as a regular
             expression.  An empty set ('', (), [], {}) will match *any*
@@ -248,17 +237,17 @@ class SplatalogueClass(BaseQuery):
             Show only NRAO recommended species?
         line_lists : list
             Options:
-            Lovas, SLAIM, JPL, CDMS, ToyoMA, OSU, Recomb, Lisa, RFI
+            Lovas, SLAIM, JPL, CDMS, ToyaMA, OSU, Recombination, RFI
         line_strengths : list
             * CDMS/JPL Intensity : ls1
             * Sij : ls3
             * Aij : ls4
             * Lovas/AST : ls5
         energy_levels : list
-            * E_lower (cm^-1) : el1
-            * E_lower (K) : el2
-            * E_upper (cm^-1) : el3
-            * E_upper (K) : el4
+            * E_lower (cm^-1) : "One"
+            * E_lower (K) : "Two"
+            * E_upper (cm^-1) : "Three"
+            * E_upper (K) : "Four"
         export : bool
             Set up arguments for the export server (as opposed to the HTML
             server)?
@@ -292,135 +281,178 @@ class SplatalogueClass(BaseQuery):
 
         """
 
-        payload = {'submit': 'Search',
-                   'frequency_units': 'GHz',
-                   }
-
-        if band != 'any':
-            if band not in self.FREQUENCY_BANDS:
-                raise ValueError("Invalid frequency band.")
-            if min_frequency is not None or max_frequency is not None:
-                warnings.warn("Band was specified, so the frequency "
-                              "specification is overridden")
-            payload['band'] = band
-        elif min_frequency is not None and max_frequency is not None:
+        payload = {"searchSpecies": "",
+                   "speciesSelectBox": [],
+                   "dataVersion": "v3.0",
+                   "userInputFrequenciesFrom": [],
+                   "userInputFrequenciesTo": [],
+                   "userInputFrequenciesUnit": "GHz",
+                   "frequencyRedshift": 0,
+                   "energyFrom": 0,
+                   "energyTo": 0,
+                   "energyRangeType": "el_cm-1",
+                   "lineIntensity": "None",
+                   "lineIntensityLowerLimit": 0,
+                   "excludeAtmosSpecies": False,
+                   "excludePotentialInterstellarSpecies": False,
+                   "excludeProbableInterstellarSpecies": False,
+                   "excludeKnownASTSpecies": False,
+                   "showOnlyAstronomicallyObservedTransitions": False,
+                   "showOnlyNRAORecommendedFrequencies": False,
+                   "lineListDisplayJPL": True,
+                   "lineListDisplayCDMS": True,
+                   "lineListDisplayLovasNIST": True,
+                   "lineListDisplaySLAIM": True,
+                   "lineListDisplayToyaMA": True,
+                   "lineListDisplayOSU": True,
+                   "lineListDisplayRecombination": True,
+                   "lineListDisplayTopModel": True,
+                   "lineListDisplayRFI": True,
+                   "lineStrengthDisplayCDMSJPL": True,
+                   "lineStrengthDisplaySijMu2": False,
+                   "lineStrengthDisplaySij": False,
+                   "lineStrengthDisplayAij": False,
+                   "lineStrengthDisplayLovasAST": True,
+                   "energyLevelOne": True,
+                   "energyLevelTwo": False,
+                   "energyLevelThree": False,
+                   "energyLevelFour": False,
+                   "displayObservedTransitions": False,
+                   "displayG358MaserTransitions": False,
+                   "displayObservationReference": False,
+                   "displayObservationSource": False,
+                   "displayTelescopeLovasNIST": False,
+                   "frequencyErrorLimit": False,
+                   "displayHFSIntensity": False,
+                   "displayUnresolvedQuantumNumbers": False,
+                   "displayUpperStateDegeneracy": False,
+                   "displayMoleculeTag": False,
+                   "displayQuantumNumberCode": False,
+                   "displayLabRef": False,
+                   "displayOrderedFrequencyOnly": False,
+                   "displayNRAORecommendedFrequencies": False,
+                   "displayUniqueSpeciesTag": False,
+                   "displayUniqueLineIDNumber": False,
+                   "exportType": "current",
+                   "exportDelimiter": "tab",
+                   "exportLimit": "allRecords",
+                   "exportStart": 1,
+                   "exportStop": 250}
+
+        if min_frequency is not None and max_frequency is not None:
             # allow setting payload without having *ANY* valid frequencies set
             min_frequency = min_frequency.to(u.GHz, u.spectral())
             max_frequency = max_frequency.to(u.GHz, u.spectral())
             if min_frequency > max_frequency:
                 min_frequency, max_frequency = max_frequency, min_frequency
 
-            payload['from'] = min_frequency.value
-            payload['to'] = max_frequency.value
+            payload['userInputFrequenciesFrom'] = [min_frequency.value]
+            payload['userInputFrequenciesTo'] = [max_frequency.value]
 
-        if top20 is not None:
-            if top20 in self.TOP20_LIST:
-                payload['top20'] = top20
-            else:
-                raise ValueError("Top20 is not one of the allowed values")
-        elif chemical_name in ('', {}, (), [], set()):
-            # include all
-            payload['sid[]'] = []
+        if chemical_name in ('', {}, (), [], set(), None):
+            # include all by default, or whatever default was set
+            payload['speciesSelectBox'] = (self.data['speciesSelectBox']
+                                           if hasattr(self, 'data')
+                                           else [])
         elif chemical_name is not None:
             if parse_chemistry_locally:
                 species_ids = self.get_species_ids(species_regex=chemical_name, reflags=chem_re_flags)
                 if len(species_ids) == 0:
                     raise ValueError("No matching chemical species found.")
-                payload['sid[]'] = list(species_ids.values())
+                payload['speciesSelectBox'] = list(species_ids.values())
             else:
-                payload['chemical_name'] = chemical_name
+                payload['searchSpecies'] = chemical_name
 
         if energy_min is not None:
-            payload['energy_range_from'] = float(energy_min)
+            payload['energyFrom'] = float(energy_min)
         if energy_max is not None:
-            payload['energy_range_to'] = float(energy_max)
+            payload['energyTo'] = float(energy_max)
         if energy_type is not None:
-            validate_energy_type(energy_type)
-            payload['energy_range_type'] = energy_type
-
-        if intensity_type is not None:
-            payload['lill'] = 'lill_' + intensity_type
-            if intensity_lower_limit is not None:
-                payload[payload['lill']] = intensity_lower_limit
-
-        if transition is not None:
-            payload['tran'] = transition
+            if energy_type not in self.VALID_ENERGY_TYPES:
+                raise ValueError(f'energy_type must be one of {self.VALID_ENERGY_TYPES}')
+            payload['energyRangeType'] = energy_type
+
+        if intensity_lower_limit is not None:
+            if intensity_type is None:
+                raise ValueError("If you specify an intensity lower limit, you must also specify its intensity_type.")
+            elif intensity_type not in self.VALID_INTENSITY_TYPES:
+                raise ValueError(f'intensity_type must be one of {self.VALID_INTENSITY_TYPES}')
+            payload['lineIntensity'] = intensity_type
+            payload['lineIntensityLowerLimit'] = intensity_lower_limit
 
         if version in self.versions:
-            payload['data_version'] = version
+            payload['dataVersion'] = version
         elif version is not None:
             raise ValueError("Invalid version specified.  Allowed versions "
                              "are {vers}".format(vers=str(self.versions)))
 
-        if exclude == 'none':
-            for e in ('potential', 'atmospheric', 'probable', 'known'):
-                # Setting a keyword value to 'None' removes it (see query_lines_async)
-                log.debug("Setting no_{0} to None".format(e))
-                payload['no_' + e] = None
-        elif exclude is not None:
-            for e in exclude:
-                payload['no_' + e] = 'no_' + e
+        if exclude is not None:
+            if 'potential' in exclude:
+                payload['excludePotentialInterstellarSpecies'] = True
+            if 'atmospheric' in exclude:
+                payload['excludeAtmosSpecies'] = True
+            if 'probable' in exclude:
+                payload['excludeProbableInterstellarSpecies'] = True
+            if 'known' in exclude:
+                payload['excludeKnownASTSpecies'] = True
 
         if only_astronomically_observed:
-            payload['include_only_observed'] = 'include_only_observed'
+            payload['showOnlyAstronomicallyObservedTransitions'] = True
         if only_NRAO_recommended:
-            payload['include_only_nrao'] = 'include_only_nrao'
+            payload['showOnlyNRAORecommendedFrequencies'] = True
 
         if line_lists is not None:
             if type(line_lists) not in (tuple, list):
                 raise TypeError("Line lists should be a list of linelist "
                                 "names.  See Splatalogue.ALL_LINE_LISTS")
             for L in self.ALL_LINE_LISTS:
-                kwd = 'display' + L
-                if L in line_lists:
-                    payload[kwd] = kwd
-                else:
-                    payload[kwd] = ''
+                kwd = 'lineListDisplay' + L
+                payload[kwd] = L in line_lists
 
         if line_strengths is not None:
             for LS in line_strengths:
-                payload[LS] = LS
+                if LS not in self.VALID_LINE_STRENGTHS:
+                    raise ValueError(f"Line strengths must be one of {self.VALID_LINE_STRENGTHS}")
+                payload['lineStrengthDisplay' + LS] = True
 
         if energy_levels is not None:
             for EL in energy_levels:
-                payload[EL] = EL
-
-        for b in ("noHFS", "displayHFS", "show_unres_qn",
-                  "show_upper_degeneracy", "show_molecule_tag",
-                  "show_qn_code", "show_lovas_labref",
-                  "show_orderedfreq_only", "show_lovas_obsref",
-                  "show_nrao_recommended"):
-            if locals()[b]:
-                payload[b] = b
-
-        # default arg, unmodifiable...
-        payload['jsMath'] = 'font:symbol,warn:0'
-        payload['__utma'] = ''
-        payload['__utmc'] = ''
+                if EL not in self.VALID_ENERGY_LEVELS:
+                    raise ValueError("Energy levels must be a number spelled out, i.e., "
+                                     f"one of {self.VALID_ENERGY_LEVELS}")
+                payload['energyLevel' + EL] = True
+
+        for b in ("displayHFSIntensity", "displayUnresolvedQuantumNumbers",
+                  "displayUpperStateDegeneracy", "displayMoleculeTag",
+                  "displayQuantumNumberCode", "displayLabRef",
+                  "displayOrderedFrequencyOnly", "displayNRAORecommendedFrequencies",
+                  "displayUniqueLineIDNumber", "displayUniqueSpeciesTag"):
+            if b in locals() and locals()[b]:
+                payload[b] = True
 
         if export:
-            payload['submit'] = 'Export'
-            payload['export_delimiter'] = 'colon'  # or tab or comma
-            payload['export_type'] = 'current'
-            payload['offset'] = 0
-            payload['range'] = 'on'
+            payload['exportDelimiter'] = 'tab'  # or tab or comma
+            payload['exportType'] = 'current'
+            payload['exportStart'] = export_start
+            payload['exportStop'] = export_stop
 
         if export_limit is not None:
-            payload['limit'] = export_limit
+            payload['exportLimit'] = export_limit
         else:
-            payload['limit'] = self.LINES_LIMIT
+            payload['exportLimit'] = self.LINES_LIMIT
+
+        payload = {'body': json.dumps(payload),
+                   'headers': {'normalizedNames': {}, 'lazyUpdate': None}}
 
         return payload
 
     def _validate_kwargs(self, *, min_frequency=None, max_frequency=None,
-                         band='any', **kwargs):
+                         **kwargs):
         """
-        Check that either min_frequency + max_frequency or band are specified
+        Check that min_frequency + max_frequency are specified
         """
-        if band == 'any':
-            if min_frequency is None or max_frequency is None:
-                raise ValueError("Must specify either min/max frequency or "
-                                 "a valid Band.")
+        if min_frequency is None or max_frequency is None:
+            raise ValueError("Must specify min/max frequency")
 
     @prepend_docstr_nosections("\n" + _parse_kwargs.__doc__)
     def query_lines_async(self, min_frequency=None, max_frequency=None, *,
@@ -439,26 +471,25 @@ class SplatalogueClass(BaseQuery):
         self._validate_kwargs(min_frequency=min_frequency,
                               max_frequency=max_frequency, **kwargs)
 
+        data_payload = self._parse_kwargs(min_frequency=min_frequency,
+                                          max_frequency=max_frequency,
+                                          **kwargs)
         if hasattr(self, 'data'):
-            data_payload = self.data.copy()
-            data_payload.update(self._parse_kwargs(min_frequency=min_frequency,
-                                                   max_frequency=max_frequency,
-                                                   **kwargs))
+            body = self.data.copy()
         else:
-            data_payload = self._default_kwargs()
-            data_payload.update(self._parse_kwargs(min_frequency=min_frequency,
-                                                   max_frequency=max_frequency,
-                                                   **kwargs))
+            body = self._default_kwargs()
 
-        # Add an extra step: sometimes, need to REMOVE keywords
-        data_payload = {k: v for k, v in data_payload.items() if v is not None}
+        body.update(json.loads(
+            self._parse_kwargs(min_frequency=min_frequency,
+                               max_frequency=max_frequency, **kwargs)['body']))
+        data_payload['body'] = json.dumps(body)
 
         if get_query_payload:
             return data_payload
 
         response = self._request(method='POST',
                                  url=self.QUERY_URL,
-                                 data=data_payload,
+                                 json=data_payload,
                                  timeout=self.TIMEOUT,
                                  cache=cache)
 
@@ -472,13 +503,24 @@ class SplatalogueClass(BaseQuery):
 
         Parameters
         ----------
-        clean_headers : bool
-            Attempt to simplify / clean up the column headers returned by
-            splatalogue to make them more terminal-friendly
+        verbose : bool
+            Has no effect; kept for API compatibility
         """
 
-        result = ascii.read(response.text.split('\n'), delimiter=':',
-                            format='basic', fast_reader=False)
+        # these are metadata items not intended to be part of the table
+        meta_columns = ['orderFreqColName', 'measFreqColName']
+        meta = {}
+
+        jdat = response.json()
+
+        result = Table([x for x in jdat if x['species_id'] is not None])
+
+        for key in meta_columns:
+            if key in result.colnames:
+                meta[key] = result[key][0]
+                del result[key]
+
+        result.meta = meta
 
         return result
 
@@ -498,11 +540,4 @@ class SplatalogueClass(BaseQuery):
         return table
 
 
-def validate_energy_type(etype):
-    valid_energy_types = ('el_cm1', 'eu_cm1', 'eu_k', 'el_k')
-    if etype not in valid_energy_types:
-        raise ValueError("Energy type must be one of {0}"
-                         .format(valid_energy_types))
-
-
 Splatalogue = SplatalogueClass()
diff --git a/astroquery/splatalogue/setup_package.py b/astroquery/splatalogue/setup_package.py
index 47b3c59d..3c41ffcd 100644
--- a/astroquery/splatalogue/setup_package.py
+++ b/astroquery/splatalogue/setup_package.py
@@ -5,7 +5,7 @@ import os
 
 
 def get_package_data():
-    paths_test = [os.path.join('data', 'CO_colons.csv'),
+    paths_test = [os.path.join('data', 'CO.json'),
                   ]
 
     paths_data = [os.path.join('data', '*.json'),
diff --git a/astroquery/splatalogue/slap.py b/astroquery/splatalogue/slap.py
deleted file mode 100644
index f1af3893..00000000
--- a/astroquery/splatalogue/slap.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Licensed under a 3-clause BSD style license - see LICENSE.rst
-"""
-Construct a SLAP query.
-
-This is not presently used, since I don't know how to construct a complete SLAP
-query.
-"""
-
-
-def slap_default_payload(*, request='queryData', version='2.0', wavelength='',
-                         chemical_element='', initial_level_energy='',
-                         final_level_energy='', temperature='', einstein_a=''):
-    """
-    Parse the valid parameters specified by the `IVOA SLAP`_ interface
-    document.
-
-    .. _IVOA SLAP: http://www.ivoa.net/documents/SLAP/20101209/REC-SLAP-1.0-20101209.pdf
-
-
-    Parameters
-    ----------
-    request : 'queryData'
-        No other valid entries are known
-    version : '2.0'
-        A valid data version number
-    wavelength : 'x/y' or 'x' or 'x,y/z' or 'x/'
-        Wavelength range in meters.
-        'x/y' means 'in the range from x to y'
-        'x/' means 'wavelength > x'
-        'x' means 'wavelength == x'
-        'x/y,y/z' means 'wavelength in range [x,y] or [y,z]'
-        See Appendix A of the `IVOA SLAP`_ manual
-
-    Other Parameters
-    ----------------
-    chemical_element : str
-        A chemical element name.  Can be specified as a comma-separated list
-    initial_level_energy : float
-        Unit: Joules
-    final_level_energy : float
-        Unit: Joules
-    temperature : float
-        Unit : Kelvin
-        Expected temperature of object.  Not needed for splatalogue
-    einstein_a : float
-        Unit : s^-1
-    process_type : str
-    process_name : str
-        Examples:
-        "Photoionization", "Collisional excitation",
-        "Gravitational redshift", "Stark broadening", "Resonance broadening",
-        "Van de Waals broadening"
-
-    Returns
-    -------
-    Dictionary of parameters which can then be POSTed to the service
-    """
-    return locals()
diff --git a/astroquery/splatalogue/templates.py b/astroquery/splatalogue/templates.py
index cf74081b..8c72cb66 100644
--- a/astroquery/splatalogue/templates.py
+++ b/astroquery/splatalogue/templates.py
@@ -6,6 +6,6 @@ Template queries modifying the defaults of Splatalogue
 from .core import SplatalogueClass
 
 SplatalogueKelvins = SplatalogueClass(energy_max=500, energy_type='eu_k',
-                                      energy_levels=['el4'],
-                                      line_strengths=['ls4'],
+                                      energy_levels=['Four'],
+                                      line_strengths=['CDMSJPL'],
                                       only_NRAO_recommended=True, noHFS=True)
diff --git a/astroquery/splatalogue/utils.py b/astroquery/splatalogue/utils.py
index 3e343466..06b591d9 100644
--- a/astroquery/splatalogue/utils.py
+++ b/astroquery/splatalogue/utils.py
@@ -2,35 +2,16 @@
 """
 Utilities for working with Splatalogue query results
 """
-import numpy as np
-import astropy
-
-# Remap column headings to something IPAC-compatible
-column_headings_map = {'Log<sub>10</sub> (A<sub>ij</sub>)': 'log10_Aij',
-                       'Resolved QNs': 'QNs',
-                       'CDMS/JPL Intensity': 'CDMSJPL_Intensity',
-                       'S<sub>ij</sub>': 'Sij',
-                       'Freq-GHz': 'FreqGHz',
-                       'Meas Freq-GHz': 'MeasFreqGHz',
-                       'Lovas/AST Intensity': 'LovasAST_Intensity',
-                       'E_L (cm^-1)': 'EL_percm',
-                       'E_L (K)': 'EL_K',
-                       'E_U (cm^-1)': 'EU_percm',
-                       'E_U (K)': 'EU_K',
-                       'Chemical Name': 'ChemicalName',
-                       'Freq Err': 'FreqErr',
-                       'Meas Freq Err': 'MeasFreqErr',
-                       'Freq-GHz(rest frame,redshifted)': 'FreqGHz',
-                       'Freq Err(rest frame,redshifted)': 'eFreqGHz',
-                       'Meas Freq-GHz(rest frame,redshifted)': 'MeasFreqGHz',
-                       'Meas Freq Err(rest frame,redshifted)': 'eMeasFreqGHz',
-                       }
-
-
-def clean_column_headings(table, *, renaming_dict=column_headings_map):
+from bs4 import BeautifulSoup
+
+
+def clean_column_headings(table, *, renaming_dict={}):
     """
     Rename column headings to shorter version that are easier for display
     on-screen / at the terminal
+
+    As of March 2024, the default column names are all valid and no longer need
+    renaming.
     """
 
     for key in renaming_dict:
@@ -40,50 +21,30 @@ def clean_column_headings(table, *, renaming_dict=column_headings_map):
     return table
 
 
-def merge_frequencies(table, *, prefer='measured',
-                      theor_kwd='Freq-GHz(rest frame,redshifted)',
-                      meas_kwd='Meas Freq-GHz(rest frame,redshifted)'):
-    """
-    Replace "Freq-GHz" and "Meas Freq-GHz" with a single "Freq" column.
-
-    Parameters
-    ----------
-    table : table
-        The Splatalogue table
-    prefer: 'measured' or 'theoretical'
-        Which of the two columns to prefer if there is a conflict
-    """
-
-    if prefer == 'measured':
-        Freq = np.copy(table[theor_kwd]).astype('float')
-        if hasattr(table[meas_kwd], 'mask'):
-            measmask = np.logical_not(table[meas_kwd].mask)
-        else:
-            measmask = slice(None)  # equivalent to [:] - all data are good
-        Freq[measmask] = table[meas_kwd][measmask].astype('float')
-    elif prefer == 'theoretical':
-        Freq = np.copy(table[meas_kwd]).astype('float')
-        if hasattr(table[theor_kwd], 'mask'):
-            theomask = np.logical_not(table[theor_kwd].mask)
-        else:
-            theomask = slice(None)  # equivalent to [:] - all data are good
-        Freq[theomask] = table[theor_kwd][theomask].astype('float')
-    else:
-        raise ValueError('prefer must be one of "measured" or "theoretical"')
-
-    index = table.index_column(theor_kwd)
-    table.remove_columns([theor_kwd, meas_kwd])
-    newcol = astropy.table.Column(name='Freq', data=Freq)
-    table.add_column(newcol, index=index)
+def try_clean(row):
+    if row:
+        return BeautifulSoup(row, features='html5lib').text
 
-    return table
 
+def clean_columns(table):
+    """
+    Remove HTML tags in table columns
 
-def minimize_table(table, *, columns=['Species', 'Chemical Name',
-                                      'Resolved QNs',
-                                      'Freq-GHz(rest frame,redshifted)',
-                                      'Meas Freq-GHz(rest frame,redshifted)',
-                                      'Log<sub>10</sub> (A<sub>ij</sub>)',
+    (modifies table inplace)
+    """
+    for col in table.colnames:
+        # check for any html tag
+        if isinstance(table[col][0], str) and '<' in table[col][0]:
+            table[col] = [
+                try_clean(row)
+                for row in table[col]
+            ]
+
+
+def minimize_table(table, *, columns=['name', 'chemical_name',
+                                      'resolved_QNs',
+                                      'orderedfreq',
+                                      'aij',
                                       'E_U (K)'],
                    merge=True,
                    clean=True):
@@ -101,11 +62,17 @@ def minimize_table(table, *, columns=['Species', 'Chemical Name',
     clean_column_headings : bool
         Run clean_column_headings to shorted the headers?
     """
+    from .core import colname_mapping_feb2024
+
+    clean_columns(table)
+
+    columns = [colname_mapping_feb2024[c] if c in colname_mapping_feb2024 else c
+               for c in columns]
 
     table = table[columns]
 
     if merge:
-        table = merge_frequencies(table)
+        table.rename_column('orderedfreq', 'Freq')
     if clean:
         table = clean_column_headings(table)
 
diff --git a/docs/splatalogue/splatalogue.rst b/docs/splatalogue/splatalogue.rst
index 0ce76f10..31985fb8 100644
--- a/docs/splatalogue/splatalogue.rst
+++ b/docs/splatalogue/splatalogue.rst
@@ -104,32 +104,32 @@ size of the printout and assist with doctests; it is not needed as the default
 
    >>> from astropy import units as u
    >>> CO1to0 = Splatalogue.query_lines(115.271*u.GHz, 115.273*u.GHz)
-   >>> CO1to0.pprint(max_width=100)
-          Species                  Chemical Name             ...  E_U (K)   Linelist
-    ------------------- ------------------------------------ ... ---------- --------
-            GA-n-C4H9CN                      n-Butyl cyanide ...  332.23706     CDMS
-       NH2CH2CH2OHv26=1                         Aminoethanol ...  390.35352      JPL
-                  COv=0                      Carbon Monoxide ...    5.53211     CDMS
-                  COv=0                      Carbon Monoxide ...    5.53211      JPL
-                  COv=0                      Carbon Monoxide ...        0.0    Lovas
-                  COv=0                      Carbon Monoxide ...    5.53211    SLAIM
-                   FeCO                    Iron Monocarbonyl ...  103.95656     CDMS
-         CH3CHNH2COOH-I                      &alpha;-Alanine ...  129.92964     CDMS
-     s-trans-H2C=CHCOOH                       Propenoic acid ...   18.49667     CDMS
-          CH3CHOv=0,1&2                         Acetaldehyde ...  223.65667    SLAIM
-          CH3CHOv=0,1&2                         Acetaldehyde ...   223.6558      JPL
-                c-C5H5N                             Pyridine ...  230.47644     CDMS
-                c-C5H5N                             Pyridine ...  230.47644     CDMS
-             c-CH2CHCHO                             Propenal ... 1266.35462      JPL
-             c-CH2CHCHO                             Propenal ... 1266.35462      JPL
-       NH2CH2CH2OHv26=1                         Aminoethanol ...  766.11681      JPL
-       NH2CH2CH2OHv26=1                         Aminoethanol ...  766.11681      JPL
-       NH2CH2CH2OHv26=1                         Aminoethanol ...  766.11681      JPL
-       NH2CH2CH2OHv26=1                         Aminoethanol ...  766.11681      JPL
-    CH3O13CHO(TopModel)                       Methyl Formate ...  272.75041 TopModel
-       CH3O13CHO,vt=0,1 Methyl formate, v<sub>t</sub> = 0, 1 ...  272.75358     CDMS
-       H2NCH2COOH-IIv=1                              Glycine ...  2355.1427      JPL
-        cis-CH2OHCHOv=3                       Glycolaldehyde ...  887.56625      JPL
+   >>> CO1to0.pprint(max_width=200)
+    species_id                                          name                                                     chemical_name             ... searchErrorMessage sqlquery requestnumber
+    ---------- -------------------------------------------------------------------------------------- ------------------------------------ ... ------------------ -------- -------------
+         21228                                        <i>GA</i>-<i>n</i>-C<sub>4</sub>H<sub>9</sub>CN                      n-Butyl cyanide ...                        None             0
+          1288 NH<sub>2</sub>CH<sub>2</sub>CH<sub>2</sub>OH <font color="red">v<sub>26</sub>=1</font>                         Aminoethanol ...                        None             0
+           204                                                      CO <font color="red">v = 0</font>                      Carbon Monoxide ...                        None             0
+           204                                                      CO <font color="red">v = 0</font>                      Carbon Monoxide ...                        None             0
+           204                                                      CO <font color="red">v = 0</font>                      Carbon Monoxide ...                        None             0
+           204                                                      CO <font color="red">v = 0</font>                      Carbon Monoxide ...                        None             0
+             8                                                                                   FeCO                    Iron Monocarbonyl ...                        None             0
+          1321                                                 CH<sub>3</sub>CHNH<sub>2</sub>COOH - I                      &alpha;-Alanine ...                        None             0
+         21092                                                                     s-trans-H2C=CHCOOH                       Propenoic acid ...                        None             0
+           529                               CH<sub>3</sub>CHO <font color="red">v = 0, 1 & 2 </font>                         Acetaldehyde ...                        None             0
+           529                               CH<sub>3</sub>CHO <font color="red">v = 0, 1 & 2 </font>                         Acetaldehyde ...                        None             0
+         21067                                                   <i>c</i>-C<sub>5</sub>H<sub>5</sub>N                             Pyridine ...                        None             0
+         21067                                                   <i>c</i>-C<sub>5</sub>H<sub>5</sub>N                             Pyridine ...                        None             0
+          1275                                                           <i>c</i>-CH<sub>2</sub>CHCHO                             Propenal ...                        None             0
+          1275                                                           <i>c</i>-CH<sub>2</sub>CHCHO                             Propenal ...                        None             0
+          1288 NH<sub>2</sub>CH<sub>2</sub>CH<sub>2</sub>OH <font color="red">v<sub>26</sub>=1</font>                         Aminoethanol ...                        None             0
+          1288 NH<sub>2</sub>CH<sub>2</sub>CH<sub>2</sub>OH <font color="red">v<sub>26</sub>=1</font>                         Aminoethanol ...                        None             0
+          1288 NH<sub>2</sub>CH<sub>2</sub>CH<sub>2</sub>OH <font color="red">v<sub>26</sub>=1</font>                         Aminoethanol ...                        None             0
+          1288 NH<sub>2</sub>CH<sub>2</sub>CH<sub>2</sub>OH <font color="red">v<sub>26</sub>=1</font>                         Aminoethanol ...                        None             0
+          1370                                             CH<sub>3</sub>O<sup>13</sup>CHO (TopModel)                       Methyl Formate ...                        None             0
+         21026                                                                   CH3O13CHO, vt = 0, 1 Methyl formate, v<sub>t</sub> = 0, 1 ...                        None             0
+          1314                     H<sub>2</sub>NCH<sub>2</sub>COOH - II <font color="red">v=1</font>                              Glycine ...                        None             0
+          1284                                   cis-CH<sub>2</sub>OHCHO <font color="red">v=3</font>                       Glycolaldehyde ...                        None             0          
 
 Querying just by frequency isn't particularly effective; a nicer approach is to
 use both frequency and chemical name.  If you can remember that CO 2-1 is approximately
@@ -139,30 +139,30 @@ this query works:
 .. doctest-remote-data::
 
    >>> CO2to1 = Splatalogue.query_lines(1*u.mm, 2*u.mm, chemical_name=" CO ")
-   >>> CO2to1.pprint(max_width=100)
-   Species  Chemical Name  Freq-GHz(rest frame,redshifted) ... E_U (cm^-1)  E_U (K)   Linelist
-   ------- --------------- ------------------------------- ... ----------- ---------- --------
-     COv=3 Carbon Monoxide                     224.2417699 ...    6361.659  9152.9556     CDMS
-     COv=2 Carbon Monoxide                              -- ...   4271.3871  6145.5379     CDMS
-     COv=2 Carbon Monoxide                      226.340357 ...   4271.3869 6145.53761    SLAIM
-     COv=1 Carbon Monoxide                              -- ...  2154.70101 3100.11628     CDMS
-     COv=1 Carbon Monoxide                       228.43911 ...  2154.70191 3100.11758    SLAIM
-     COv=0 Carbon Monoxide                              -- ...    11.53492   16.59608     CDMS
-     COv=0 Carbon Monoxide                              -- ...    11.53492   16.59608      JPL
-     COv=0 Carbon Monoxide                         230.538 ...         0.0        0.0    Lovas
-     COv=0 Carbon Monoxide                         230.538 ...    11.53492   16.59608    SLAIM
+   >>> CO2to1.pprint(max_width=200)
+   species_id                name                chemical_name  resolved_QNs linelist LovasASTIntensity ... telescope_Lovas_NIST transitionBandColor  searchErrorMessage sqlquery requestnumber
+    ---------- --------------------------------- --------------- ------------ -------- ----------------- ... -------------------- -------------------- ------------------ -------- -------------
+          1343        CO <font color="red">v = 3 Carbon Monoxide         2- 1     CDMS                   ...                      datatablelightpurple                        None             0
+           991 CO <font color="red">v = 2</font> Carbon Monoxide         2- 1     CDMS                   ...                      datatablelightpurple                        None             0
+           991 CO <font color="red">v = 2</font> Carbon Monoxide         2- 1    SLAIM                   ...                      datatablelightpurple                        None             0
+           990 CO <font color="red">v = 1</font> Carbon Monoxide         2- 1     CDMS                   ...                      datatablelightpurple                        None             0
+           990 CO <font color="red">v = 1</font> Carbon Monoxide         2- 1    SLAIM           0.62 Jy ...                      datatablelightpurple                        None             0
+           204 CO <font color="red">v = 0</font> Carbon Monoxide          2-1     CDMS               70. ...         NRAO     11m datatablelightpurple                        None             0
+           204 CO <font color="red">v = 0</font> Carbon Monoxide          2-1      JPL                   ...                      datatablelightpurple                        None             0
+           204 CO <font color="red">v = 0</font> Carbon Monoxide          2-1    Lovas               70. ...         NRAO     11m datatablelightpurple                        None             0
+           204 CO <font color="red">v = 0</font> Carbon Monoxide         2- 1    SLAIM               70. ...                      datatablelightpurple                        None             0
 
 Of course, there's some noise in there: both the vibrationally excited line and a whole lot of different line lists.
 Start by thinning out the line lists used:
 
 .. doctest-remote-data::
 
-   >>> CO2to1 = Splatalogue.query_lines(1*u.mm, 2*u.mm, chemical_name=" CO ",only_NRAO_recommended=True)
-   >>> CO2to1.pprint(max_width=100)
-   Species  Chemical Name  Freq-GHz(rest frame,redshifted) ... E_U (cm^-1)  E_U (K)   Linelist
-    ------- --------------- ------------------------------- ... ----------- ---------- --------
-      COv=1 Carbon Monoxide                              -- ...  2154.70101 3100.11628     CDMS
-      COv=0 Carbon Monoxide                              -- ...    11.53492   16.59608     CDMS
+   >>> CO2to1 = Splatalogue.query_lines(1*u.mm, 2*u.mm, chemical_name=" CO ", only_NRAO_recommended=True)
+   >>> CO2to1.pprint(max_width=200)
+    species_id                name                chemical_name  resolved_QNs linelist LovasASTIntensity ... telescope_Lovas_NIST transitionBandColor  searchErrorMessage sqlquery requestnumber
+    ---------- --------------------------------- --------------- ------------ -------- ----------------- ... -------------------- -------------------- ------------------ -------- -------------
+           990 CO <font color="red">v = 1</font> Carbon Monoxide         2- 1     CDMS                   ...                      datatablelightpurple                        None             0
+           204 CO <font color="red">v = 0</font> Carbon Monoxide          2-1     CDMS               70. ...         NRAO     11m datatablelightpurple                        None             0
 
 Then get rid of the vibrationally excited line by setting an energy upper limit in Kelvin:
 
@@ -171,10 +171,10 @@ Then get rid of the vibrationally excited line by setting an energy upper limit
    >>> CO2to1 = Splatalogue.query_lines(1*u.mm, 2*u.mm, chemical_name=" CO ",
    ...                                  only_NRAO_recommended=True,
    ...                                  energy_max=50, energy_type='eu_k')
-   >>> CO2to1.pprint(max_width=100)
-   Species  Chemical Name  Freq-GHz(rest frame,redshifted) ... E_U (cm^-1) E_U (K)  Linelist
-   ------- --------------- ------------------------------- ... ----------- -------- --------
-     COv=0 Carbon Monoxide                              -- ...    11.53492 16.59608     CDMS
+   >>> CO2to1.pprint(max_width=200)
+   species_id                name                chemical_name  resolved_QNs linelist LovasASTIntensity ... telescope_Lovas_NIST transitionBandColor  searchErrorMessage sqlquery requestnumber
+    ---------- --------------------------------- --------------- ------------ -------- ----------------- ... -------------------- -------------------- ------------------ -------- -------------
+           204 CO <font color="red">v = 0</font> Carbon Monoxide          2-1     CDMS               70. ...         NRAO     11m datatablelightpurple                        None             0
 
 A note on recombination lines
 -----------------------------
@@ -189,25 +189,25 @@ these symbols (Hα, Hβ, Hγ, Hδ, Hε, Hζ), even though they will show up as
 .. doctest-remote-data::
 
    >>> ha_result = Splatalogue.query_lines(84*u.GHz, 115*u.GHz, chemical_name='Hα')
-   >>> ha_result.pprint(max_width=100)
-   Species         Chemical Name        Freq-GHz(rest frame,redshifted) ... E_U (K) Linelist
-   -------- --------------------------- ------------------------------- ... ------- --------
-   H&alpha; Hydrogen Recombination Line                        85.68839 ...     0.0   Recomb
-   H&alpha; Hydrogen Recombination Line                       92.034434 ...     0.0   Recomb
-   H&alpha; Hydrogen Recombination Line                       99.022952 ...     0.0   Recomb
-   H&alpha; Hydrogen Recombination Line                      106.737357 ...     0.0   Recomb
+   >>> ha_result.pprint(max_width=200)
+    species_id   name          chemical_name           resolved_QNs    linelist LovasASTIntensity ... source_Lovas_NIST telescope_Lovas_NIST transitionBandColor searchErrorMessage sqlquery requestnumber
+    ---------- -------- --------------------------- ------------------ -------- ----------------- ... ----------------- -------------------- ------------------- ------------------ -------- -------------
+          1154 H&alpha; Hydrogen Recombination Line  H ( 42 ) &alpha;    Recomb                   ...                                           datatableskyblue                        None             0
+          1154 H&alpha; Hydrogen Recombination Line  H ( 41 ) &alpha;    Recomb                   ...                                           datatableskyblue                        None             0
+          1154 H&alpha; Hydrogen Recombination Line  H ( 40 ) &alpha;    Recomb                   ...                                           datatableskyblue                        None             0
+          1154 H&alpha; Hydrogen Recombination Line  H ( 39 ) &alpha;    Recomb                   ...                                           datatableskyblue                        None             0
 
 You could also search by specifying the line list
 
 .. doctest-remote-data::
 
-    >>> recomb_result = Splatalogue.query_lines(84*u.GHz, 85*u.GHz, line_lists=['Recomb'])
-    >>> recomb_result.pprint(max_width=100)
-     Species         Chemical Name        Freq-GHz(rest frame,redshifted) ... E_U (K) Linelist
-    --------- --------------------------- ------------------------------- ... ------- --------
-     H&gamma; Hydrogen Recombination Line                       84.914394 ...     0.0   Recomb
-    He&gamma;   Helium Recombination Line                       84.948997 ...     0.0   Recomb
-     C&gamma;   Carbon Recombination Line                       84.956762 ...     0.0   Recomb
+    >>> recomb_result = Splatalogue.query_lines(84*u.GHz, 85*u.GHz, line_lists=['Recombination'])
+    >>> recomb_result.pprint(max_width=200)
+    species_id    name          chemical_name            resolved_QNs    linelist LovasASTIntensity ... source_Lovas_NIST telescope_Lovas_NIST transitionBandColor searchErrorMessage sqlquery requestnumber
+    ---------- --------- --------------------------- ------------------- -------- ----------------- ... ----------------- -------------------- ------------------- ------------------ -------- -------------
+          1156  H&gamma; Hydrogen Recombination Line   H ( 60 ) &gamma;    Recomb                   ...                                           datatableskyblue                        None             0
+          1162 He&gamma;   Helium Recombination Line  He ( 60 ) &gamma;    Recomb                   ...                                           datatableskyblue                        None             0
+          1166  C&gamma;   Carbon Recombination Line   C ( 60 ) &gamma;    Recomb                   ...                                           datatableskyblue                        None             0
 
 Cleaning Up the Returned Data
 -----------------------------
@@ -218,48 +218,37 @@ regular basis.  For example, if you want data returned preferentially in units
 of K rather than inverse cm, you're interested in low-energy lines, and you want your
 data sorted by energy, you can use an approach like this:
 
-(note that as of March 2023, there is an upstream error in which the ``noHFS`` keyword
-is not respected; we include it here as a demonstration in the hope that that error will
-be fixed)
-
 .. doctest-remote-data::
 
     >>> S = Splatalogue(energy_max=500,
-    ...    energy_type='eu_k',energy_levels=['el4'],
-    ...    line_strengths=['ls4'],
-    ...    only_NRAO_recommended=True,
-    ...    noHFS=True,
-    ...    displayHFS=False)
+    ...    energy_type='eu_k', energy_levels=['Four'],
+    ...    line_strengths=['CDMSJPL'])
     >>> def trimmed_query(*args,**kwargs):
-    ...     columns = ('Species','Chemical Name','Resolved QNs',
-    ...                'Freq-GHz(rest frame,redshifted)',
-    ...                'Meas Freq-GHz(rest frame,redshifted)',
-    ...                'Log<sub>10</sub> (A<sub>ij</sub>)',
-    ...                'E_U (K)')
+    ...     columns = ('species_id', 'chemical_name', 'name', 'resolved_QNs',
+    ...                'orderedfreq',
+    ...                'aij',
+    ...                'upper_state_energy_K')
     ...     table = S.query_lines(*args, **kwargs)[columns]
-    ...     table.rename_column('Log<sub>10</sub> (A<sub>ij</sub>)','log10(Aij)')
-    ...     table.rename_column('E_U (K)','EU_K')
-    ...     table.rename_column('Resolved QNs','QNs')
-    ...     table.rename_column('Freq-GHz(rest frame,redshifted)', 'Freq-GHz'),
-    ...     table.rename_column('Meas Freq-GHz(rest frame,redshifted)', 'Meas Freq-GHz'),
-    ...     table.sort('EU_K')
+    ...     table.sort('upper_state_energy_K')
     ...     return table
     >>> trimmed_query(1*u.GHz,30*u.GHz,
     ...     chemical_name='(H2.*Formaldehyde)|( HDCO )',
-    ...     energy_max=50)[:10].pprint(max_width=100)
-    Species Chemical Name         QNs          Freq-GHz Meas Freq-GHz log10(Aij)   EU_K
-    ------- ------------- ------------------- --------- ------------- ---------- --------
-       HDCO  Formaldehyde       1(1,0)-1(1,1)        --     5.3461416   -8.31616 11.18301
-     H2C18O  Formaldehyde 1(1,0)-1(1,1),F=1-0 4.3887783            --    -9.0498 15.30206
-     H2C18O  Formaldehyde 1(1,0)-1(1,1),F=0-1 4.3887957            --   -8.57268 15.30206
-     H2C18O  Formaldehyde 1(1,0)-1(1,1),F=2-2 4.3887965            --   -8.69765 15.30206
-     H2C18O  Formaldehyde       1(1,0)-1(1,1)  4.388797            --   -8.57272 15.30206
-     H2C18O  Formaldehyde 1(1,0)-1(1,1),F=2-1 4.3888012            --   -9.17475 15.30206
-     H2C18O  Formaldehyde 1(1,0)-1(1,1),F=1-2 4.3888036            --    -8.9529 15.30206
-     H2C18O  Formaldehyde 1(1,0)-1(1,1),F=1-1 4.3888083            --    -9.1748 15.30206
-     H213CO  Formaldehyde       1(1,0)-1(1,1)        --     4.5930885   -8.51332 15.34693
-       H2CO  Formaldehyde 1(1,0)-1(1,1),F=1-2 4.8296665            --   -8.82819 15.39497
-
+    ...     energy_max=50)[:10].pprint(max_width=150)
+    species_id chemical_name             name                     resolved_QNs         orderedfreq   aij    upper_state_energy_K
+    ---------- ------------- ---------------------------- ---------------------------- ----------- -------- --------------------
+           109  Formaldehyde                         HDCO       1(  1, 0)-   1(  1, 1)    5346.142 -8.44112             11.18258
+           109  Formaldehyde                         HDCO           1( 1, 0)- 1( 1, 1)   5346.1616 -8.31295             11.18287
+           109  Formaldehyde                         HDCO              1(1,0) - 1(1,1)   5346.1416 -8.31616             11.18301
+           155  Formaldehyde H<sub>2</sub>C<sup>18</sup>O       1(  1, 0)-   1(  1, 1)    4388.797 -8.22052             15.30187
+           155  Formaldehyde H<sub>2</sub>C<sup>18</sup>O  1( 1, 0)- 1( 1, 1), F= 1- 0   4388.7783  -9.0498             15.30206
+           155  Formaldehyde H<sub>2</sub>C<sup>18</sup>O  1( 1, 0)- 1( 1, 1), F= 0- 1   4388.7957 -8.57268             15.30206
+           155  Formaldehyde H<sub>2</sub>C<sup>18</sup>O  1( 1, 0)- 1( 1, 1), F= 2- 2   4388.7965 -8.69765             15.30206
+           155  Formaldehyde H<sub>2</sub>C<sup>18</sup>O              1(1,0) - 1(1,1)    4388.797 -8.57272             15.30206
+           155  Formaldehyde H<sub>2</sub>C<sup>18</sup>O  1( 1, 0)- 1( 1, 1), F= 2- 1   4388.8012 -9.17475             15.30206
+           155  Formaldehyde H<sub>2</sub>C<sup>18</sup>O  1( 1, 0)- 1( 1, 1), F= 1- 2   4388.8036  -8.9529             15.30206
+
+There are utility functions in ``astroquery.splatalogue.utils`` that automate
+some of the above cleanup.
 
 Troubleshooting
 ===============


Test patch:
diff --git a/astroquery/splatalogue/tests/conftest.py b/astroquery/splatalogue/tests/conftest.py
index 6fd73cc1..a60bcd41 100644
--- a/astroquery/splatalogue/tests/conftest.py
+++ b/astroquery/splatalogue/tests/conftest.py
@@ -6,7 +6,7 @@ import requests
 from astroquery.utils.mocks import MockResponse
 
 
-SPLAT_DATA = 'CO_colons.csv'
+SPLAT_DATA = 'CO.json'
 
 
 def data_path(filename):
diff --git a/astroquery/splatalogue/tests/data/CO.json b/astroquery/splatalogue/tests/data/CO.json
new file mode 100644
index 00000000..fa6a201b
--- /dev/null
+++ b/astroquery/splatalogue/tests/data/CO.json
@@ -0,0 +1,1 @@
+[{"species_id": 990, "name": "CO <font color=\"red\">v = 1</font>", "chemical_name": "Carbon Monoxide", "resolved_QNs": " 1- 0", "linelist": "CDMS", "LovasASTIntensity": " ", "lower_state_energy": 2143.2711, "upper_state_energy": 2147.08113, "sijmu2": 0.00723, "sij": 1.0, "aij": -7.37879, "intintensity": "-9.7069", "Lovas_NRAO": 1, "orderedfreq": 114221.7523, "lower_state_energy_K": 3083.67129, "upper_state_energy_K": 3089.15304, "orderedFreq": "114221.7523 (0.0013), <span style = 'color: #DC143C'>114221.7523</span>", "measFreq": " <span style = 'color: #DC143C'></span>", "upperStateDegen": "3", "moleculeTag": 28512, "qnCode": 1202, "labref_Lovas_NIST": " ", "rel_int_HFS_Lovas": " ", "unres_quantum_numbers": " 1 1         0 1", "lineid": 6187001, "transition_in_space": 0, "transition_in_G358": 0, "obsref_Lovas_NIST": " ", "source_Lovas_NIST": " ", "telescope_Lovas_NIST": " ", "orderFreqColName": "Freq in GHz (Err)<br>(rest frame, <p class = 'search-results-red search-results-para'>redshifted<span class = 'search-results-black search-results-para'>)</span></p>", "measFreqColName": "Meas Freq in GHz (Err)<br>(rest frame, <p  class = 'search-results-red search-results-para'>redshifted<span class = 'search-results-black search-results-para'>)</span></p>", "transitionBandColor": "datatableskyblue", "searchErrorMessage": "", "sqlquery": null}, {"species_id": 990, "name": "CO <font color=\"red\">v = 1</font>", "chemical_name": "Carbon Monoxide", "resolved_QNs": " 1- 0", "linelist": "SLAIM", "LovasASTIntensity": " ", "lower_state_energy": 2143.272, "upper_state_energy": 2147.08203, "sijmu2": 0.01212, "sij": 1.0, "aij": -7.15428, "intintensity": "", "Lovas_NRAO": 0, "orderedfreq": 114221.757, "lower_state_energy_K": 3083.67258, "upper_state_energy_K": 3089.15433, "orderedFreq": "114221.757 (0.003), <span style = 'color: #DC143C'>114221.757</span>", "measFreq": "114221.74 (0.04), <span style = 'color: #DC143C'>114221.74</span>", "upperStateDegen": "3", "moleculeTag": 0, "qnCode": 0, "labref_Lovas_NIST": "   Dix77", "rel_int_HFS_Lovas": "", "unres_quantum_numbers": "      1        -   0 v=1", "lineid": 3768099, "transition_in_space": 0, "transition_in_G358": 0, "obsref_Lovas_NIST": " ", "source_Lovas_NIST": " ", "telescope_Lovas_NIST": " ", "orderFreqColName": null, "measFreqColName": null, "transitionBandColor": "datatableskyblue", "searchErrorMessage": "", "sqlquery": null}, {"species_id": 204, "name": "CO <font color=\"red\">v = 0</font>", "chemical_name": "Carbon Monoxide", "resolved_QNs": "1-0", "linelist": "CDMS", "LovasASTIntensity": "60.0", "lower_state_energy": 0.0, "upper_state_energy": 3.84503, "sijmu2": 0.01212, "sij": 1.0, "aij": -7.14246, "intintensity": "-5.0105", "Lovas_NRAO": 1, "orderedfreq": 115271.2018, "lower_state_energy_K": 0.0, "upper_state_energy_K": 5.53211, "orderedFreq": " <span style = 'color: #DC143C'></span>", "measFreq": "115271.2018 (5.0E-4), <span style = 'color: #DC143C'>115271.2018</span>", "upperStateDegen": "3", "moleculeTag": -28503, "qnCode": 101, "labref_Lovas_NIST": " ", "rel_int_HFS_Lovas": " ", "unres_quantum_numbers": "J=1-0", "lineid": 363613, "transition_in_space": 0, "transition_in_G358": 0, "obsref_Lovas_NIST": "Uli76", "source_Lovas_NIST": " OriMC-1", "telescope_Lovas_NIST": " NRAO     11m", "orderFreqColName": null, "measFreqColName": null, "transitionBandColor": "datatableskyblue", "searchErrorMessage": "", "sqlquery": null}, {"species_id": 204, "name": "CO <font color=\"red\">v = 0</font>", "chemical_name": "Carbon Monoxide", "resolved_QNs": "1-0", "linelist": "JPL", "LovasASTIntensity": " ", "lower_state_energy": 0.0, "upper_state_energy": 3.84503, "sijmu2": 0.01212, "sij": 1.0, "aij": -7.14246, "intintensity": "-5.0105", "Lovas_NRAO": 0, "orderedfreq": 115271.2018, "lower_state_energy_K": 0.0, "upper_state_energy_K": 5.53211, "orderedFreq": " <span style = 'color: #DC143C'></span>", "measFreq": "115271.2018 (5.0E-4), <span style = 'color: #DC143C'>115271.2018</span>", "upperStateDegen": "3", "moleculeTag": -28001, "qnCode": 101, "labref_Lovas_NIST": " ", "rel_int_HFS_Lovas": " ", "unres_quantum_numbers": "J=1-0", "lineid": 824116, "transition_in_space": 0, "transition_in_G358": 0, "obsref_Lovas_NIST": " ", "source_Lovas_NIST": " ", "telescope_Lovas_NIST": " ", "orderFreqColName": null, "measFreqColName": null, "transitionBandColor": "datatableskyblue", "searchErrorMessage": "", "sqlquery": null}, {"species_id": 204, "name": "CO <font color=\"red\">v = 0</font>", "chemical_name": "Carbon Monoxide", "resolved_QNs": "1-0", "linelist": "Lovas/NIST", "LovasASTIntensity": "60.0", "lower_state_energy": 0.0, "upper_state_energy": 0.0, "sijmu2": 0.0, "sij": 0.0, "aij": 0.0, "intintensity": "", "Lovas_NRAO": 0, "orderedfreq": 115271.202, "lower_state_energy_K": 0.0, "upper_state_energy_K": 0.0, "orderedFreq": "115271.202 (0.001), <span style = 'color: #DC143C'>115271.202</span>", "measFreq": " <span style = 'color: #DC143C'></span>", "upperStateDegen": "", "moleculeTag": 0, "qnCode": 0, "labref_Lovas_NIST": "", "rel_int_HFS_Lovas": " ", "unres_quantum_numbers": "1-0", "lineid": 3732287, "transition_in_space": 0, "transition_in_G358": 0, "obsref_Lovas_NIST": "Uli76", "source_Lovas_NIST": " OriMC-1", "telescope_Lovas_NIST": " NRAO     11m", "orderFreqColName": null, "measFreqColName": null, "transitionBandColor": "datatableskyblue", "searchErrorMessage": "", "sqlquery": null}, {"species_id": 204, "name": "CO <font color=\"red\">v = 0</font>", "chemical_name": "Carbon Monoxide", "resolved_QNs": " 1- 0", "linelist": "SLAIM", "LovasASTIntensity": "60.0", "lower_state_energy": 0.0, "upper_state_energy": 3.84503, "sijmu2": 0.01212, "sij": 1.0, "aij": -7.14236, "intintensity": "", "Lovas_NRAO": 0, "orderedfreq": 115271.202, "lower_state_energy_K": 0.0, "upper_state_energy_K": 5.53211, "orderedFreq": "115271.202, <span style = 'color: #DC143C'>115271.202</span>", "measFreq": "115271.202 (0.001), <span style = 'color: #DC143C'>115271.202</span>", "upperStateDegen": "3", "moleculeTag": 0, "qnCode": 0, "labref_Lovas_NIST": "   Win97", "rel_int_HFS_Lovas": "", "unres_quantum_numbers": "      1        -   0 v=0", "lineid": 3768098, "transition_in_space": 1, "transition_in_G358": 0, "obsref_Lovas_NIST": " ", "source_Lovas_NIST": " ", "telescope_Lovas_NIST": " ", "orderFreqColName": null, "measFreqColName": null, "transitionBandColor": "datatableskyblue", "searchErrorMessage": "", "sqlquery": null}, {"species_id": null, "name": null, "chemical_name": null, "resolved_QNs": null, "linelist": null, "LovasASTIntensity": null, "lower_state_energy": null, "upper_state_energy": null, "sijmu2": null, "sij": null, "aij": null, "intintensity": null, "Lovas_NRAO": null, "orderedfreq": null, "lower_state_energy_K": null, "upper_state_energy_K": null, "orderedFreq": null, "measFreq": null, "upperStateDegen": null, "moleculeTag": null, "qnCode": null, "labref_Lovas_NIST": null, "rel_int_HFS_Lovas": null, "unres_quantum_numbers": null, "lineid": null, "transition_in_space": null, "transition_in_G358": null, "obsref_Lovas_NIST": null, "source_Lovas_NIST": null, "telescope_Lovas_NIST": null, "orderFreqColName": null, "measFreqColName": null, "transitionBandColor": null, "searchErrorMessage": null, "sqlquery": "SELECT /*+ MAX_EXECUTION_TIME(60000) */species.species_id, species.name, species.chemical_name, main.resolved_QNs, main.frequency, main.uncertainty, main.measfreq, main.measerrfreq,  main.rel_int_HFS_Lovas, main.quantum_numbers, main.upper_state_degeneracy, main.molecule_tag, main.qn_code, main.labref_Lovas_NIST, main.line_id  ,main.transition_in_space,  main.transition_in_G358, main.obsref_Lovas_NIST, main.source_Lovas_NIST, main.telescope_Lovas_NIST , linelists.linelist,  main.lower_state_energy ,main.upper_state_energy ,main.upper_state_energy_K ,main.lower_state_energy_K , main.sijmu2, main.aij, main.sij, main.intintensity,  main.obsintensity_Lovas_NIST as LovasASTIntensity , main.Lovas_NRAO, main.orderedfreq, main.lower_state_energy_K, main.upper_state_energy_K  FROM main  INNER JOIN species ON main.species_id = species.species_id  INNER JOIN linelists ON main.ll_id = linelists.ll_id AND main.ll_id IN ( 10 ,11 , 12 ,14 ,15 ,16 ,17 ,18 ,19 ) AND (main.species_id = 204 OR main.species_id = 990 OR main.species_id = 991 OR main.species_id = 1343)  AND (main.`v3.0` != 0) AND((main.orderedfreq >= 114000.0 AND main.orderedfreq <= 116000.0)) ORDER BY main.orderedfreq"}]
\ No newline at end of file
diff --git a/astroquery/splatalogue/tests/data/CO_colons.csv b/astroquery/splatalogue/tests/data/CO_colons.csv
deleted file mode 100644
index 6541c3b9..00000000
--- a/astroquery/splatalogue/tests/data/CO_colons.csv
+++ /dev/null
@@ -1,7 +0,0 @@
-Species:Chemical Name:Freq-GHz(rest frame,redshifted):Freq Err(rest frame,redshifted):Meas Freq-GHz(rest frame,redshifted):Meas Freq Err(rest frame,redshifted):Resolved QNs:CDMS/JPL Intensity:S<sub>ij</sub>&#956;<sup>2</sup> (D<sup>2</sup>):S<sub>ij</sub>:Log<sub>10</sub> (A<sub>ij</sub>):Lovas/AST Intensity:E_L (cm^-1):E_L (K):E_U (cm^-1):E_U (K):Linelist
-COv=1:Carbon Monoxide:114.2217523:1.3e-06:::1-0:-9.7069:0.00723:1.0:-7.37879::2143.2711:3083.67129:2147.08113:3089.15304:CDMS
-COv=1:Carbon Monoxide:114.221757:3e-06:114.22174:4e-05:1-0:0.0:0.01212:1.0:-7.15428::2143.272:3083.67258:2147.08203:3089.15433:SLAIM
-COv=0:Carbon Monoxide:::115.2712018:5e-07:1-0:-5.0105:0.01212:1.0:-7.14246:60.0:0.0:0.0:3.84503:5.53211:CDMS
-COv=0:Carbon Monoxide:::115.2712018:5e-07:1-0:-5.0105:0.01212:1.0:-7.14246::0.0:0.0:3.84503:5.53211:JPL
-COv=0:Carbon Monoxide:115.271202:1e-06:::1-0:0.0:0.0:0.0:0.0:60.0:0.0:0.0:0.0:0.0:Lovas
-COv=0:Carbon Monoxide:115.271202:0.0:115.271202:1e-06:1-0:0.0:0.01212:1.0:-7.14236:60.0:0.0:0.0:3.84503:5.53211:SLAIM
diff --git a/astroquery/splatalogue/tests/test_splatalogue.py b/astroquery/splatalogue/tests/test_splatalogue.py
index 45ad70fc..a0720768 100644
--- a/astroquery/splatalogue/tests/test_splatalogue.py
+++ b/astroquery/splatalogue/tests/test_splatalogue.py
@@ -1,19 +1,11 @@
 # Licensed under a 3-clause BSD style license - see LICENSE.rst
 
-import os
 import pytest
+import json
 
 from astropy import units as u
 
-from ... import splatalogue
-
-
-SPLAT_DATA = 'CO_colons.csv'
-
-
-def data_path(filename):
-    data_dir = os.path.join(os.path.dirname(__file__), 'data')
-    return os.path.join(data_dir, filename)
+from astroquery import splatalogue
 
 
 def test_simple(patch_post):
@@ -22,8 +14,15 @@ def test_simple(patch_post):
                                         chemical_name=' CO ')
 
 
+def test_backward_freqs(patch_post):
+    """ check that reversed frequencies still work """
+    splatalogue.Splatalogue.query_lines(min_frequency=116 * u.GHz,
+                                        max_frequency=114 * u.GHz,
+                                        chemical_name=' CO ')
+
+
 @pytest.mark.remote_data
-def test_init(patch_post):
+def test_init_remote():
     x = splatalogue.Splatalogue.query_lines(min_frequency=114 * u.GHz,
                                             max_frequency=116 * u.GHz,
                                             chemical_name=' CO ')
@@ -33,8 +32,20 @@ def test_init(patch_post):
     # masked arrays fail
     # assert y == x
     assert len(x) == len(y)
-    assert all(y['Species'] == x['Species'])
-    assert all(x['Chemical Name'] == y['Chemical Name'])
+    assert all(y['species_id'] == x['species_id'])
+    assert all(y['name'] == x['name'])
+    assert all(y['chemical_name'] == x['chemical_name'])
+
+
+def test_init():
+    splat = splatalogue.Splatalogue(chemical_name=' CO ')
+    assert splat.data['speciesSelectBox'] == ['204', '990', '991', '1343']
+    payload = splat.query_lines(min_frequency=114 * u.GHz, max_frequency=116 * u.GHz,
+                                get_query_payload=True)
+    payload = json.loads(payload['body'])
+    assert payload['speciesSelectBox'] == ['204', '990', '991', '1343']
+    assert payload['userInputFrequenciesFrom'] == [114.0]
+    assert payload['userInputFrequenciesTo'] == [116.0]
 
 
 def test_load_species_table():
@@ -45,20 +56,24 @@ def test_load_species_table():
 
 # regression test: get_query_payload should work (#308)
 def test_get_payload():
-    q = splatalogue.core.Splatalogue.query_lines_async(min_frequency=1 * u.GHz,
-                                                       max_frequency=10 * u.GHz,
-                                                       get_query_payload=True)
-    assert '__utma' in q
+    payload = splatalogue.core.Splatalogue.query_lines_async(min_frequency=1 * u.GHz,
+                                                             max_frequency=10 * u.GHz,
+                                                             get_query_payload=True)
+    payload = json.loads(payload['body'])
+    assert payload["userInputFrequenciesFrom"] == [1.0]
+    assert payload["userInputFrequenciesTo"] == [10.0]
 
 
 # regression test: line lists should ask for only one line list, not all
 def test_line_lists():
-    q = splatalogue.core.Splatalogue.query_lines_async(min_frequency=1 * u.GHz,
-                                                       max_frequency=10 * u.GHz,
-                                                       line_lists=['JPL'],
-                                                       get_query_payload=True)
-    assert q['displayJPL'] == 'displayJPL'
-    assert q['displaySLAIM'] == ''
+    payload = splatalogue.core.Splatalogue.query_lines_async(min_frequency=1 * u.GHz,
+                                                             max_frequency=10 * u.GHz,
+                                                             line_lists=['JPL'],
+                                                             get_query_payload=True)
+    payload = json.loads(payload['body'])
+    assert payload['lineListDisplayJPL']
+    assert not payload['lineListDisplaySLAIM']
+    assert not payload['lineListDisplayCDMS']
 
 
 # regression test: raise an exception if a string is passed to line_lists
@@ -73,67 +88,33 @@ def test_linelist_type():
                                  "names.  See Splatalogue.ALL_LINE_LISTS")
 
 
-def test_top20_crashorno():
-    splatalogue.core.Splatalogue.query_lines_async(min_frequency=114 * u.GHz,
-                                                   max_frequency=116 * u.GHz,
-                                                   top20='top20',
-                                                   get_query_payload=True)
-    with pytest.raises(ValueError) as exc:
-        splatalogue.core.Splatalogue.query_lines_async(
-            min_frequency=114 * u.GHz, max_frequency=116 * u.GHz,
-            top20='invalid', get_query_payload=True)
-    assert exc.value.args[0] == "Top20 is not one of the allowed values"
-
-
-def test_band_crashorno():
-    splatalogue.core.Splatalogue.query_lines_async(band='alma3',
-                                                   get_query_payload=True)
-    with pytest.raises(ValueError) as exc:
-        splatalogue.core.Splatalogue.query_lines_async(band='invalid',
-                                                       get_query_payload=True)
-    assert exc.value.args[0] == "Invalid frequency band."
-
-
-# Upstream changed: there is no distinction between versions for this molecule
-# # regression test : version selection should work
-# # Unfortunately, it looks like version1 = version2 on the web page now, so this
-# # may no longer be a valid test
-# @pytest.mark.remote_data
-# def test_version_selection():
-#     results = splatalogue.Splatalogue.query_lines(
-# 			    min_frequency= 703*u.GHz,
-# 			    max_frequency=706*u.GHz,
-# 			    chemical_name='Acetaldehyde',
-# 			    version='v1.0'
-# 			    )
-#     assert len(results)==1
-
 def test_exclude(patch_post):
     # regression test for issue 616
-    d = splatalogue.Splatalogue.query_lines_async(min_frequency=114 * u.GHz,
-                                                  max_frequency=116 * u.GHz,
-                                                  chemical_name=' CO ',
-                                                  exclude=None,
-                                                  get_query_payload=True)
-
-    exclusions = {'no_atmospheric': 'no_atmospheric',
-                  'no_potential': 'no_potential',
-                  'no_probable': 'no_probable', }
+    payload = splatalogue.Splatalogue.query_lines_async(min_frequency=114 * u.GHz,
+                                                        max_frequency=116 * u.GHz,
+                                                        chemical_name=' CO ',
+                                                        exclude=None,
+                                                        get_query_payload=True)
+
+    payload = json.loads(payload['body'])
+    exclusions = {'excludePotentialInterstellarSpecies': False,
+                  'excludeAtmosSpecies': False,
+                  'excludeProbableInterstellarSpecies': False,
+                  'excludeKnownASTSpecies': False}
 
     for k, v in exclusions.items():
-        assert d[k] == v
+        assert payload[k] == v
 
-    d = splatalogue.Splatalogue.query_lines_async(min_frequency=114 * u.GHz,
-                                                  max_frequency=116 * u.GHz,
-                                                  chemical_name=' CO ',
-                                                  exclude='none',
-                                                  get_query_payload=True)
+    # 'none' doesn't mean None, but it should have the same effect
+    payload = splatalogue.Splatalogue.query_lines_async(min_frequency=114 * u.GHz,
+                                                        max_frequency=116 * u.GHz,
+                                                        chemical_name=' CO ',
+                                                        exclude='none',
+                                                        get_query_payload=True)
+    payload = json.loads(payload['body'])
 
-    for k, v in exclusions.items():
-        assert k not in d
-
-    for k in d:
-        assert k[:3] != 'no_'
+    for key in exclusions:
+        assert not payload[key]
 
 
 @pytest.mark.remote_data
@@ -146,3 +127,20 @@ def test_exclude_remote():
         chemical_name='Formaldehyde',
         exclude='none')
     assert len(results) >= 1
+
+
+@pytest.mark.remote_data
+def test_energy_limits():
+    # first, check that there are high-energy things to exclude
+    rslt = splatalogue.Splatalogue.query_lines(min_frequency=114 * u.GHz,
+                                               max_frequency=116 * u.GHz,
+                                               chemical_name=' CO ')
+    assert rslt['upper_state_energy'].max() > 1000
+
+    # then, verify that they are successfully excluded
+    rslt = splatalogue.Splatalogue.query_lines(min_frequency=114 * u.GHz,
+                                               max_frequency=116 * u.GHz,
+                                               energy_max=1000,
+                                               energy_min=0,
+                                               chemical_name=' CO ')
+    assert rslt['upper_state_energy'].max() < 5
diff --git a/astroquery/splatalogue/tests/test_utils.py b/astroquery/splatalogue/tests/test_utils.py
index b37514c2..527c98a0 100644
--- a/astroquery/splatalogue/tests/test_utils.py
+++ b/astroquery/splatalogue/tests/test_utils.py
@@ -13,16 +13,7 @@ def test_clean(patch_post):
                                             chemical_name=' CO ')
     c = utils.clean_column_headings(x)
     assert 'Resolved QNs' not in c.colnames
-    assert 'QNs' in c.colnames
-
-
-def test_merge(patch_post):
-    x = splatalogue.Splatalogue.query_lines(min_frequency=114 * u.GHz,
-                                            max_frequency=116 * u.GHz,
-                                            chemical_name=' CO ')
-    c = utils.merge_frequencies(x)
-    assert 'Freq' in c.colnames
-    assert np.all(c['Freq'] > 0)
+    assert 'resolved_QNs' in c.colnames
 
 
 def test_minimize(patch_post):
@@ -34,11 +25,15 @@ def test_minimize(patch_post):
     assert 'Freq' in c.colnames
     assert np.all(c['Freq'] > 0)
     assert 'Resolved QNs' not in c.colnames
-    assert 'QNs' in c.colnames
+    assert 'resolved_QNs' in c.colnames
 
 
 @pytest.mark.remote_data
 def test_minimize_issue2135():
+    """
+    This was a regression test for 2135, but is now just a basic test for the
+    new (March 2024) keywords
+    """
     rslt = splatalogue.Splatalogue.query_lines(min_frequency=100*u.GHz,
                                                max_frequency=200*u.GHz,
                                                chemical_name=' SiO ',
@@ -49,5 +44,4 @@ def test_minimize_issue2135():
 
     minimized = utils.minimize_table(rslt)
 
-    theomask = rslt['Freq-GHz(rest frame,redshifted)'].mask
-    np.testing.assert_allclose(minimized['Freq'][theomask], rslt['Meas Freq-GHz(rest frame,redshifted)'][theomask])
+    np.testing.assert_allclose(minimized['Freq'], rslt['orderedfreq'])