/v1/article-tags is every
word they are filed under, in one call — the chips an app draws, and what
filter[tag] takes.
Pages are everything else: how it works, who we are, the terms, the contact page.
template says which layout the website draws each one with, so an app can lay out a
contact page differently from a terms page without matching on the slug.
The help centre is /v1/faq-categories and /v1/faq-articles. An answer is a
question and one body of HTML — not blocks, because it is written in a single editor
field and a one-block list is a wrapper nobody wants to unwrap. A heading with
?include=articles is the whole screen in one call, which is why the headings are not
paged.
All of them need content:read, and a guest token is enough — somebody browsing
before they sign up is exactly who these pages are for.
A filter page is a search with words around it
The field that matters issearch. It is the listing the page stands for, written in
the catalogue’s own vocabulary:
search.words goes in filter[q], search.filters are the facet filters. They are
the same names the search’s own facets come back under, so a page and a filter panel
speak one language — the search, in full →Blocks
Filter pages, articles and pages carry their content asblocks: an ordered list, each with a kind
and named fields.
body is HTML written in our editor. Everything else is plain text.
Fields that are empty are left out rather than sent as null, so check for a key
before reading it. The one exception is a links group’s name, which is null
when the links were written on the block itself rather than picked from a named list.
Why not the raw page builder
Our editor stores what it needs:content_left, list_3, image_alt. Those mean
something standing next to one of our Blade templates and nothing on their own, and an
app built on them would break the day somebody renames one. So each component is
translated into a block, and a component kind the API has not been taught about is
left out entirely — a blank space beats a half-understood guess.
In a list, blocks is null
-watchCount); articles newest first
(-publishedAt).
Autocomplete
sort is refused (400, search_only_sort) while the filter pages are searching:
suggestions are ordered by how well they match, and nothing else would be useful.
While the articles are searching a sort is not applied — they come back newest
first among what matched, whatever it says. A suggestion row is
autocompleteName — the short name an editor gave the page, falling back to name —
with watchCount beside it.
Tapping one is a catalogue search with the search it already carries. Nothing has to
be looked up in between, and there is still only one way to say “every Rolex”.
Arriving from a link
A link carries a slug, so that is what they take:tag (by the tag’s slug), type — default, video or
podcast, or several comma separated (podcast,video) — featured (true or 1 for
the ones we are featuring, false or 0 for the rest), and author (by the author’s
slug).
Who wrote it
?include=author puts the byline beside the article, as type authors: name,
function, bio, linkedin, slug, image (the square portrait) and url, their
page on the website. A byline, not an account — nothing else about the person is
served. Everything they wrote is GET /v1/articles?filter[author]={slug}.
Personal shopper
GET /v1/personal-shopper is the account page’s “Personal shopper” block: an intro
line, the shoppers (each a name and a square portrait image), and how to reach
them — whatsapp and whatsappUrl, phone and phoneUrl (tel:), email. The
website reads the same settings, so a new number or a new face reaches the app without a
release. The website’s chat button is a live-chat widget that exists only there, and no
opening hours are kept: in the app, WhatsApp is the chat.
The help centre has no search
There is nofilter[q] on /v1/faq-articles, and no website page to link an answer to:
the help centre is the app’s own screen. It is small enough to be one call —
GET /v1/faq-categories?include=articles — so search what came back, on the phone.
Ask again cheaply
Every read here carries anETag. Send it back as If-None-Match and an unchanged
page answers 304 with no body:
include or language is a different tag.
It saves the network, not the work: the answer is still built. Do not use it as a
cheap way to poll for changes on something that changes often.
What else to read
/v1/watches/{id}/related under a listing.
One language at a time
Every page exists as a row per locale.Accept-Language picks one, and a list without
it would be the same page nine times over, so there is no way to ask for all of them.
Nothing unpublished
A page still being written, or an article scheduled for next Tuesday, is not in a list and answers404 by id. There is no preview parameter: a draft reachable by id is a
draft published.