Skip to content

Provision a customer workspace in one step

POST
/v1/admin/workspaces/provision
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.

Media typeapplication/json
object
name
required
string
<= 100 characters
slug
required

Also the subdomain. 2–63 lowercase letters, digits, hyphens; reserved names (www, api, admin, …) refused.

string
locale
string
default: en
Allowed values: en es
description
string
owner_email

Owner of a new workspace. Defaults to the first of admins; ignored when the workspace exists.

string
admins
required
Array<string>
<= 20 items
if_exists

match adopts an existing slug only when its name matches; update adopts it and renames; fail refuses.

string
default: match
Allowed values: match update fail
subdomain
boolean
branding
object
accent_color
string
/^#[0-9a-fA-F]{6}$/
hide_footer
boolean
logo
One of:
string format: uri
policy
object
allowed_domains
Array<string>
allowed_emails
Array<string>
external_sharing

The collab.external_sharing flag.

boolean
guest_comments

Guest comments on the folders this run creates.

boolean
knowledge
boolean
features

Feature-flag overrides, keys from the feature registry.

object
key
additional properties
boolean
folders
Array<string>
<= 50 items
connectors

Same body as POST /v1/workspaces/{workspaceId}/connections. An existing connector with the name is left untouched.

Array<object>
<= 20 items
object
resend_invites
boolean
templates

Template set to install. pending until the instance has templates.

string
custom_domain

Hostname to attach. pending until the instance has custom domains.

string

Existing workspace, nothing failed

Media typeapplication/json
object
ok
boolean
created
boolean
workspace
object
id
string
name
string
slug
string
locale
string
links
object
home
string
admin
string
subdomain
string | null
instance_admin
string
admins
Array<object>
object
email
string
role
string
Allowed values: owner admin member
status
string
Allowed values: invited already_invited active added failed
email_sent
boolean
invite_url

Only when the invite email did not go out.

string
error
string
steps
Array<object>
object
step

Workspace, branding, policy, folders, admins, connector:, templates, custom_domain

string
status
string
Allowed values: created updated unchanged skipped pending failed
detail
object
error
string
next_step
string
next_steps
Array<string>
duration_ms
integer
Example
{
"admins": [
{
"role": "owner",
"status": "invited"
}
],
"steps": [
{
"status": "created"
}
]
}

Workspace created, nothing failed

Media typeapplication/json
object
ok
boolean
created
boolean
workspace
object
id
string
name
string
slug
string
locale
string
links
object
home
string
admin
string
subdomain
string | null
instance_admin
string
admins
Array<object>
object
email
string
role
string
Allowed values: owner admin member
status
string
Allowed values: invited already_invited active added failed
email_sent
boolean
invite_url

Only when the invite email did not go out.

string
error
string
steps
Array<object>
object
step

Workspace, branding, policy, folders, admins, connector:, templates, custom_domain

string
status
string
Allowed values: created updated unchanged skipped pending failed
detail
object
error
string
next_step
string
next_steps
Array<string>
duration_ms
integer
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.

Media typeapplication/json
object
ok
boolean
created
boolean
workspace
object
id
string
name
string
slug
string
locale
string
links
object
home
string
admin
string
subdomain
string | null
instance_admin
string
admins
Array<object>
object
email
string
role
string
Allowed values: owner admin member
status
string
Allowed values: invited already_invited active added failed
email_sent
boolean
invite_url

Only when the invite email did not go out.

string
error
string
steps
Array<object>
object
step

Workspace, branding, policy, folders, admins, connector:, templates, custom_domain

string
status
string
Allowed values: created updated unchanged skipped pending failed
detail
object
error
string
next_step
string
next_steps
Array<string>
duration_ms
integer
Example
{
"admins": [
{
"role": "owner",
"status": "invited"
}
],
"steps": [
{
"status": "created"
}
]
}

Invalid request

Media typeapplication/json
object
success
required
boolean
error
required

Human-readable message.

string
code
required

Machine-readable error code.

string
request_id

Correlation id (also the X-Request-Id header). Quote it in support tickets.

string
reason

Finer cause under code. For UNAUTHORIZED: missing, invalid, revoked or expired.

string
hint

What to do next, in plain words.

string
suggestion
string
param

The request field at fault.

string
docs

Doc page for this error.

string
redirect_url
string
support

Present on 5xx β€” how to reach a human.

object
how
string
include
Array<string>
Example
{
"success": false,
"support": {
"how": "POST /v1/support/tickets",
"include": [
"request_id"
]
}
}

Access denied

Media typeapplication/json
object
success
required
boolean
error
required

Human-readable message.

string
code
required

Machine-readable error code.

string
request_id

Correlation id (also the X-Request-Id header). Quote it in support tickets.

string
reason

Finer cause under code. For UNAUTHORIZED: missing, invalid, revoked or expired.

string
hint

What to do next, in plain words.

string
suggestion
string
param

The request field at fault.

string
docs

Doc page for this error.

string
redirect_url
string
support

Present on 5xx β€” how to reach a human.

object
how
string
include
Array<string>
Example
{
"success": false,
"support": {
"how": "POST /v1/support/tickets",
"include": [
"request_id"
]
}
}

Slug taken or version conflict

Media typeapplication/json
object
success
required
boolean
error
required

Human-readable message.

string
code
required

Machine-readable error code.

string
request_id

Correlation id (also the X-Request-Id header). Quote it in support tickets.

string
reason

Finer cause under code. For UNAUTHORIZED: missing, invalid, revoked or expired.

string
hint

What to do next, in plain words.

string
suggestion
string
param

The request field at fault.

string
docs

Doc page for this error.

string
redirect_url
string
support

Present on 5xx β€” how to reach a human.

object
how
string
include
Array<string>
Example
{
"success": false,
"support": {
"how": "POST /v1/support/tickets",
"include": [
"request_id"
]
}
}