Autentifikacija
Pošaljite API ključ kao bearer token. Ova krajnja točka ne navodi određenu dozvolu u specifikaciji, stoga dajte svom ključu najmanje što mu je potrebno i provjerite odgovor umjesto da pretpostavljate.
Ova krajnja točka ne prihvaća ID organizacije. Vaš ključ već identificira organizaciju kojoj pripada, a odgovor je ograničen na nju.
Isprobajte
Zamijenite sve unutar šiljastih zagrada svojim vlastitim vrijednostima, a rezervirano mjesto za ključ s ključem iz vaše nadzorne ploče.
curl -X POST https://api.zinndigital.com/v1/sites/{siteId}/collaborators \
-H "Authorization: Bearer zdk_live_…" \
-H "Content-Type: application/json" \
-d '{ "email": <string>, "role": <SiteCollaboratorRole>, "reason": <string> }'Prijavljeni ste? API konzola na vašoj nadzornoj ploči automatski unosi stvarni ID vaše organizacije i vaš vlastiti ključ te šalje zahtjev prema aktivnom API-ju kako biste mogli vidjeti stvarni odgovor. Otvori ovu krajnju točku u API konzoli
Pojedinosti
Grants one person access to this one site at one role, optionally until a date, and gives them the narrow `site_collaborator` organisation membership if they have none. The narrowing is enforced by Postgres row-level security on the site table itself, not by a filter in a query, so it applies to every endpoint on this API rather than to the ones somebody remembered. ⭐ **The person need not have an account yet.** An address nobody has signed in as is invited in the same call: an ordinary organisation invitation is sent at the `site_collaborator` role, and the grant is returned with `status: pending` and a null `user_id`. The moment they accept — which proves control of that inbox through the identity provider, so no id is ever guessed — the grant activates for that person. A pending grant narrows nobody: nothing is reachable until the accept. If the address already holds a pending invitation to the *whole* organisation the call is refused with `SITE_COLLABORATOR_ALREADY_INVITED` rather than quietly downgrading that invitation to one site. **What a collaborator may then do is the per-site role, on that site only.** A request whose path names a granted site is evaluated with the role's keys (`viewer` reads; `editor` adds `hosting.deploy.manage`, `sites.cache.purge`, `hosting.performance.manage`, `sites.wp_login`, `sites.panel_access`, `sites.restart`, `hosting.php.manage`; `manager` adds `hosting.backup.manage`, `hosting.ssl.manage`, `hosting.cdn.manage`, `hosting.applications.manage`, `hosting.import.manage`). A request naming any other site answers `404`, and a request naming no site — the collection endpoints and every organisation-level surface such as members, API keys and billing — carries only `sites.view`, so it is refused with `403`. Revoking a grant takes effect on the next request, whatever token the person is holding. Every refusal carries its OWN `error.code`, because the status says what happened and only the code says what to do about it. `409` is about the world: `SITE_COLLABORATOR_ALREADY_GRANTED` (this person already has a live or pending grant here), `SITE_COLLABORATOR_ALREADY_A_MEMBER` (they are already an unrestricted member, so a grant would imply a restriction we are not applying — a lie in an access table) and `SITE_COLLABORATOR_ALREADY_INVITED` (above). `422` is about the request: `SITE_COLLABORATOR_EXPIRY_IN_THE_PAST` and `SITE_COLLABORATOR_REASON_REQUIRED`. ⛔ Key on the code, never on `error.message`. The message is a sentence written for a person and it is translated; the code is the contract.
Parametri
| Naziv | Vrsta | Obavezno | Što je to |
|---|---|---|---|
siteId (path) | Uuid | Da | Site ID (UUIDv7). |
Tijelo zahtjeva
| Naziv | Vrsta | Obavezno | Što je to |
|---|---|---|---|
email | string | Da | The person to share with. An address with no account here is invited in the same call and the grant is returned `pending` — see the endpoint description. |
role | SiteCollaboratorRole | Da | What a collaborator may do on the site they were granted. `viewer` reads it; `editor` adds the day-to-day work (deploys, cache, plugins, staging); `manager` adds the structural… |
reason | string | Da | Why they are being given this site. Required rather than optional: an optional reason is one nobody fills in, and the audit value of the record collapses to *"somebody granted s… |
expires_at | object | Ne | Optional automatic end. Null means until revoked. A time in the past is refused with `expiry_in_the_past` rather than silently creating a dead grant. |
Odgovor
| Naziv | Vrsta | Obavezno | Što je to |
|---|---|---|---|
id | string | Da | — |
site_id | string | Da | — |
user_id | object | Da | The collaborator, once known. Null while the grant is `pending` — the address has been invited and nobody has signed in as it yet. |
email | string | Da | — |
role | SiteCollaboratorRole | Da | What a collaborator may do on the site they were granted. `viewer` reads it; `editor` adds the day-to-day work (deploys, cache, plugins, staging); `manager` adds the structural… |
reason | string | Da | Why this person was given this site. Required on creation, and returned here because a year later it is the only thing that can answer *"why does this person have my site?"*. |
granted_by | string | Da | The audit ref of whoever granted it, `user:<id>`. |
created_at | string | Da | — |
expires_at | object | Da | When the grant lapses on its own, or null for *until revoked*. Evaluated at read time, so it takes effect on the clock rather than when a sweep next runs. |
active | boolean | Da | Neither revoked nor past its expiry, as of this response. |
status | string<pending, active, expired, revoked> | Da | `pending` — invited, waiting for the person to sign in as that address; `active` — in force now; `expired` — lapsed on its own end date; `revoked` — ended by the owner, the row… |
Pogreške koje ova krajnja točka može vratiti
401 · 403 · 404 · 409 · 422 · 429