Get the site
The key's own site: identity, serving URLs, and its custom domains with live HTTPS status.
https://webbuddy.radioworkflow.com/api/v1/sitesite:readReturns the one site the API key belongs to. There is no site id in the URL and no way to ask for a different one — the key IS the site selector, so a key leaked from one site cannot read another.
primary_url is the canonical public address: the verified primary custom domain, or null when no custom domain has been connected and verified yet. When it is null, test_url is the canonical address.
HTTPS status is only meaningful for a verified domain. An unverified domain always reports none — the certificate has not been requested yet, and this endpoint does not go looking.
Authentication
| Header | Required | Value |
|---|---|---|
| Authorization | Required | Bearer wb_live_your_key_here The site API key as a bearer token: Bearer wb_live_…. It is the only credential — there are no cookies, no session and no CSRF token in this API. |
The key must also carry the site:readscope. Scopes are ticked when a key is created on the site's API tab and cannot be added afterwards — a key without this one answers insufficient_scope to this endpoint however many times it is retried, so the fix is a new key. What each scope unlocks.
Parameters
This endpoint takes no query parameters and no request body.
Request
curl 'https://webbuddy.radioworkflow.com/api/v1/site' \ -H "Authorization: Bearer wb_live_your_key_here"
Try it
This form calls /api/v1/site from your browser, straight to the API, on this same origin. The key you paste below is put into an Authorization header on that one request — it is not sent to the documentation, not written to storage on this device, and not kept once you close the tab.
It is a real request against a real key: it counts against the same limit as any other call — 120 per minute per key — and it appears in your site's API log like anything else you send.
A live key for the site, carrying the site:read scope.
GET /api/v1/site Authorization: Bearer wb_live_your_key_here
The placeholder above is what the docs print. Your key is never shown back to you here, in the preview or in the response.
Response
application/jsonA JSON object.| Field | Type | Description |
|---|---|---|
| id | integer | The site's numeric id in the console. |
| name | string | Display name, as set in the console. |
| slug | string | URL-safe short name. Also the subdomain in test_url, so renaming it moves that URL. |
| template | string | Which product template the site runs — news, station, eventbuddy and so on. New templates are added regularly; treat this as an open set.Values come from AVAILABLE_TEMPLATES in src/lib/sites.ts (server-only, and seventeen entries and growing — deliberately not copied here). |
| status | enum | Always active over the API. A key belonging to a disabled or deleted site fails authentication outright and answers 401 unauthorized, so no other value can reach a caller. The field is published because it is part of the site resource, not because it varies.active |
| test_url | string | The always-available {slug}.… address. Derived from the slug and the template, never stored. |
| primary_url | stringor null | https:// plus the verified primary custom domain, or null when there is not one. |
| domains | object[] | Custom domains attached to the site, oldest first. Empty until one is connected. |
| domains.hostname | string | The hostname, without a scheme. |
| domains.verified | boolean | Whether DNS has been checked and the domain is serving. |
| domains.is_primary | boolean | Whether this is the canonical domain. At most one domain is primary. |
| domains.https | enum | Managed-certificate state. active is serving; provisioning is issuing; failed needs attention in the console; none means no certificate exists yet, which is always the answer for an unverified domain; unconfigured means certificate automation is off in this environment (local development).activeprovisioningfailednoneunconfiguredValues come from CertStatus in src/lib/certs.ts (server-only — restated here). |
domains is ordered by when each was added. HTTPS status is read live per verified domain, so this endpoint is a little slower for a site with several.
{
"id": 12,
"name": "Riverside Daily News",
"slug": "riverside",
"template": "news",
"status": "active",
"test_url": "https://riverside.webbuddy.radioworkflow.com",
"primary_url": "https://news.example.com",
"domains": [
{
"hostname": "news.example.com",
"verified": true,
"is_primary": true,
"https": "active"
}
]
}Every response also carries the headers listed under what every response carries.
Errors
| HTTP | code | Retry? | What to do |
|---|---|---|---|
| 401 | unauthorized | Do not | Check the header is exactly Authorization: Bearer wb_live_…. If it is, the key was probably revoked — mint a new one on the site's API tab. Do not retry: nothing about this request will succeed on a second attempt. |
| 403 | insufficient_scope | Do not | Mint a new key on the site's API tab with the required scope ticked, then revoke the old one. Do not retry: the same key answers 403 forever. The message names the scope that was missing. |
| 429 | rate_limited | Retry | Back off and retry — the window is at most 60 seconds long, so an exponential backoff starting around a second will clear it. If you hit this steadily, cache the responses you poll rather than raising your request rate. If the message mentions failed authentications, fix the key first: retrying the same bad token is what filled that bucket. |
| 500 | internal_error | Retry | Retry once after a short delay. If it persists for a given endpoint, it is a bug on our side rather than something your request can fix; report it with the endpoint and the time. |
What each code means, and the envelope they arrive in, are on the errors page.