DEV Community

OnePassApps
OnePassApps

Posted on

The Catalogue Route on Our API Host: 43 Records, 22 Enabled, One Renamed Slug

The Catalogue Route on Our API Host: 43 Records, 22 Enabled, One Renamed Slug

I work on OnePassApps, so this is our own product, and every number below was measured on it today with plain HTTPS from a signed-out session: no API key, no cookie, no browser, no session, no writes.

The route

GET https://api.onepassapps.com/api/products answers 200 with application/json, 15,650 bytes, and Cache-Control: private, no-store, max-age=0. The envelope is the one our other API routes use - {"ok":true,"data":[...],"meta":{"requestId":"req_..."}} - and data is a list of 43 records. Every one of the 43 carries the same eleven fields: slug, name, status, category, availability, appEnabled, appDisabled, appDisabledNote, launchSurface, launchBlocked, launchNote.

Counted across the 43 records:

Field Values
status 38 prototype-ready, 5 spec-needed
availability 22 enabled, 21 disabled
appEnabled / appDisabled 22 true / false, 21 false / true
launchSurface 2 launch, 41 blocked
launchBlocked 2 false, 41 true

Every one of the 22 enabled entries is prototype-ready, and every enabled entry carries an empty appDisabledNote.

Two routes, the same 43 names, two different verdicts

On 4 November I published the feature-flag route: /api/config/feature-flags carries 46 values, 43 of them product.<slug>.enabled switches, and every one of the 43 read true. That post said plainly that nothing it had read established which of the 43 a visitor could reach, because it could only compare flag names against the home page and the guides.

This route answers a different question. It lists the same 43 names one by one, each with its display name, its category and its own state:

  • the 43 flag names and the 43 catalogue slugs are the same set, exactly, with no name on either side that the other lacks
  • all 43 flags read true
  • the catalogue marks 21 of those same 43 as appEnabled: false and availability: "disabled"

So the two routes on the same host, served by the same release, disagree about 21 of the same names: the flag says the product is on, the catalogue says the app is disabled. I am not going to guess why, and I am not going to call either one wrong. What is measurable is that the two readings exist, that they cover the same 43 names, and that they differ on 21 of them.

The 22 enabled entries are the apps the site actually serves

Our public sitemap lists 22 /apps/ routes. The catalogue's 22 enabled slugs and those 22 route slugs are the same set apart from one rename: 21 slugs are shared, the only site slug with no catalogue match is newsflow, and the only catalogue slug with no site match is signaldesk. They are the same product - /apps/newsflow answers 200 and its title is "NewsFlow — Trusted-source briefs and audio — OnePassApps", and the catalogue's signaldesk entry is named "NewsFlow". So that one app is newsflow in its URL and signaldesk in the API, in the flags, and in the runtime route.

The other 21 match one to one, and the catalogue names are the leading phrase of each page's own title: PDF Organiser, CV Builder, Email Signature Builder, Chart Maker, Subtitle Workbench, Browser Teleprompter, Screen & Cinema Planner, Label & Card Maker, Social Preview Designer, Citation Formatter, Calendar Maker, Password Generator, Word Counter, Focus Timer, QR Code Maker, Ambient Noise Mixer, Time Zone Planner, Invoice Maker, Signature Maker, Screen Recorder, MovieMatcherAI.

That is the part the 4 November post could not reach from the flags alone: 21 of the 22 catalogue slugs match a public URL segment exactly.

Launch scope

launchSurface reads launch for exactly two records, signaldesk and movie-tracker, and blocked for the other 41. The note on those two says the product "is included in the configured production launch scope". The other 20 enabled entries carry the opposite sentence - the product "is blocked until it is added to the configured production launch scope" - while their public pages answer 200 and carry their own titles.

The runtime route agrees with the catalogue about which two those are. /api/runtime has its own products object, and its two keys are exactly signaldesk and movie-tracker, each with mode inherit and an empty message.

One shape difference worth knowing about: the catalogue returns launchSurface as the string launch or blocked, with the sentence in a separate launchNote field. The app's own bundle reads launchSurface as an object with blocked, note and label fields. The catalogue's records are not shaped like the payload that code is written against.

Whether an app is live and whether it is in launch scope are two different switches in this data, and the public site follows the first one.

Nothing in our own published files points at this route

  • llms.txt has no line mentioning "api" at all.
  • The home page HTML mentions neither api.onepassapps.com nor /api/products.
  • The app bundle carries our API origin and the string signaldesk, but no reference to /api/products.
  • The API host's own robots.txt is 1,248 bytes of content-signal commentary with zero directive lines, and it does not mention products.

How much of the API host is there

I probed 74 hand-picked paths on the API host, signed out, one GET each: 7 answer 200 (/api, /api/, /api/health, /api/runtime, /api/plans, /api/products, /robots.txt), 1 answers 401 (/api/account: "Sign in before using this endpoint."), 1 answers 400 (/api/analytics: "A valid analytics session is required."), and 65 answer 404. All 65 of those 404s are the same 124-byte envelope - {"ok":false,"error":{"code":"NOT_FOUND","message":"That route does not exist."},...} - and the only field that differs between them is the request id. On /api/runtime, OPTIONS answers 204 with no Allow header, POST answers that same 404 envelope rather than a 405, and HEAD answers 200 with an empty body.

Two reads of the catalogue returned identical records. Adding four tracking parameters to the URL changed nothing but the request id - 15,650 bytes either way, the record list identical - which is why the tracked link below returns the same catalogue as the plain one.

What I did not do

No key, no sign-in, no write, and no flag flipped. I did not read the 21 disabled entries' names into this post: they are not public products yet, so the counts are here and the names stay off the page. I probed the 74 paths I chose by hand, so other routes may exist that I did not guess. The launch scope and the flag set are our own configuration and only the owner can change them - this post reports what two of our routes say, it does not ask for anything.

If you want to read the catalogue yourself, it is at https://api.onepassapps.com/api/products?utm_source=devto&utm_medium=post&utm_campaign=api-products-catalogue&utm_content=api-products-link, and the apps it lists are at https://app.onepassapps.com?utm_source=devto&utm_medium=post&utm_campaign=api-products-catalogue&utm_content=home-link. The feature-flag route I published on 4 November is here.

I work on OnePassApps, the team behind app.onepassapps.com.

Top comments (0)