Provision a customer workspace in one step
const url = 'https://shareout.site/v1/admin/workspaces/provision';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"name":"example","slug":"example","locale":"en","description":"example","owner_email":"example","admins":["hello@example.com"],"if_exists":"match","subdomain":true,"branding":{"accent_color":"example","hide_footer":true,"logo":{"url":"https://example.com"}},"policy":{"allowed_domains":["example"],"allowed_emails":["example"],"external_sharing":true,"guest_comments":true,"knowledge":true,"features":{"additionalProperty":true}},"folders":["example"],"connectors":[{}],"resend_invites":false,"templates":"example","custom_domain":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://shareout.site/v1/admin/workspaces/provision \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "name": "example", "slug": "example", "locale": "en", "description": "example", "owner_email": "example", "admins": [ "hello@example.com" ], "if_exists": "match", "subdomain": true, "branding": { "accent_color": "example", "hide_footer": true, "logo": { "url": "https://example.com" } }, "policy": { "allowed_domains": [ "example" ], "allowed_emails": [ "example" ], "external_sharing": true, "guest_comments": true, "knowledge": true, "features": { "additionalProperty": true } }, "folders": [ "example" ], "connectors": [ {} ], "resend_invites": false, "templates": "example", "custom_domain": "example" }'Instance admins only (session, or a personal so_ token β workspace Agent sot_ tokens are refused; a workspace owner/admin gets 403). Creates the workspace (or adopts the one on slug), applies branding, policy defaults and feature flags, creates starter folders, invites the admins with the normal invite email, and stores connectors through the normal encrypted connector path. Idempotent by slug: a re-run fills in what is missing and reports the rest unchanged β no second workspace, folder, membership or connector, no resent live invite, no overwritten credential. A failing step is reported in steps and the run continues (HTTP 207). Credential values are never returned or audited. Every step writes a workspace.provision.* audit row.
Authorizations
Section titled βAuthorizationsβRequest Bodyrequired
Section titled βRequest Bodyrequiredβobject
Also the subdomain. 2β63 lowercase letters, digits, hyphens; reserved names (www, api, admin, β¦) refused.
Owner of a new workspace. Defaults to the first of admins; ignored when the workspace exists.
match adopts an existing slug only when its name matches; update adopts it and renames; fail refuses.
object
The collab.external_sharing flag.
Guest comments on the folders this run creates.
Feature-flag overrides, keys from the feature registry.
object
Same body as POST /v1/workspaces/{workspaceId}/connections. An existing connector with the name is left untouched.
object
Template set to install. pending until the instance has templates.
Hostname to attach. pending until the instance has custom domains.
Responses
Section titled βResponsesβExisting workspace, nothing failed
object
object
object
object
Only when the invite email did not go out.
object
Workspace, branding, policy, folders, admins, connector:
object
Example
{ "admins": [ { "role": "owner", "status": "invited" } ], "steps": [ { "status": "created" } ]}Workspace created, nothing failed
object
object
object
object
Only when the invite email did not go out.
object
Workspace, branding, policy, folders, admins, connector:
object
Example
{ "admins": [ { "role": "owner", "status": "invited" } ], "steps": [ { "status": "created" } ]}Workspace exists; at least one step failed (see steps and next_steps). Fix and re-run.
object
object
object
object
Only when the invite email did not go out.
object
Workspace, branding, policy, folders, admins, connector:
object
Example
{ "admins": [ { "role": "owner", "status": "invited" } ], "steps": [ { "status": "created" } ]}Invalid request
object
Human-readable message.
Machine-readable error code.
Correlation id (also the X-Request-Id header). Quote it in support tickets.
Finer cause under code. For UNAUTHORIZED: missing, invalid, revoked or expired.
What to do next, in plain words.
The request field at fault.
Doc page for this error.
Present on 5xx β how to reach a human.
object
Example
{ "success": false, "support": { "how": "POST /v1/support/tickets", "include": [ "request_id" ] }}Access denied
object
Human-readable message.
Machine-readable error code.
Correlation id (also the X-Request-Id header). Quote it in support tickets.
Finer cause under code. For UNAUTHORIZED: missing, invalid, revoked or expired.
What to do next, in plain words.
The request field at fault.
Doc page for this error.
Present on 5xx β how to reach a human.
object
Example
{ "success": false, "support": { "how": "POST /v1/support/tickets", "include": [ "request_id" ] }}Slug taken or version conflict
object
Human-readable message.
Machine-readable error code.
Correlation id (also the X-Request-Id header). Quote it in support tickets.
Finer cause under code. For UNAUTHORIZED: missing, invalid, revoked or expired.
What to do next, in plain words.
The request field at fault.
Doc page for this error.
Present on 5xx β how to reach a human.
object
Example
{ "success": false, "support": { "how": "POST /v1/support/tickets", "include": [ "request_id" ] }}