public
GET /v1/plugins/{slug}/download
The installable plugin zip.
Authentication
This endpoint takes no API key. Anything else it needs, such as a signed request, is described above.
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/plugins/{slug}/download \
-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
The archive itself, over TLS on our own hostname, with its SHA-256 in X-Zinn-Package-SHA256 so a download is checkable without a second request. ⛔ The bytes are served rather than redirected, and that is a constraint the CLIENT imposes: the self-hosted updater shipped inside these plugins accepts a package only on our own host, so a redirect to a release asset or an object store is refused on every site. An app-only plugin is invisible here to an anonymous caller. A site we host reaches it with the package ticket (site, exp, sig) that POST /v1/wp/plugin-update/{siteId} puts in the package URL it returns — WordPress fetches that URL with no headers, so the proof has to travel in the query string. The ticket is bound to one plugin at one version and expires; an invalid one is the same 404 as an unknown plugin. A plugin held for launch (launch_pending in wp/plugins.json, e.g. Zinn® SEO until release R1) is a 404 to every caller, signed in or not, and is absent from listPlugins and getPlugin; only a hosted site's package ticket opens it, so a site already running it keeps its updates. version downloads one of the older releases listPluginVersions offers, under the same entitlement as the current one. A version that exists but is not offered — a superseded patch, a line older than the two previous majors, or a newer release that has not been made current — is a 404, exactly like a version that never existed. Every credential stays bound to the version it names: a ticket for 1.2.3 does not open 1.1.2.
Parameters
| Name | Type | Required | What it is |
|---|---|---|---|
slug (path) | string | Yes | The plugin's directory name and text domain, e.g. zinn-cache. |
version (query) | string | No | One of the versions listPluginVersions lists for this plugin. Omit for the current release. |
site (query) | string | No | The site id a package ticket was minted for. Ignored for public plugins. |
exp (query) | integer | No | Unix time the package ticket stops being accepted. |
sig (query) | string | No | Hex HMAC-SHA256 over slug:version:exp with the site's own secret. |
Errors this endpoint can return
404 · 429