Organizations

Organizations are team workspaces containing projects and pages. Members can have admin or member roles.

Role Permissions
admin Full control: update settings, delete org, manage members
member View org, create projects, invite members

List Organizations

Get all organizations you're a member of.

Endpoint GET /api/orgs/
Auth Bearer token

Response (200):

[
  {
    "external_id": "org123",
    "name": "My Organization",
    "domain": "myorg.com",
    "created": "2025-01-10T08:00:00Z"
  }
]

Get Organization

Endpoint GET /api/orgs/{external_id}/
Auth Bearer token

Response (200):

{
  "external_id": "org123",
  "name": "My Organization",
  "domain": "myorg.com",
  "created": "2025-01-10T08:00:00Z"
}

Create Organization

You'll automatically be added as an admin.

Endpoint POST /api/orgs/
Auth Bearer token
Field Type Required? Description
name string Yes Organization name

Response (201):

{
  "external_id": "org789",
  "name": "My New Organization",
  "domain": null,
  "created": "2025-01-15T14:30:00Z"
}

Update Organization

Endpoint PATCH /api/orgs/{external_id}/
Auth Bearer token (admin only)
Field Type Required? Description
name string No New organization name

Response (200):

{
  "external_id": "org123",
  "name": "Updated Organization Name",
  "domain": "myorg.com",
  "created": "2025-01-10T08:00:00Z"
}

Delete Organization

Permanently deletes the organization and all its projects/pages.

Endpoint DELETE /api/orgs/{external_id}/
Auth Bearer token (admin only)

Response (204): No content.

Warning: This cannot be undone.


Members

List Members

Endpoint GET /api/orgs/{external_id}/members/
Auth Bearer token

Response (200):

[
  {
    "external_id": "user123",
    "email": "[email protected]",
    "role": "admin"
  },
  {
    "external_id": "user456",
    "email": "[email protected]",
    "role": "member"
  }
]

Add Member

Endpoint POST /api/orgs/{external_id}/members/
Auth Bearer token
Field Type Required? Description
email string Yes User's email (must have account)
role string No admin or member (default)

Response (201):

{
  "external_id": "user789",
  "email": "[email protected]",
  "role": "member"
}

Update Member Role

Endpoint PATCH /api/orgs/{external_id}/members/{user_id}/
Auth Bearer token (admin only)
Field Type Required? Description
role string Yes admin or member

Response (200):

{
  "external_id": "user456",
  "email": "[email protected]",
  "role": "admin"
}

Remove Member

Endpoint DELETE /api/orgs/{external_id}/members/{user_id}/
Auth Bearer token

Response (204): No content.

Cannot remove the only admin.


Examples

List your organizations

BASE_URL="<BASE_URL>"
TOKEN="<ACCESS_TOKEN>"

curl "$BASE_URL/api/orgs/" \
  -H "Authorization: Bearer $TOKEN"
import requests

BASE_URL = "<BASE_URL>"
TOKEN = "<ACCESS_TOKEN>"

response = requests.get(
    f"{BASE_URL}/api/orgs/",
    headers={"Authorization": f"Bearer {TOKEN}"}
)
print(response.json())
const BASE_URL = "<BASE_URL>";
const TOKEN = "<ACCESS_TOKEN>";

const response = await fetch(`${BASE_URL}/api/orgs/`, {
  headers: { Authorization: `Bearer ${TOKEN}` },
});
console.log(await response.json());
require 'net/http'
require 'json'
require 'uri'

BASE_URL = "<BASE_URL>"
TOKEN = "<ACCESS_TOKEN>"

uri = URI("#{BASE_URL}/api/orgs/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'

request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{TOKEN}"

response = http.request(request)
puts JSON.parse(response.body)
<?php
$baseUrl = "<BASE_URL>";
$token = "<ACCESS_TOKEN>";

$ch = curl_init("$baseUrl/api/orgs/");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer $token"]
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

const (
    baseURL = "<BASE_URL>"
    token   = "<ACCESS_TOKEN>"
)

func main() {
    req, _ := http.NewRequest("GET", baseURL+"/api/orgs/", nil)
    req.Header.Set("Authorization", "Bearer "+token)

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()

    var result []map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Println(result)
}

Create an organization

BASE_URL="<BASE_URL>"
TOKEN="<ACCESS_TOKEN>"

curl -X POST "$BASE_URL/api/orgs/" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "name": "My New Organization"
}
EOF
import requests

BASE_URL = "<BASE_URL>"
TOKEN = "<ACCESS_TOKEN>"

response = requests.post(
    f"{BASE_URL}/api/orgs/",
    headers={"Authorization": f"Bearer {TOKEN}"},
    json={"name": "My New Organization"}
)
print(response.json())
const BASE_URL = "<BASE_URL>";
const TOKEN = "<ACCESS_TOKEN>";

const response = await fetch(`${BASE_URL}/api/orgs/`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "My New Organization" }),
});
console.log(await response.json());
require 'net/http'
require 'json'
require 'uri'

BASE_URL = "<BASE_URL>"
TOKEN = "<ACCESS_TOKEN>"

uri = URI("#{BASE_URL}/api/orgs/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'

request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{TOKEN}"
request["Content-Type"] = "application/json"
request.body = { name: "My New Organization" }.to_json

response = http.request(request)
puts JSON.parse(response.body)
<?php
$baseUrl = "<BASE_URL>";
$token = "<ACCESS_TOKEN>";

$ch = curl_init("$baseUrl/api/orgs/");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $token",
        "Content-Type: application/json"
    ],
    CURLOPT_POSTFIELDS => json_encode(["name" => "My New Organization"])
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

const (
    baseURL = "<BASE_URL>"
    token   = "<ACCESS_TOKEN>"
)

func main() {
    body, _ := json.Marshal(map[string]string{"name": "My New Organization"})

    req, _ := http.NewRequest("POST", baseURL+"/api/orgs/", bytes.NewBuffer(body))
    req.Header.Set("Authorization", "Bearer "+token)
    req.Header.Set("Content-Type", "application/json")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Println(result)
}

Add a member

BASE_URL="<BASE_URL>"
TOKEN="<ACCESS_TOKEN>"
ORG_ID="org123"

curl -X POST "$BASE_URL/api/orgs/$ORG_ID/members/" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "email": "[email protected]",
  "role": "member"
}
EOF
import requests

BASE_URL = "<BASE_URL>"
TOKEN = "<ACCESS_TOKEN>"
ORG_ID = "org123"

response = requests.post(
    f"{BASE_URL}/api/orgs/{ORG_ID}/members/",
    headers={"Authorization": f"Bearer {TOKEN}"},
    json={"email": "[email protected]", "role": "member"}
)
print(response.json())
const BASE_URL = "<BASE_URL>";
const TOKEN = "<ACCESS_TOKEN>";
const ORG_ID = "org123";

const response = await fetch(`${BASE_URL}/api/orgs/${ORG_ID}/members/`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    email: "[email protected]",
    role: "member",
  }),
});
console.log(await response.json());
require 'net/http'
require 'json'
require 'uri'

BASE_URL = "<BASE_URL>"
TOKEN = "<ACCESS_TOKEN>"
ORG_ID = "org123"

uri = URI("#{BASE_URL}/api/orgs/#{ORG_ID}/members/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'

request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{TOKEN}"
request["Content-Type"] = "application/json"
request.body = { email: "[email protected]", role: "member" }.to_json

response = http.request(request)
puts JSON.parse(response.body)
<?php
$baseUrl = "<BASE_URL>";
$token = "<ACCESS_TOKEN>";
$orgId = "org123";

$ch = curl_init("$baseUrl/api/orgs/$orgId/members/");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $token",
        "Content-Type: application/json"
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "email" => "[email protected]",
        "role" => "member"
    ])
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

const (
    baseURL = "<BASE_URL>"
    token   = "<ACCESS_TOKEN>"
    orgID   = "org123"
)

func main() {
    body, _ := json.Marshal(map[string]string{
        "email": "[email protected]",
        "role":  "member",
    })

    req, _ := http.NewRequest("POST", baseURL+"/api/orgs/"+orgID+"/members/", bytes.NewBuffer(body))
    req.Header.Set("Authorization", "Bearer "+token)
    req.Header.Set("Content-Type", "application/json")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Println(result)
}