API reference

orgs

Organizations: people, teams with roles in spaces, folder rules that limit or widen who may change what (never who sees it), single sign-on through OpenID Connect for proven email domains, and an audit export.

30 endpoints · Overview

POST/v1/auth/sso/start

Start signing in through the organization that owns the address's domain (OpenID Connect)
No auth

Open url in a browser, then poll /v1/auth/sso/poll with handle. 404 when no organization signs this domain in.

Request body application/json

  • emailstringrequired
  • device_namestring
  • platformstring

Responses

Example request
curl -X POST "https://side.example.com/v1/auth/sso/start" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]"}'
Example response · 200
{
  "url": "https://hooks.example.com/side",
  "handle": "handle",
  "expires_at": "2026-11-14T09:30:00Z"
}

GET/v1/auth/sso/callback

Where the identity provider sends the browser back (an HTML page)
No auth

Responses

  • 200
    Signed in
    any
  • 400
    Unknown
    any
  • 403
    The provider refused
    any
Example request
curl "https://side.example.com/v1/auth/sso/callback"

POST/v1/auth/sso/poll

Collect the tokens once the browser came back (once)
No auth

Request body application/json

  • handlestringrequired

Responses

  • 200
    Signed in
    TokenPair
  • 202
    Still waiting for the browser
  • 410
    Expired
  • 4xx/5xx
    Error
    Error
Example request
curl -X POST "https://side.example.com/v1/auth/sso/poll" \
  -H "Content-Type: application/json" \
  -d '{"handle":"handle"}'
Example response · 200
{
  "access_token": "access_token",
  "refresh_token": "refresh_token",
  "expires_in": 1,
  "user": {
    "id": "id",
    "email": "[email protected]",
    "display_name": "display_name",
    "kind": "human"
  },
  "device_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S"
}

GET/v1/orgs

Your organizations
Bearer token

Responses

  • 200
    Organizations
    object
    › Show fields
    • itemsOrg[]required
      › 7 fields
      • idstringrequired
      • namestringrequired
      • roleOrgRolerequired
        owneradminmember
      • membersintegerrequired
      • teamsintegerrequired
      • spacesintegerrequired
      • created_atTimestamprequired
  • 4xx/5xx
    Error
    Error
Example request
curl "https://side.example.com/v1/orgs" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "items": [
    {
      "id": "id",
      "name": "A001_C003.mov",
      "role": "owner",
      "members": 1,
      "teams": 1,
      "spaces": 1,
      "created_at": "2026-11-14T09:30:00Z"
    }
  ]
}

POST/v1/orgs

Make an organization with you as its owner (people only; tokens need admin)
Bearer token

Request body application/json

  • namestringrequired

Responses

Example request
curl -X POST "https://side.example.com/v1/orgs" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"A001_C003.mov"}'
Example response · 201
{
  "id": "id",
  "name": "A001_C003.mov",
  "role": "owner",
  "members": 1,
  "teams": 1,
  "spaces": 1,
  "created_at": "2026-11-14T09:30:00Z"
}

GET/v1/orgs/{oid}

Bearer token

Parameters · path

  • oidstringrequired

Responses

Example request
curl "https://side.example.com/v1/orgs/oid" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "id": "id",
  "name": "A001_C003.mov",
  "role": "owner",
  "members": 1,
  "teams": 1,
  "spaces": 1,
  "created_at": "2026-11-14T09:30:00Z"
}

PATCH/v1/orgs/{oid}

Rename (an admin)
Bearer token

Parameters · path

  • oidstringrequired

Request body application/json

  • namestringrequired

Responses

Example request
curl -X PATCH "https://side.example.com/v1/orgs/oid" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"A001_C003.mov"}'
Example response · 200
{
  "id": "id",
  "name": "A001_C003.mov",
  "role": "owner",
  "members": 1,
  "teams": 1,
  "spaces": 1,
  "created_at": "2026-11-14T09:30:00Z"
}

GET/v1/orgs/{oid}/members

Bearer token

Parameters · path

  • oidstringrequired

Responses

  • 200
    People
    object
    › Show fields
    • itemsOrgMember[]required
      › 4 fields
      • userUserrequired
        › 4 fields
        • idstringrequired
        • emailstringrequired
          Agents have an address at agents.invalid: it finds them for invites, no mail goes there
        • display_namestringrequired
        • kindstringrequired
          humanagent
      • roleOrgRolerequired
        owneradminmember
      • teamsstring[]required
      • sinceTimestamprequired
  • 4xx/5xx
    Error
    Error
Example request
curl "https://side.example.com/v1/orgs/oid/members" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "items": [
    {
      "user": {},
      "role": "owner",
      "teams": [],
      "since": "2026-11-14T09:30:00Z"
    }
  ]
}

POST/v1/orgs/{oid}/members

Add someone by email (an admin; only an owner adds owners)
Bearer token

Parameters · path

  • oidstringrequired

Request body application/json

  • emailstringrequired
  • owneradminmember

Responses

Example request
curl -X POST "https://side.example.com/v1/orgs/oid/members" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]"}'
Example response · 201
{
  "user": {
    "id": "id",
    "email": "[email protected]",
    "display_name": "display_name",
    "kind": "human"
  },
  "role": "owner",
  "teams": [
    "team"
  ],
  "since": "2026-11-14T09:30:00Z"
}

PATCH/v1/orgs/{oid}/members/{uid}

Change a role (an admin; owners by an owner). The last owner stays.
Bearer token

Parameters · path

  • oidstringrequired
  • uidstringrequired

Request body application/json

  • roleOrgRolerequired
    owneradminmember

Responses

Example request
curl -X PATCH "https://side.example.com/v1/orgs/oid/members/usr_01JD7Q1Z3X5V7T9R1P3N5L7J9H" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role":"owner"}'

DELETE/v1/orgs/{oid}/members/{uid}

Remove someone (an admin, or themself). They leave its teams, and the spaces they were in only through them.
Bearer token

Parameters · path

  • oidstringrequired
  • uidstringrequired

Responses

Example request
curl -X DELETE "https://side.example.com/v1/orgs/oid/members/usr_01JD7Q1Z3X5V7T9R1P3N5L7J9H" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"

GET/v1/orgs/{oid}/teams

Bearer token

Parameters · path

  • oidstringrequired

Responses

  • 200
    Teams
    object
    › Show fields
    • itemsTeam[]required
      › 5 fields
      • idstringrequired
      • org_idstringrequired
      • namestringrequired
      • membersUser[]required
        › 4 fields
        • idstringrequired
        • emailstringrequired
          Agents have an address at agents.invalid: it finds them for invites, no mail goes there
        • display_namestringrequired
        • kindstringrequired
          humanagent
      • created_atTimestamprequired
  • 4xx/5xx
    Error
    Error
Example request
curl "https://side.example.com/v1/orgs/oid/teams" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "items": [
    {
      "id": "id",
      "org_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
      "name": "A001_C003.mov",
      "members": [],
      "created_at": "2026-11-14T09:30:00Z"
    }
  ]
}

POST/v1/orgs/{oid}/teams

Make a team (an admin). Names are unique in the organization, ignoring case.
Bearer token

Parameters · path

  • oidstringrequired

Request body application/json

  • namestringrequired

Responses

Example request
curl -X POST "https://side.example.com/v1/orgs/oid/teams" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"A001_C003.mov"}'
Example response · 201
{
  "id": "id",
  "org_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
  "name": "A001_C003.mov",
  "members": [
    {}
  ],
  "created_at": "2026-11-14T09:30:00Z"
}

PATCH/v1/orgs/{oid}/teams/{tid}

Bearer token

Parameters · path

  • oidstringrequired
  • tidstringrequired

Request body application/json

  • namestringrequired

Responses

Example request
curl -X PATCH "https://side.example.com/v1/orgs/oid/teams/tid" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"A001_C003.mov"}'
Example response · 200
{
  "id": "id",
  "org_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
  "name": "A001_C003.mov",
  "members": [
    {}
  ],
  "created_at": "2026-11-14T09:30:00Z"
}

DELETE/v1/orgs/{oid}/teams/{tid}

Delete a team (an admin); its roles in spaces and folder grants go with it
Bearer token

Parameters · path

  • oidstringrequired
  • tidstringrequired

Responses

Example request
curl -X DELETE "https://side.example.com/v1/orgs/oid/teams/tid" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"

POST/v1/orgs/{oid}/teams/{tid}/members

Add someone to a team (an admin); they join the organization as a member if needed
Bearer token

Parameters · path

  • oidstringrequired
  • tidstringrequired

Request body application/json

  • emailstringrequired

Responses

Example request
curl -X POST "https://side.example.com/v1/orgs/oid/teams/tid/members" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]"}'
Example response · 201
{
  "id": "id",
  "email": "[email protected]",
  "display_name": "display_name",
  "kind": "human"
}

DELETE/v1/orgs/{oid}/teams/{tid}/members/{uid}

Bearer token

Parameters · path

  • oidstringrequired
  • tidstringrequired
  • uidstringrequired

Responses

Example request
curl -X DELETE "https://side.example.com/v1/orgs/oid/teams/tid/members/usr_01JD7Q1Z3X5V7T9R1P3N5L7J9H" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"

GET/v1/orgs/{oid}/spaces

The organization's spaces (admins see all, members the ones they are in)
Bearer token

Parameters · path

  • oidstringrequired

Responses

  • 200
    Spaces
    object
    › Show fields
    • itemsOrgSpace[]required
      › 4 fields
      • idstringrequired
      • namestringrequired
      • owner_idstringrequired
      • teamsMemberTeam[]required
        › 3 fields
        • idstringrequired
        • namestringrequired
        • roleRolerequired
          viewercommentereditormanager
  • 4xx/5xx
    Error
    Error
Example request
curl "https://side.example.com/v1/orgs/oid/spaces" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "items": [
    {
      "id": "id",
      "name": "A001_C003.mov",
      "owner_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
      "teams": []
    }
  ]
}

GET/v1/orgs/{oid}/sso

Single sign-on settings (an admin). A 404 still names the redirect URI and the DNS proof.
Bearer token

Parameters · path

  • oidstringrequired

Responses

Example request
curl "https://side.example.com/v1/orgs/oid/sso" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "issuer": "issuer",
  "client_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
  "client_secret": "client_secret",
  "domains": [
    "domain"
  ],
  "required": false,
  "redirect_uri": "redirect_uri",
  "domain_proof": "domain_proof",
  "updated_at": "2026-11-14T09:30:00Z"
}

PUT/v1/orgs/{oid}/sso

Connect an OpenID Connect provider for email domains (an owner)
Bearer token

The issuer must answer OpenID discovery over https. Each new domain must carry the DNS TXT record _sidespace. = domain_proof (422 domain_unproven otherwise), unless the server trusts it. With required, email codes stop working for those domains (403 sso_required). client_secret may be left out to keep the stored one.

Parameters · path

  • oidstringrequired

Request bodySSOConfig application/json

  • issuerstringrequired
  • client_idstringrequired
  • client_secretstring
  • domainsstring[]required
  • requiredboolean
    Email codes stop working for these domains
  • redirect_uristring
    Register it with the provider
  • domain_proofstring
    Value of the DNS TXT record _sidespace.
  • updated_atTimestamp

Responses

Example request
curl -X PUT "https://side.example.com/v1/orgs/oid/sso" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"issuer":"issuer","client_id":"nod_01JD7Q3A5C7E9G1J3K5M7P9R2S","domains":["domain"]}'
Example response · 200
{
  "issuer": "issuer",
  "client_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
  "client_secret": "client_secret",
  "domains": [
    "domain"
  ],
  "required": false,
  "redirect_uri": "redirect_uri",
  "domain_proof": "domain_proof",
  "updated_at": "2026-11-14T09:30:00Z"
}

DELETE/v1/orgs/{oid}/sso

Turn single sign-on off (an owner); email codes work again
Bearer token

Parameters · path

  • oidstringrequired

Responses

Example request
curl -X DELETE "https://side.example.com/v1/orgs/oid/sso" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"

GET/v1/orgs/{oid}/audit

Audit export (an admin; tokens need admin), oldest first, at most 200 000 records
Bearer token

Parameters · path

  • oidstringrequired

Parameters · query

  • sincestring
    RFC 3339 or YYYY-MM-DD; default 30 days before until
  • untilstring
    Default now
  • formatstring
    jsonlcsv
    default "jsonl"

Responses

  • 200
    One AuditRecord per line (jsonl), or CSV with a header row
    AuditRecord
  • 4xx/5xx
    Error
    Error
Example request
curl "https://side.example.com/v1/orgs/oid/audit" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"

PUT/v1/spaces/{sid}/org

Put the space in an organization, or take it out with an empty org_id (a space manager who is an admin there)
Bearer token

Taking it out drops its teams' roles.

Parameters · path

  • sidstringrequired
    ^spc_[0-9A-HJKMNP-TV-Z]{26}$

Request body application/json

  • org_idstringrequired

Responses

Example request
curl -X PUT "https://side.example.com/v1/spaces/spc_01JD7Q2M8X4V6N0R3T5W9Y1B2C/org" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"org_id":"nod_01JD7Q3A5C7E9G1J3K5M7P9R2S"}'
Example response · 200
{
  "id": "id",
  "name": "A001_C003.mov",
  "role": "viewer",
  "owner_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
  "root_node_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
  "journal_seq": 1,
  "created_at": "2026-11-14T09:30:00Z",
  "storage_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
  "fork": {
    "from_space_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
    "path": "Ep01/Shots/A001_C003.mov",
    "at_seq": 1
  },
  "org_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S"
}

GET/v1/spaces/{sid}/teams

Teams with a role in the space
Bearer token

Parameters · path

  • sidstringrequired
    ^spc_[0-9A-HJKMNP-TV-Z]{26}$

Responses

  • 200
    Teams
    object
    › Show fields
    • itemsMemberTeam[]required
      › 3 fields
      • idstringrequired
      • namestringrequired
      • roleRolerequired
        viewercommentereditormanager
  • 4xx/5xx
    Error
    Error
Example request
curl "https://side.example.com/v1/spaces/spc_01JD7Q2M8X4V6N0R3T5W9Y1B2C/teams" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "items": [
    {
      "id": "id",
      "name": "A001_C003.mov",
      "role": "viewer"
    }
  ]
}

PUT/v1/spaces/{sid}/teams/{tid}

Give a team of the space's organization a role (a manager); tokens need members:manage
Bearer token

Parameters · path

  • sidstringrequired
    ^spc_[0-9A-HJKMNP-TV-Z]{26}$
  • tidstringrequired

Request body application/json

  • roleRolerequired
    viewercommentereditormanager

Responses

Example request
curl -X PUT "https://side.example.com/v1/spaces/spc_01JD7Q2M8X4V6N0R3T5W9Y1B2C/teams/tid" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role":"viewer"}'
Example response · 200
{
  "id": "id",
  "name": "A001_C003.mov",
  "role": "viewer"
}

DELETE/v1/spaces/{sid}/teams/{tid}

Bearer token

Parameters · path

  • sidstringrequired
    ^spc_[0-9A-HJKMNP-TV-Z]{26}$
  • tidstringrequired

Responses

Example request
curl -X DELETE "https://side.example.com/v1/spaces/spc_01JD7Q2M8X4V6N0R3T5W9Y1B2C/teams/tid" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"

GET/v1/spaces/{sid}/folder-access

Folders with access rules
Bearer token

Parameters · path

  • sidstringrequired
    ^spc_[0-9A-HJKMNP-TV-Z]{26}$

Responses

  • 200
    Folders
    object
    › Show fields
    • itemsFolderAccess[]required
      › 6 fields
      • node_idstringrequired
      • pathstringrequired
      • default_roleRole | anyrequired
        The most anyone not granted may do inside; null keeps their space role
      • grantsFolderGrant[]required
        › 4 fields
        • kindstringrequired
          userteam
        • idstring
        • roleRolerequired
          viewercommentereditormanager
        • namestring
          An email or team name; on a request a user may be named by email instead of id
      • updated_bystring
      • updated_atTimestamp
  • 4xx/5xx
    Error
    Error
Example request
curl "https://side.example.com/v1/spaces/spc_01JD7Q2M8X4V6N0R3T5W9Y1B2C/folder-access" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "items": [
    {
      "node_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
      "path": "Ep01/Shots/A001_C003.mov",
      "default_role": "viewer",
      "grants": [],
      "updated_by": "updated_by",
      "updated_at": "2026-11-14T09:30:00Z"
    }
  ]
}

GET/v1/spaces/{sid}/nodes/{nid}/access

Your role at a file or folder, and the folder whose rules decide it
Bearer token

Parameters · path

  • sidstringrequired
    ^spc_[0-9A-HJKMNP-TV-Z]{26}$
  • nidstringrequired

Responses

Example request
curl "https://side.example.com/v1/spaces/spc_01JD7Q2M8X4V6N0R3T5W9Y1B2C/nodes/nod_01JD7Q3A5C7E9G1J3K5M7P9R2S/access" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"
Example response · 200
{
  "role": "viewer",
  "space_role": "viewer",
  "governed_by": {
    "node_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
    "path": "Ep01/Shots/A001_C003.mov",
    "default_role": "viewer",
    "grants": [],
    "updated_by": "updated_by",
    "updated_at": "2026-11-14T09:30:00Z"
  }
}

PUT/v1/spaces/{sid}/nodes/{nid}/access

Set a folder's rules (a manager; tokens need members:manage). Replaces them.
Bearer token

The nearest folder with rules decides for everything under it. A grant may exceed the person's space role; default_role caps everyone else. Managers are never limited. Rules decide what may be changed, not what is seen.

Parameters · path

  • sidstringrequired
    ^spc_[0-9A-HJKMNP-TV-Z]{26}$
  • nidstringrequired

Request bodySetFolderAccessRequest application/json

  • default_roleRole | any
  • grantsFolderGrant[]required
    › 4 fields
    • kindstringrequired
      userteam
    • idstring
    • roleRolerequired
      viewercommentereditormanager
    • namestring
      An email or team name; on a request a user may be named by email instead of id

Responses

Example request
curl -X PUT "https://side.example.com/v1/spaces/spc_01JD7Q2M8X4V6N0R3T5W9Y1B2C/nodes/nod_01JD7Q3A5C7E9G1J3K5M7P9R2S/access" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"grants":[{}]}'
Example response · 200
{
  "node_id": "nod_01JD7Q3A5C7E9G1J3K5M7P9R2S",
  "path": "Ep01/Shots/A001_C003.mov",
  "default_role": "viewer",
  "grants": [
    {}
  ],
  "updated_by": "updated_by",
  "updated_at": "2026-11-14T09:30:00Z"
}

DELETE/v1/spaces/{sid}/nodes/{nid}/access

Remove a folder's rules (a manager)
Bearer token

Parameters · path

  • sidstringrequired
    ^spc_[0-9A-HJKMNP-TV-Z]{26}$
  • nidstringrequired

Responses

Example request
curl -X DELETE "https://side.example.com/v1/spaces/spc_01JD7Q2M8X4V6N0R3T5W9Y1B2C/nodes/nod_01JD7Q3A5C7E9G1J3K5M7P9R2S/access" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN"