Authentication
Send an API key as a bearer token. The key must carry the sites.view permission; a key without it is refused with 403, not 404.
This endpoint takes no organisation id. Your key already identifies the organisation it belongs to, and the response is scoped to it.
Try it
Replace anything in angle brackets with your own values, and the key placeholder with a key from your dashboard.
curl -X GET https://api.zinndigital.com/v1/wordpress/theme-directory?q=<q> \
-H "Authorization: Bearer zdk_live_…"Signed in? The API console in your dashboard fills in your real organisation id and your own key, and runs the request against the live API so you can see the actual response. Open this endpoint in the API console
Details
Themes a customer can install, from the wordpress.org directory. **Collection-level and not under a site**, for the same reason as the plugin catalogue: choosing a theme comes before choosing where to put it. An empty or whitespace-only `q` returns an empty page rather than the directory's popularity ranking. `rating` is normalised to **0–5** (upstream reports 0–100). `author` is plain text — upstream returns it as an **object** on this API and as an HTML anchor on the plugin one, so neither shape reaches our page. `screenshot_url` and `preview_url` are normalised to `https`: upstream emits them protocol-relative (`//ts.w.org/…`), which is a working URL in a browser and a broken one everywhere else. ⚠️ `screenshot_url` and `preview_url` are **third-party URLs** a client will put in an `<img src>` and an anchor. Choosing a theme without seeing it is not a feature, so they travel; this is a considered risk, not an oversight. The engine never fetches them. Requires `sites.view`. Our egress routing for the upstream is registered as `wordpress_org` — the **same** service key as the plugin directory, because it is the same host, the same (absent) account and therefore the same throttling subject.
Parameters
| Name | Type | Required | What it is |
|---|---|---|---|
q (query) | string | Yes | What to search for. |
page (query) | integer | No | — |
per_page (query) | integer | No | — |
Response
| Name | Type | Required | What it is |
|---|---|---|---|
data | WordPressDirectoryTheme[] | Yes | — |
page | integer | Yes | — |
pages | integer | Yes | Total pages available. `0` when nothing matched. |
total | integer | Yes | Total matching themes across all pages. |
Errors this endpoint can return
401 · 403 · 429 · 503